Mercurial > hg > nginx
comparison src/event/ngx_event_pipe.c @ 4489:9806bf07d119
Event pipe: fixed buffer loss in p->length case.
With previous code raw buffer might be lost if p->input_filter() was called
on a buffer without any data and used ngx_event_pipe_add_free_buf() to
return it to the free list. This eventually might cause "all buffers busy"
problem, resulting in segmentation fault due to null pointer dereference in
ngx_event_pipe_write_chain_to_temp_file().
In ngx_event_pipe_add_free_buf() the buffer was added to the list start
due to pos == last, and then "p->free_raw_bufs = cl->next" in
ngx_event_pipe_read_upstream() dropped both chain links to the buffer
from the p->free_raw_bufs list.
Fix is to move "p->free_raw_bufs = cl->next" before calling the
p->input_filter().
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 22 Feb 2012 11:28:53 +0000 |
parents | d620f497c50f |
children | 778ef9c3fd2d |
comparison
equal
deleted
inserted
replaced
4488:d33ce8cd0d70 | 4489:9806bf07d119 |
---|---|
399 if (p->free_raw_bufs && p->length != -1) { | 399 if (p->free_raw_bufs && p->length != -1) { |
400 cl = p->free_raw_bufs; | 400 cl = p->free_raw_bufs; |
401 | 401 |
402 if (cl->buf->last - cl->buf->pos >= p->length) { | 402 if (cl->buf->last - cl->buf->pos >= p->length) { |
403 | 403 |
404 p->free_raw_bufs = cl->next; | |
405 | |
404 /* STUB */ cl->buf->num = p->num++; | 406 /* STUB */ cl->buf->num = p->num++; |
405 | 407 |
406 if (p->input_filter(p, cl->buf) == NGX_ERROR) { | 408 if (p->input_filter(p, cl->buf) == NGX_ERROR) { |
407 return NGX_ABORT; | 409 return NGX_ABORT; |
408 } | 410 } |
409 | 411 |
410 p->free_raw_bufs = cl->next; | |
411 ngx_free_chain(p->pool, cl); | 412 ngx_free_chain(p->pool, cl); |
412 } | 413 } |
413 } | 414 } |
414 | 415 |
415 if (p->length == 0) { | 416 if (p->length == 0) { |