From f166d6d7055bbd9da83594b045a496e15b3c302a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 21 Dec 2013 20:12:35 -0800 Subject: [PATCH] osx: Fix a possible segfault in uv__io_poll In our build infrastructure, I've seen a lot of segfaults recently that were all only happening on OSX. Upon inspecting the coredumps, it appearded that all segfaults happened at the same instruction, and upon translating the assembly back to the source, I found that an array could be indexed with a -1 index before the index was checked to be not -1. As concrete evidence, here is the situation that I found caused the segfault. The instruction in question along with the relevant register values was: mov (%r8,%r15,8),%r12 r8 = 0x7fb0ba800000 r15 = 0xffffffffffffffff r8 + r15 * 8 == 0x7fb0ba7ffff8 It appears that the base of loop->watchers was page aligned, and by going back one word I guess that the page wasn't mapped, causing our segfaults. --- src/unix/kqueue.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/unix/kqueue.c b/src/unix/kqueue.c index 70f5d9ed..f86f291f 100644 --- a/src/unix/kqueue.c +++ b/src/unix/kqueue.c @@ -167,11 +167,10 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { for (i = 0; i < nfds; i++) { ev = events + i; fd = ev->ident; - w = loop->watchers[fd]; - /* Skip invalidated events, see uv__platform_invalidate_fd */ if (fd == -1) continue; + w = loop->watchers[fd]; if (w == NULL) { /* File descriptor that we've stopped watching, disarm it. */