[PATCH] Fixing a segmentation fault when resolver and poll are used together

agentzh agentzh at gmail.com
Tue Jan 22 22:56:34 UTC 2013


Hello!

I've noticed a segmentation fault caught by Valgrind/Memcheck when
using ngx_resolver and ngx_poll_module together with Nginx 1.2.6 on
Linux x86_64 (and i386 too):

    ==25191== Jump to the invalid address stated on the next line
    ==25191==    at 0x0: ???
    ==25191==    by 0x42CC67: ngx_event_process_posted (ngx_event_posted.c:40)
    ==25191==    by 0x42C7E7: ngx_process_events_and_timers (ngx_event.c:274)
    ==25191==    by 0x434BCB: ngx_single_process_cycle (ngx_process_cycle.c:315)
    ==25191==    by 0x416981: main (nginx.c:409)
    ==25191==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
    ==25191==

It crashes on the following source line in src/event/ngx_event_posted.c:

    ev->handler(ev);

The minimized config sample is as follows:

    events {
        use poll;
    }

    http {
        server {
            listen 8080;

            location /t {
                set $myserver nginx.org;
                proxy_pass http://$myserver/;
                resolver 127.0.0.1;
            }
        }
    }

assuming that there's nothing listening on the local port 53.

Basically, when POLLERR happens ngx_poll_module will generate both a
write event and a read event for the current connection but there is
no write event handler registered for the UDP connection created in
ngx_resolver.c, thus leading to calling a NULL function pointer.

The simplest fix (though maybe not the most reasonable) is to register
an empty write event handler in ngx_resolver.c, as shown in the patch
attached to this mail (already tested on my side).

Best regards,
-agentzh

--- nginx-1.2.6/src/core/ngx_resolver.c	2012-11-12 10:47:07.000000000 -0800
+++ nginx-1.2.6-patched/src/core/ngx_resolver.c	2013-01-22
14:52:42.716434183 -0800
@@ -91,6 +91,7 @@ static void *ngx_resolver_dup(ngx_resolv
 static in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src,
     ngx_uint_t n);
 static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
+static void ngx_resolver_empty_handler(ngx_event_t *ev);


 ngx_resolver_t *
@@ -2258,6 +2259,8 @@ ngx_udp_connect(ngx_udp_connection_t *uc
     rev->log = &uc->log;
     wev->log = &uc->log;

+    wev->handler = ngx_resolver_empty_handler;
+
     uc->connection = c;

     c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
@@ -2311,3 +2314,9 @@ ngx_udp_connect(ngx_udp_connection_t *uc

     return NGX_OK;
 }
+
+
+static void
+ngx_resolver_empty_handler(ngx_event_t *ev)
+{
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nginx-1.2.6-resolver_wev_handler_segfault_with_poll.patch
Type: application/octet-stream
Size: 890 bytes
Desc: not available
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20130122/517f02af/attachment.obj>


More information about the nginx-devel mailing list