]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* modules/http/http_filters.c (parse_chunk_size): Reduce by four the
authorJoe Orton <jorton@apache.org>
Mon, 17 Feb 2020 08:20:52 +0000 (08:20 +0000)
committerJoe Orton <jorton@apache.org>
Mon, 17 Feb 2020 08:20:52 +0000 (08:20 +0000)
  limit to the number of bits that can be handled in a chunk size, to
  avoid undefined behaviour bitshifting a signed integer left.  Max
  chunk size on 32-bit arch is now 32MiB.  Avoids UBSan error in:

http_filters.c:227:46: runtime error: left shift of 768614336404564650 by 4 places cannot be represented in type 'long int'

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1874102 13f79535-47bb-0310-9956-ffa450edef68

modules/http/http_filters.c

index 42423e4ddedee23f7035aed674320d4087ed9f9d..5bebe2c500c13e63dc8234c7dd777247fd38e59e 100644 (file)
@@ -139,7 +139,11 @@ static apr_status_t parse_chunk_size(http_ctx_t *ctx, const char *buffer,
                 ctx->state = BODY_CHUNK_PART;
             }
             ctx->remaining = 0;
-            ctx->chunkbits = sizeof(apr_off_t) * 8;
+            /* The maximum number of bits that can be handled in a
+             * chunk size is in theory sizeof(apr_off_t)*8-1 since
+             * off_t is signed, but use -4 to avoid undefined
+             * behaviour when bitshifting left. */
+            ctx->chunkbits = sizeof(apr_off_t) * 8 - 4;
             ctx->chunk_used = 0;
             ctx->chunk_bws = 0;
         }
@@ -226,7 +230,8 @@ static apr_status_t parse_chunk_size(http_ctx_t *ctx, const char *buffer,
 
             ctx->remaining = (ctx->remaining << 4) | xvalue;
             if (ctx->remaining < 0) {
-                /* overflow */
+                /* Overflow - should be unreachable since the
+                 * chunkbits limit will be reached first. */
                 return APR_ENOSPC;
             }
         }