New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 2 users
Status: Fixed
Owner:
Email to this user bounced
Closed: Apr 2015
Cc:



Sign in to add a comment
Mongoose Web Server - Multiple integer issues
Project Member Reported by markbrand@google.com, Jan 21 2015 Back to list
Integer overflow in iobuf_append

eg. if io->len == io->size = 0x1000 and len == 0xffffffff

size_t iobuf_append(struct iobuf *io, const void *buf, size_t len) {
  char *p = NULL;

  assert(io != NULL);
  assert(io->len <= io->size);

  if (len <= 0) {
  } else if (io->len + len <= io->size) {    <---- io->len + len = 0xfff < 0x1000
    memcpy(io->buf + io->len, buf, len);     <---- whoops!
    io->len += len;
  } else if ((p = (char *) NS_REALLOC(io->buf, io->len + len)) != NULL) {
    io->buf = p;
    memcpy(io->buf + io->len, buf, len);
    io->len += len;
    io->size = io->len;
  } else {
    len = 0;
  }

  return len;
}


Integer issues in deliver_websocket_frame

int type is used for length type; it’s not really adequate;

data_len = (int) (((uint64_t) htonl(* (uint32_t *) &buf[2])) << 32) + htonl(* (uint32_t *) &buf[6]);

On 32-bit systems a packet of length > 0x7fffffff has negative length, and any packet of length > 0xffffffff will be truncated to the 32-bit component. On 64-bit systems, there are still issues with negative lengths. data_len is later assigned to a size_t type; so at the moment this code is safe, but it’s definitely not working as intended for 32-bit systems.


Integer overflow in mg_websocket_write resulting in stack corruption

eg. if data_len == 0xffffffff

size_t mg_websocket_write(struct mg_connection *conn, int opcode,
                       const char *data, size_t data_len) {
    unsigned char mem[4192], *copy = mem;
    size_t copy_len = 0;
    
    fprintf(stderr, "mg_websocket_write %u\n", data_len);

    if (data_len + 10 > sizeof(mem) &&    <---- data_len + 10 == 9 < sizeof(mem)
        (copy = (unsigned char *) NS_MALLOC(data_len + 10)) == NULL) {
      return 0;
    }
    
    fprintf(stderr, "copy = %p\n", copy);

    copy[0] = 0x80 + (opcode & 0x0f);

    // Frame format: http://tools.ietf.org/html/rfc6455#section-5.2
    if (data_len < 126) {
      // Inline 7-bit length field
      copy[1] = data_len;
      memcpy(copy + 2, data, data_len);
      copy_len = 2 + data_len;
    } else if (data_len <= 0xFFFF) {
      // 16-bit length field
      copy[1] = 126;
      * (uint16_t *) (copy + 2) = (uint16_t) htons((uint16_t) data_len);
      memcpy(copy + 4, data, data_len);
      copy_len = 4 + data_len;
    } else {
      // 64-bit length field
      copy[1] = 127;
      const uint32_t hi = htonl((uint32_t) ((uint64_t) data_len >> 32));
      const uint32_t lo = htonl(data_len & 0xffffffff);
      memcpy(copy+2,&hi,sizeof(hi));
      memcpy(copy+6,&lo,sizeof(lo));
      fprintf(stderr, "copy %p %p %u\n", copy+10, data, data_len);
      memcpy(copy + 10, data, data_len);    <---- copying 0xffffffff bytes into 4192 byte stack buffer
      copy_len = 10 + data_len;
    }

    if (copy_len > 0) {
      mg_write(conn, copy, copy_len);
    }
    if (copy != mem) {
      NS_FREE(copy);
    }

    // If we send closing frame, schedule a connection to be closed after
    // data is drained to the client.
    if (opcode == WEBSOCKET_OPCODE_CONNECTION_CLOSE) {
      MG_CONN_2_CONN(conn)->ns_conn->flags |= NSF_FINISHED_SENDING_DATA;
    }

    return MG_CONN_2_CONN(conn)->ns_conn->send_iobuf.len;
}

This issue is triggerable in the example websocket_echo_server by sending a websocket request of length 0xffffffff

This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.

 
mongoose.py
1018 bytes View Download
Project Member Comment 1 by scvitti@google.com, Jan 22 2015
Labels: -Reported-2014-Jan-21 Reported-2015-Jan-21
Project Member Comment 2 by markbrand@google.com, Apr 24 2015
Labels: -Restrict-View-Commit Fixed-2015-Mar-8
Making publicly viewable; missed this one when the initial patch notification came in.
Comment 3 by cevans@google.com, Apr 24 2015
Status: Fixed
Project Member Comment 4 by markbrand@google.com, Apr 24 2015
Labels: -Fixed-2015-Mar-8 Fixed-2015-Mar-17
Further details on fix - patch details were sent to me on 2015-Mar-08; the patch was released in v5.6 of Mongoose on 2015-Mar-17; I've updated the fix date accordingly.
Sign in to add a comment