[nginx] gRPC: clearing buffers in ngx_http_grpc_get_buf().
details: https://hg.nginx.org/nginx/rev/9ac0e8b9aced branches: stable-1.14 changeset: 7410:9ac0e8b9aced user: Maxim Dounin date: Mon Jul 02 19:02:08 2018 +0300 description: 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. diffstat: src/http/modules/ngx_http_grpc_module.c | 29 + 1 files changed, 17 insertions(+), 12 deletions(-) diffs (57 lines): 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 @@ -3883,6 +3883,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; @@ -3892,29 +3893,33 @@ ngx_http_grpc_get_buf(ngx_http_request_t } b = cl->buf; - -b->tag = (ngx_buf_tag_t) _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) _http_grpc_body_output_filter; +b->temporary = 1; +b->flush = 1; + return cl; } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] gRPC: clearing buffers in ngx_http_grpc_get_buf().
details: http://hg.nginx.org/nginx/rev/6cfd45d4c754 branches: changeset: 7305:6cfd45d4c754 user: Maxim Dounin date: Mon Jul 02 19:02:08 2018 +0300 description: 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. diffstat: src/http/modules/ngx_http_grpc_module.c | 29 + 1 files changed, 17 insertions(+), 12 deletions(-) diffs (57 lines): 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) _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) _http_grpc_body_output_filter; +b->temporary = 1; +b->flush = 1; + return cl; } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel