[PATCH] Fixing a segmentation fault when resolver and poll are used together
Maxim Dounin
mdounin at mdounin.ru
Wed Jan 23 15:55:28 UTC 2013
Hello!
On Wed, Jan 23, 2013 at 12:13:41PM +0400, Ruslan Ermilov wrote:
> On Tue, Jan 22, 2013 at 02:56:34PM -0800, agentzh wrote:
> > 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
>
> First of all, thanks for catching the bug!
>
> I propose one of these patches instead:
>
> %%%
> Index: src/event/modules/ngx_poll_module.c
> ===================================================================
> --- src/event/modules/ngx_poll_module.c (revision 5013)
> +++ src/event/modules/ngx_poll_module.c (working copy)
> @@ -366,7 +366,13 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_ms
> * active handler
> */
>
> - revents |= POLLIN|POLLOUT;
> + if (c->read->active) {
> + revents |= POLLIN;
> + }
> +
> + if (c->write->active) {
> + revents |= POLLOUT;
> + }
> }
>
> found = 0;
> %%%
>
> %%%
> Index: src/event/modules/ngx_poll_module.c
> ===================================================================
> --- src/event/modules/ngx_poll_module.c (revision 5013)
> +++ src/event/modules/ngx_poll_module.c (working copy)
> @@ -371,7 +371,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_ms
>
> found = 0;
>
> - if (revents & POLLIN) {
> + if ((revents & POLLIN) && c->read->active) {
> found = 1;
>
> ev = c->read;
> @@ -388,7 +388,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_ms
> ngx_locked_post_event(ev, queue);
> }
>
> - if (revents & POLLOUT) {
> + if ((revents & POLLOUT) && c->write->active) {
> found = 1;
> ev = c->write;
>
> %%%
>
> While the first patch looks more natural to me, the second patch is
> in line with the ngx_epoll_process_events() code.
Second one also consistent with rtsig code (and might also catch
other strange cases of unexpected events), I vote for it. Please
go ahead and commit it.
--
Maxim Dounin
http://nginx.com/support.html
More information about the nginx-devel
mailing list