Fix for double free if incorrect password is passed

This commit is contained in:
Mark Riddoch
2014-09-24 11:13:33 +01:00
parent a82ea9def3
commit f3429dac1b
2 changed files with 19 additions and 12 deletions

View File

@ -30,11 +30,13 @@
* @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 {
SPINLOCK lock; /**< Protocol structure lock */
int state; /**< The connection state */ int state; /**< The connection state */
char *username; /**< The login name of the user */ char *username; /**< The login name of the user */
} MAXSCALED; } MAXSCALED;

View File

@ -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));
maxscaled_pr->username = NULL;
client_dcb->protocol = (void *)maxscaled_pr;
if (maxscaled_pr == NULL)
{ {
client_dcb->protocol = 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;
} }