comparison src/http/modules/ngx_http_grpc_module.c @ 7305:6cfd45d4c754

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 9e25a5380a21
children 696df3ac27ac
comparison
equal deleted inserted replaced
7304:5c2ac36fcf56 7305:6cfd45d4c754
3866 3866
3867 3867
3868 static ngx_chain_t * 3868 static ngx_chain_t *
3869 ngx_http_grpc_get_buf(ngx_http_request_t *r, ngx_http_grpc_ctx_t *ctx) 3869 ngx_http_grpc_get_buf(ngx_http_request_t *r, ngx_http_grpc_ctx_t *ctx)
3870 { 3870 {
3871 u_char *start;
3871 ngx_buf_t *b; 3872 ngx_buf_t *b;
3872 ngx_chain_t *cl; 3873 ngx_chain_t *cl;
3873 3874
3874 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); 3875 cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
3875 if (cl == NULL) { 3876 if (cl == NULL) {
3876 return NULL; 3877 return NULL;
3877 } 3878 }
3878 3879
3879 b = cl->buf; 3880 b = cl->buf;
3880 3881 start = b->start;
3881 b->tag = (ngx_buf_tag_t) &ngx_http_grpc_body_output_filter; 3882
3882 b->temporary = 1; 3883 if (start == NULL) {
3883 b->flush = 1;
3884
3885 if (b->start == NULL) {
3886 3884
3887 /* 3885 /*
3888 * each buffer is large enough to hold two window update 3886 * each buffer is large enough to hold two window update
3889 * frames in a row 3887 * frames in a row
3890 */ 3888 */
3891 3889
3892 b->start = ngx_palloc(r->pool, 2 * sizeof(ngx_http_grpc_frame_t) + 8); 3890 start = ngx_palloc(r->pool, 2 * sizeof(ngx_http_grpc_frame_t) + 8);
3893 if (b->start == NULL) { 3891 if (start == NULL) {
3894 return NULL; 3892 return NULL;
3895 } 3893 }
3896 3894
3897 b->pos = b->start; 3895 }
3898 b->last = b->start; 3896
3899 3897 ngx_memzero(b, sizeof(ngx_buf_t));
3900 b->end = b->start + 2 * sizeof(ngx_http_grpc_frame_t) + 8; 3898
3901 } 3899 b->start = start;
3900 b->pos = start;
3901 b->last = start;
3902 b->end = start + 2 * sizeof(ngx_http_grpc_frame_t) + 8;
3903
3904 b->tag = (ngx_buf_tag_t) &ngx_http_grpc_body_output_filter;
3905 b->temporary = 1;
3906 b->flush = 1;
3902 3907
3903 return cl; 3908 return cl;
3904 } 3909 }
3905 3910
3906 3911