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) {