# HG changeset patch # User Maxim Dounin # Date 1530547328 -10800 # Node ID 6cfd45d4c754c86c090f0c5b5bfdd1363bb975da # Parent 5c2ac36fcf564c72d070b7923cf028dc947aa9b4 gRPC: clearing buffers in ngx_http_grpc_get_buf(). We copy input buffers to our buffers, so various flags might be unexpectedly set in buffers returned by ngx_chain_get_free_buf(). In particular, the b->in_file flag might be set when the body was written to a file in a different context. With sendfile enabled this in turn might result in protocol corruption if such a buffer was reused for a control frame. Make sure to clear buffers and set only fields we really need to be set. diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c --- a/src/http/modules/ngx_http_grpc_module.c +++ b/src/http/modules/ngx_http_grpc_module.c @@ -3868,6 +3868,7 @@ ngx_http_grpc_send_window_update(ngx_htt static ngx_chain_t * ngx_http_grpc_get_buf(ngx_http_request_t *r, ngx_http_grpc_ctx_t *ctx) { + u_char *start; ngx_buf_t *b; ngx_chain_t *cl; @@ -3877,29 +3878,33 @@ ngx_http_grpc_get_buf(ngx_http_request_t } b = cl->buf; - - b->tag = (ngx_buf_tag_t) &ngx_http_grpc_body_output_filter; - b->temporary = 1; - b->flush = 1; - - if (b->start == NULL) { + start = b->start; + + if (start == NULL) { /* * each buffer is large enough to hold two window update * frames in a row */ - b->start = ngx_palloc(r->pool, 2 * sizeof(ngx_http_grpc_frame_t) + 8); - if (b->start == NULL) { + start = ngx_palloc(r->pool, 2 * sizeof(ngx_http_grpc_frame_t) + 8); + if (start == NULL) { return NULL; } - b->pos = b->start; - b->last = b->start; - - b->end = b->start + 2 * sizeof(ngx_http_grpc_frame_t) + 8; } + ngx_memzero(b, sizeof(ngx_buf_t)); + + b->start = start; + b->pos = start; + b->last = start; + b->end = start + 2 * sizeof(ngx_http_grpc_frame_t) + 8; + + b->tag = (ngx_buf_tag_t) &ngx_http_grpc_body_output_filter; + b->temporary = 1; + b->flush = 1; + return cl; }