Fixed nasty crash if a user sends a very large command to the hub.
Will overwrite heap memory. Thanks to Toast who found this bug. Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
This commit is contained in:
parent
abedec692a
commit
1a1b5bdb38
@ -25,10 +25,9 @@ void net_on_read(int fd, short ev, void *arg)
|
|||||||
static char buf[MAX_RECV_BUF];
|
static char buf[MAX_RECV_BUF];
|
||||||
struct user* user = (struct user*) arg;
|
struct user* user = (struct user*) arg;
|
||||||
char* pos;
|
char* pos;
|
||||||
char* start;
|
size_t offset;
|
||||||
ssize_t offset;
|
size_t buflen;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
ssize_t buflen;
|
|
||||||
int more = 1;
|
int more = 1;
|
||||||
int flag_close = 0;
|
int flag_close = 0;
|
||||||
|
|
||||||
@ -55,10 +54,6 @@ void net_on_read(int fd, short ev, void *arg)
|
|||||||
memcpy(buf, user->recv_buf, user->recv_buf_offset);
|
memcpy(buf, user->recv_buf, user->recv_buf_offset);
|
||||||
offset = user->recv_buf_offset;
|
offset = user->recv_buf_offset;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = net_recv(fd, &buf[offset], MAX_RECV_BUF - offset, 0);
|
size = net_recv(fd, &buf[offset], MAX_RECV_BUF - offset, 0);
|
||||||
if (size == -1)
|
if (size == -1)
|
||||||
@ -75,40 +70,63 @@ void net_on_read(int fd, short ev, void *arg)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
buflen = offset + size;
|
buflen = offset + size;
|
||||||
start = buf;
|
ssize_t handled = 0;
|
||||||
while ((pos = strchr(start, '\n')))
|
|
||||||
|
while ((pos = memchr(&buf[handled], '\n', (buflen - handled))))
|
||||||
{
|
{
|
||||||
pos[0] = '\0';
|
pos[0] = '\0';
|
||||||
if (*start && strlen(start) < user->hub->config->max_recv_buffer)
|
size_t msglen = &pos[0] - &buf[handled];
|
||||||
{
|
|
||||||
if (hub_handle_message(user, start, &pos[0]-&start[0]) == -1)
|
|
||||||
{
|
|
||||||
flag_close = quit_protocol_error;
|
|
||||||
more = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
start = &pos[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!more) break;
|
if (user_flag_get(user, flag_maxbuf))
|
||||||
|
|
||||||
if (&buf[offset + size] > &start[0])
|
|
||||||
{
|
|
||||||
if (!user->recv_buf)
|
|
||||||
{
|
{
|
||||||
user->recv_buf = hub_malloc(user->hub->config->max_recv_buffer);
|
user_flag_unset(user, flag_maxbuf);
|
||||||
}
|
|
||||||
|
|
||||||
if (!user->recv_buf)
|
|
||||||
{
|
|
||||||
flag_close = quit_memory_error;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(user->recv_buf, start, &buf[offset + size] - &start[0]);
|
if (msglen < user->hub->config->max_recv_buffer)
|
||||||
user->recv_buf_offset = &buf[offset + size] - &start[0];
|
{
|
||||||
|
if (hub_handle_message(user, &buf[handled], msglen) == -1)
|
||||||
|
{
|
||||||
|
flag_close = quit_protocol_error;
|
||||||
|
more = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handled += msglen;
|
||||||
|
handled++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled == 0 && user_flag_get(user, flag_maxbuf))
|
||||||
|
handled = buflen;
|
||||||
|
|
||||||
|
if (!more)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (handled < buflen)
|
||||||
|
{
|
||||||
|
if ((buflen - handled) > user->hub->config->max_recv_buffer)
|
||||||
|
{
|
||||||
|
user_flag_set(user, flag_maxbuf);
|
||||||
|
hub_free(user->recv_buf);
|
||||||
|
user->recv_buf = 0;
|
||||||
|
user->recv_buf_offset = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!user->recv_buf)
|
||||||
|
user->recv_buf = hub_malloc(user->hub->config->max_recv_buffer);
|
||||||
|
|
||||||
|
if (user->recv_buf)
|
||||||
|
{
|
||||||
|
memcpy(user->recv_buf, &buf[handled], buflen - handled);
|
||||||
|
user->recv_buf_offset = buflen - handled;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flag_close = quit_memory_error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
11
src/user.h
11
src/user.h
@ -47,11 +47,12 @@ enum user_flags
|
|||||||
feature_ping = 0x00000080, /** PING: Hub pinger information extension */
|
feature_ping = 0x00000080, /** PING: Hub pinger information extension */
|
||||||
feature_link = 0x00000100, /** LINK: Hub link (not supported) */
|
feature_link = 0x00000100, /** LINK: Hub link (not supported) */
|
||||||
flag_ignore = 0x01000000, /** Ignore further reads */
|
flag_ignore = 0x01000000, /** Ignore further reads */
|
||||||
flag_choke = 0x02000000, /** Choked: Cannot send, waiting for write event */
|
flag_maxbuf = 0x02000000, /** Hit max buf read, ignore msg */
|
||||||
flag_want_read = 0x04000000, /** Need to read (SSL) */
|
flag_choke = 0x04000000, /** Choked: Cannot send, waiting for write event */
|
||||||
flag_want_write = 0x08000000, /** Need to write (SSL) */
|
flag_want_read = 0x08000000, /** Need to read (SSL) */
|
||||||
flag_user_list = 0x10000000, /** Send queue bypass (when receiving the send queue) */
|
flag_want_write = 0x10000000, /** Need to write (SSL) */
|
||||||
flag_nat = 0x20000000, /** nat override enabled */
|
flag_user_list = 0x20000000, /** Send queue bypass (when receiving the send queue) */
|
||||||
|
flag_nat = 0x40000000, /** nat override enabled */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user