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.

PR-URL: https://github.com/libuv/libuv/pull/241
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
Ole André Vadla Ravnås 2015-03-05 20:56:00 +01:00 committed by Ben Noordhuis
parent c272f1f1bc
commit d557ad73e0
2 changed files with 4 additions and 1 deletions

View File

@ -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"); \

View File

@ -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 = uv__malloc(sizeof(*s) + sread_sz + swrite_sz);