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().
Maxim Dounin
10 years ago
400 | 400 | |
401 | 401 | if (cl->buf->last - cl->buf->pos >= p->length) { |
402 | 402 | |
403 | p->free_raw_bufs = cl->next; | |
404 | ||
403 | 405 | /* STUB */ cl->buf->num = p->num++; |
404 | 406 | |
405 | 407 | if (p->input_filter(p, cl->buf) == NGX_ERROR) { |
406 | 408 | return NGX_ABORT; |
407 | 409 | } |
408 | 410 | |
409 | p->free_raw_bufs = cl->next; | |
410 | 411 | ngx_free_chain(p->pool, cl); |
411 | 412 | } |
412 | 413 | } |