[PATCH] gRPC: fixed bug when padding is used in DATA frame

geniuss99 geniuss.dev at gmail.com
Tue Mar 16 19:04:27 UTC 2021


 src/http/modules/ngx_http_grpc_module.c |  16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)


# HG changeset patch
# User geniuss99 <geniuss.dev at gmail.com>
# Date 1615921026 -10800
#      Tue Mar 16 21:57:06 2021 +0300
# Node ID 13552d5b785104f9d137d956a6cbef25ec09b345
# Parent  ed1348e8e25381b3b1a2540289effcf7ccec6fd6
gRPC: fixed bug when padding is used in DATA frame.

As per RFC 7540 DATA frame MAY contain padding if the PADDED flag is set
in "Type" field (see clause 6.1).

When such frame is sent from an upstream which previously defined payload
length via "Content-Length" header nginx fails with an error: "upstream sent
response body larger than indicated content length".

This happens because padding is not taken into account while comparing expected
and received payload length.

diff -r ed1348e8e253 -r 13552d5b7851 src/http/modules/ngx_http_grpc_module.c
--- a/src/http/modules/ngx_http_grpc_module.c	Thu Mar 11 20:49:39 2021 +0300
+++ b/src/http/modules/ngx_http_grpc_module.c	Tue Mar 16 21:57:06 2021 +0300
@@ -2075,14 +2075,24 @@
                 }
 
                 if (ctx->length != -1) {
-                    if ((off_t) ctx->rest > ctx->length) {
+                    if (ctx->flags & NGX_HTTP_V2_PADDED_FLAG) {
+                        if (b->pos < b->last) {
+                            u_char pad_length = *b->pos;
+                            size_t payload_data_length = ctx->rest - pad_length - 1; // frame_payload_size_bytes - pad_length_bytes - pad_length_field_1_byte
+
+                            ctx->length -= payload_data_length;
+                        }
+
+                    } else {
+                        ctx->length -= ctx->rest;
+                    }
+
+                    if (ctx->length < 0) {
                         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                                       "upstream sent response body larger "
                                       "than indicated content length");
                         return NGX_ERROR;
                     }
-
-                    ctx->length -= ctx->rest;
                 }
 
                 if (ctx->rest > ctx->recv_window) {


More information about the nginx-devel mailing list