diff --git a/mongoose.c b/mongoose.c index d733d41a..27b136c0 100644 --- a/mongoose.c +++ b/mongoose.c @@ -347,6 +347,11 @@ size_t iobuf_append(struct iobuf *io, const void *buf, size_t len) { assert(io != NULL); assert(io->len <= io->size); + /* check overflow */ + if (len > ~(size_t)0 - (size_t)(io->buf + io->len)) { + return 0; + } + if (len <= 0) { } else if (io->len + len <= io->size) { memcpy(io->buf + io->len, buf, len); @@ -2893,7 +2898,7 @@ static void send_websocket_handshake(struct mg_connection *conn, static int deliver_websocket_frame(struct connection *conn) { // Having buf unsigned char * is important, as it is used below in arithmetic 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; if (buf_len >= 2) { @@ -2904,10 +2909,10 @@ static int deliver_websocket_frame(struct connection *conn) { header_len = 2 + mask_len; } else if (len == 126 && buf_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) { 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]); } } @@ -2938,10 +2943,15 @@ static int deliver_websocket_frame(struct connection *conn) { } size_t mg_websocket_write(struct mg_connection *conn, int opcode, - const char *data, size_t data_len) { + const char *data, size_t data_len) { unsigned char mem[4192], *copy = mem; size_t copy_len = 0; + /* Check overflow */ + if (data_len > ~(size_t)0 - (size_t)10) { + return 0; + } + if (data_len + 10 > sizeof(mem) && (copy = (unsigned char *) NS_MALLOC(data_len + 10)) == NULL) { return 0;