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