Commit a2e1da6e authored by Sergey Lyubka's avatar Sergey Lyubka

Add overflow checks

parent bef3f85b
...@@ -347,6 +347,11 @@ size_t iobuf_append(struct iobuf *io, const void *buf, size_t len) { ...@@ -347,6 +347,11 @@ size_t iobuf_append(struct iobuf *io, const void *buf, size_t len) {
assert(io != NULL); assert(io != NULL);
assert(io->len <= io->size); assert(io->len <= io->size);
/* check overflow */
if (len > ~(size_t)0 - (size_t)(io->buf + io->len)) {
return 0;
}
if (len <= 0) { if (len <= 0) {
} else if (io->len + len <= io->size) { } else if (io->len + len <= io->size) {
memcpy(io->buf + io->len, buf, len); memcpy(io->buf + io->len, buf, len);
...@@ -2893,7 +2898,7 @@ static void send_websocket_handshake(struct mg_connection *conn, ...@@ -2893,7 +2898,7 @@ static void send_websocket_handshake(struct mg_connection *conn,
static int deliver_websocket_frame(struct connection *conn) { static int deliver_websocket_frame(struct connection *conn) {
// Having buf unsigned char * is important, as it is used below in arithmetic // Having buf unsigned char * is important, as it is used below in arithmetic
unsigned char *buf = (unsigned char *) conn->ns_conn->recv_iobuf.buf; unsigned char *buf = (unsigned char *) conn->ns_conn->recv_iobuf.buf;
int i, len, buf_len = conn->ns_conn->recv_iobuf.len, frame_len = 0, size_t i, len, buf_len = conn->ns_conn->recv_iobuf.len, frame_len = 0,
mask_len = 0, header_len = 0, data_len = 0, buffered = 0; mask_len = 0, header_len = 0, data_len = 0, buffered = 0;
if (buf_len >= 2) { if (buf_len >= 2) {
...@@ -2904,10 +2909,10 @@ static int deliver_websocket_frame(struct connection *conn) { ...@@ -2904,10 +2909,10 @@ static int deliver_websocket_frame(struct connection *conn) {
header_len = 2 + mask_len; header_len = 2 + mask_len;
} else if (len == 126 && buf_len >= 4 + mask_len) { } else if (len == 126 && buf_len >= 4 + mask_len) {
header_len = 4 + mask_len; header_len = 4 + mask_len;
data_len = ((((int) buf[2]) << 8) + buf[3]); data_len = ((((size_t) buf[2]) << 8) + buf[3]);
} else if (buf_len >= 10 + mask_len) { } else if (buf_len >= 10 + mask_len) {
header_len = 10 + mask_len; header_len = 10 + mask_len;
data_len = (int) (((uint64_t) htonl(* (uint32_t *) &buf[2])) << 32) + data_len = (size_t) (((uint64_t) htonl(* (uint32_t *) &buf[2])) << 32) +
htonl(* (uint32_t *) &buf[6]); htonl(* (uint32_t *) &buf[6]);
} }
} }
...@@ -2942,6 +2947,11 @@ size_t mg_websocket_write(struct mg_connection *conn, int opcode, ...@@ -2942,6 +2947,11 @@ size_t mg_websocket_write(struct mg_connection *conn, int opcode,
unsigned char mem[4192], *copy = mem; unsigned char mem[4192], *copy = mem;
size_t copy_len = 0; size_t copy_len = 0;
/* Check overflow */
if (data_len > ~(size_t)0 - (size_t)10) {
return 0;
}
if (data_len + 10 > sizeof(mem) && if (data_len + 10 > sizeof(mem) &&
(copy = (unsigned char *) NS_MALLOC(data_len + 10)) == NULL) { (copy = (unsigned char *) NS_MALLOC(data_len + 10)) == NULL) {
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment