Mercurial > hg > nginx
comparison src/http/modules/ngx_http_grpc_module.c @ 7410:9ac0e8b9aced stable-1.14
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 02 Jul 2018 19:02:08 +0300 |
parents | ed5b3c4c1284 |
children | c948804cd628 |
comparison
equal
deleted
inserted
replaced
7409:17ee239ae2e6 | 7410:9ac0e8b9aced |
---|---|
3881 | 3881 |
3882 | 3882 |
3883 static ngx_chain_t * | 3883 static ngx_chain_t * |
3884 ngx_http_grpc_get_buf(ngx_http_request_t *r, ngx_http_grpc_ctx_t *ctx) | 3884 ngx_http_grpc_get_buf(ngx_http_request_t *r, ngx_http_grpc_ctx_t *ctx) |
3885 { | 3885 { |
3886 u_char *start; | |
3886 ngx_buf_t *b; | 3887 ngx_buf_t *b; |
3887 ngx_chain_t *cl; | 3888 ngx_chain_t *cl; |
3888 | 3889 |
3889 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); | 3890 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
3890 if (cl == NULL) { | 3891 if (cl == NULL) { |
3891 return NULL; | 3892 return NULL; |
3892 } | 3893 } |
3893 | 3894 |
3894 b = cl->buf; | 3895 b = cl->buf; |
3895 | 3896 start = b->start; |
3896 b->tag = (ngx_buf_tag_t) &ngx_http_grpc_body_output_filter; | 3897 |
3897 b->temporary = 1; | 3898 if (start == NULL) { |
3898 b->flush = 1; | |
3899 | |
3900 if (b->start == NULL) { | |
3901 | 3899 |
3902 /* | 3900 /* |
3903 * each buffer is large enough to hold two window update | 3901 * each buffer is large enough to hold two window update |
3904 * frames in a row | 3902 * frames in a row |
3905 */ | 3903 */ |
3906 | 3904 |
3907 b->start = ngx_palloc(r->pool, 2 * sizeof(ngx_http_grpc_frame_t) + 8); | 3905 start = ngx_palloc(r->pool, 2 * sizeof(ngx_http_grpc_frame_t) + 8); |
3908 if (b->start == NULL) { | 3906 if (start == NULL) { |
3909 return NULL; | 3907 return NULL; |
3910 } | 3908 } |
3911 | 3909 |
3912 b->pos = b->start; | 3910 } |
3913 b->last = b->start; | 3911 |
3914 | 3912 ngx_memzero(b, sizeof(ngx_buf_t)); |
3915 b->end = b->start + 2 * sizeof(ngx_http_grpc_frame_t) + 8; | 3913 |
3916 } | 3914 b->start = start; |
3915 b->pos = start; | |
3916 b->last = start; | |
3917 b->end = start + 2 * sizeof(ngx_http_grpc_frame_t) + 8; | |
3918 | |
3919 b->tag = (ngx_buf_tag_t) &ngx_http_grpc_body_output_filter; | |
3920 b->temporary = 1; | |
3921 b->flush = 1; | |
3917 | 3922 |
3918 return cl; | 3923 return cl; |
3919 } | 3924 } |
3920 | 3925 |
3921 | 3926 |