diff options
author | Ole André Vadla Ravnås <oleavr@gmail.com> | 2015-03-17 13:33:55 -0600 |
---|---|---|
committer | Trevor Norris <trev.norris@gmail.com> | 2015-03-19 12:06:57 -0700 |
commit | 2fdeb7e9327e84df657bc146fd73aa269d05dfc5 (patch) | |
tree | c85bb6e15afa91b9971fe2b7d0a3ec1a55a77c76 | |
parent | 9613ac7cb8cf1c60516a8664f0f8abf7e3ade710 (diff) | |
download | node-2fdeb7e9327e84df657bc146fd73aa269d05dfc5.tar.gz |
uv: fix size calculation in select() fallback
Original commit message:
darwin: fix size calculation in select() fallback
Apple's `fd_set` stores its bits in an array of 32-bit integers, which
means `FD_ISSET()` may read out of bounds if we allocate storage at
byte granularity. There's also a chance that the `select()` call could
corrupt the heap, although I didn't investigate that.
This issue was discovered by LLVM's AddressSanitizer which caught
`FD_ISSET()` trying to read out of bounds.
Ref: https://github.com/libuv/libuv/pull/241
Reviewed-By: Julien Gilli <julien.gilli@joyent.com>
PR-URL: https://github.com/joyent/node/pull/9179
-rw-r--r-- | deps/uv/src/unix/internal.h | 3 | ||||
-rw-r--r-- | deps/uv/src/unix/stream.c | 2 |
2 files changed, 4 insertions, 1 deletions
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 101dc7454..31db5e29e 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -55,6 +55,9 @@ #define ACCESS_ONCE(type, var) \ (*(volatile type*) &(var)) +#define ROUND_UP(a, b) \ + ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a)) + #define UNREACHABLE() \ do { \ assert(0 && "unreachable code"); \ diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 518a2fce0..7de1d8215 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -301,7 +301,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) { if (fds[1] > max_fd) max_fd = fds[1]; - sread_sz = (max_fd + NBBY) / NBBY; + sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY; swrite_sz = sread_sz; s = malloc(sizeof(*s) + sread_sz + swrite_sz); |