diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2018-07-02 19:02:08 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2018-07-02 19:02:08 +0300 |
commit | a60bdcd8236919ced645115025d5cadaab295463 (patch) | |
tree | 1803d57d8ec30bb01f6dbc83d5565387272d6a67 | |
parent | 4050b961af7217e115964443cb7500bf7e02e64e (diff) |
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.
-rw-r--r-- | src/http/modules/ngx_http_grpc_module.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c index 808198bfd..1ab1d2990 100644 --- 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_http_request_t *r, 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 *r, ngx_http_grpc_ctx_t *ctx) } b = cl->buf; + start = b->start; - b->tag = (ngx_buf_tag_t) &ngx_http_grpc_body_output_filter; - b->temporary = 1; - b->flush = 1; - - if (b->start == NULL) { + 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; } |