diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2012-02-22 11:28:53 +0000 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2012-02-22 11:28:53 +0000 |
commit | b5d0d7a232f57f26a340e7e391110055c9fcd876 (patch) | |
tree | e19ef9197dcd6099996141975535bae02f17801d /src | |
parent | 86c5513ecb34ab90027935c329e74b41fdc3a49e (diff) | |
download | nginx-b5d0d7a232f57f26a340e7e391110055c9fcd876.tar.gz nginx-b5d0d7a232f57f26a340e7e391110055c9fcd876.zip |
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().
Diffstat (limited to 'src')
-rw-r--r-- | src/event/ngx_event_pipe.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c index 62358ead1..b959ff4ff 100644 --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -401,13 +401,14 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p) if (cl->buf->last - cl->buf->pos >= p->length) { + p->free_raw_bufs = cl->next; + /* STUB */ cl->buf->num = p->num++; if (p->input_filter(p, cl->buf) == NGX_ERROR) { return NGX_ABORT; } - p->free_raw_bufs = cl->next; ngx_free_chain(p->pool, cl); } } |