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().
This commit is contained in:
Maxim Dounin 2012-02-22 11:28:53 +00:00
parent b4363125b6
commit f0cedf7c8e
1 changed files with 2 additions and 1 deletions

View File

@ -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);
}
}