Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2012-10-30 15:14:24 +0400
committerMaxim Dounin <mdounin@mdounin.ru>2012-10-30 15:14:24 +0400
commit8e67fb4226e6357477f32fbdd1443fb2bdd00b69 (patch)
tree9652a94ee8448bd3b1fa77d65711538d119f5fe9
parentd310eeef3f25c788546c885434292575fdf67663 (diff)
Event pipe: fixed handling of buf_to_file data.
Input filter might free a buffer if there is no data in it, and in case of first buffer (used for cache header and request header, aka p->buf_to_file) this resulted in cache corruption. Buffer memory was reused to read upstream response before headers were written to disk. Fix is to avoid moving pointers in ngx_event_pipe_add_free_buf() to a buffer start if we were asked to free a buffer used by p->buf_to_file. This fixes occasional cache file corruption, usually resulted in "cache file ... has md5 collision" alerts. Reported by Anatoli Marinov.
-rw-r--r--src/event/ngx_event_pipe.c11
-rw-r--r--src/http/ngx_http_upstream.c1
2 files changed, 10 insertions, 2 deletions
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index c2c79837f..476d56e30 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -946,8 +946,15 @@ ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b)
return NGX_ERROR;
}
- b->pos = b->start;
- b->last = b->start;
+ if (p->buf_to_file && b->start == p->buf_to_file->start) {
+ b->pos = p->buf_to_file->last;
+ b->last = p->buf_to_file->last;
+
+ } else {
+ b->pos = b->start;
+ b->last = b->start;
+ }
+
b->shadow = NULL;
cl->buf = b;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 6c34f39d6..75ef64e55 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2287,6 +2287,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
return;
}
+ p->buf_to_file->start = u->buffer.start;
p->buf_to_file->pos = u->buffer.start;
p->buf_to_file->last = u->buffer.pos;
p->buf_to_file->temporary = 1;