Fix for double free if incorrect password is passed
This commit is contained in:
@ -30,13 +30,15 @@
|
|||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#include <dcb.h>
|
#include <dcb.h>
|
||||||
|
#include <spinlock.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The telnetd specific protocol structure to put in the DCB.
|
* The telnetd specific protocol structure to put in the DCB.
|
||||||
*/
|
*/
|
||||||
typedef struct maxscaled {
|
typedef struct maxscaled {
|
||||||
int state; /**< The connection state */
|
SPINLOCK lock; /**< Protocol structure lock */
|
||||||
char *username; /**< The login name of the user */
|
int state; /**< The connection state */
|
||||||
|
char *username; /**< The login name of the user */
|
||||||
} MAXSCALED;
|
} MAXSCALED;
|
||||||
|
|
||||||
#define MAXSCALED_STATE_LOGIN 1 /**< Issued login prompt */
|
#define MAXSCALED_STATE_LOGIN 1 /**< Issued login prompt */
|
||||||
|
|||||||
@ -166,7 +166,6 @@ char *password;
|
|||||||
{
|
{
|
||||||
dcb_printf(dcb, "FAILED");
|
dcb_printf(dcb, "FAILED");
|
||||||
maxscaled->state = MAXSCALED_STATE_LOGIN;
|
maxscaled->state = MAXSCALED_STATE_LOGIN;
|
||||||
free(maxscaled->username);
|
|
||||||
}
|
}
|
||||||
gwbuf_consume(head, GWBUF_LENGTH(head));
|
gwbuf_consume(head, GWBUF_LENGTH(head));
|
||||||
free(password);
|
free(password);
|
||||||
@ -276,17 +275,18 @@ int n_connect = 0;
|
|||||||
client_dcb->fd = so;
|
client_dcb->fd = so;
|
||||||
client_dcb->remote = strdup(inet_ntoa(addr.sin_addr));
|
client_dcb->remote = strdup(inet_ntoa(addr.sin_addr));
|
||||||
memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL));
|
memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL));
|
||||||
client_dcb->session =
|
if ((maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED))) == NULL)
|
||||||
session_alloc(dcb->session->service, client_dcb);
|
{
|
||||||
maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED));
|
client_dcb->protocol = NULL;
|
||||||
maxscaled_pr->username = NULL;
|
|
||||||
client_dcb->protocol = (void *)maxscaled_pr;
|
|
||||||
|
|
||||||
if (maxscaled_pr == NULL)
|
|
||||||
{
|
|
||||||
dcb_add_to_zombieslist(client_dcb);
|
dcb_add_to_zombieslist(client_dcb);
|
||||||
return n_connect;
|
return n_connect;
|
||||||
}
|
}
|
||||||
|
maxscaled_pr->username = NULL;
|
||||||
|
spinlock_init(&maxscaled_pr->lock);
|
||||||
|
client_dcb->protocol = (void *)maxscaled_pr;
|
||||||
|
|
||||||
|
client_dcb->session =
|
||||||
|
session_alloc(dcb->session->service, client_dcb);
|
||||||
|
|
||||||
if (poll_add_dcb(client_dcb) == -1)
|
if (poll_add_dcb(client_dcb) == -1)
|
||||||
{
|
{
|
||||||
@ -313,11 +313,16 @@ maxscaled_close(DCB *dcb)
|
|||||||
{
|
{
|
||||||
MAXSCALED *maxscaled = dcb->protocol;
|
MAXSCALED *maxscaled = dcb->protocol;
|
||||||
|
|
||||||
if (maxscaled && maxscaled->username)
|
if (!maxscaled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
spinlock_acquire(&maxscaled->lock);
|
||||||
|
if (maxscaled->username)
|
||||||
{
|
{
|
||||||
free(maxscaled->username);
|
free(maxscaled->username);
|
||||||
maxscaled->username = NULL;
|
maxscaled->username = NULL;
|
||||||
}
|
}
|
||||||
|
spinlock_release(&maxscaled->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user