From f6422af80ab54eddf5f1344bec7ddab9ab240924 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 a80b7d14..dc642034 100644 --- a/src/unix/kqueue.c +++ b/src/unix/kqueue.c @@ -168,11 +168,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. */