From: Joe Orton Date: Mon, 17 Feb 2020 08:20:52 +0000 (+0000) Subject: * modules/http/http_filters.c (parse_chunk_size): Reduce by four the X-Git-Tag: 2.5.0-alpha2-ci-test-only~1649 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b853e4925d903ec58cb887616ba6a5d17df99f8a;p=thirdparty%2Fapache%2Fhttpd.git * modules/http/http_filters.c (parse_chunk_size): Reduce by four the 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 --- diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index 42423e4dded..5bebe2c500c 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -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; } }