diff --git a/changes-entries/socache-header-parse-bounds.txt b/changes-entries/socache-header-parse-bounds.txt new file mode 100644 index 00000000000..b3e05b5ff57 --- /dev/null +++ b/changes-entries/socache-header-parse-bounds.txt @@ -0,0 +1,5 @@ + *) mod_cache_socache: Bound the cached-header parser to the retrieved entry + length so a truncated or corrupt socache record cannot advance the parse + position past the end of the data, which caused an apr_size_t underflow of + the body length and an out-of-bounds read when recalling the response. + [arshiya tabasum ] diff --git a/modules/cache/mod_cache_socache.c b/modules/cache/mod_cache_socache.c index 78bd3e7bb4c..a6e4f6a7985 100644 --- a/modules/cache/mod_cache_socache.c +++ b/modules/cache/mod_cache_socache.c @@ -150,7 +150,7 @@ static apr_status_t read_array(request_rec *r, apr_array_header_t *arr, *((const char **) apr_array_push(arr)) = apr_pstrndup(r->pool, (const char *) buffer + val, *slider - val); (*slider)++; - if (buffer[*slider] == '\n') { + if (*slider < buffer_len && buffer[*slider] == '\n') { (*slider)++; } val = *slider; @@ -209,7 +209,7 @@ static apr_status_t read_table(cache_handle_t *handle, request_rec *r, len = colon; if (key == *slider) { (*slider)++; - if (buffer[*slider] == '\n') { + if (*slider < buffer_len && buffer[*slider] == '\n') { (*slider)++; } return APR_SUCCESS; @@ -227,7 +227,7 @@ static apr_status_t read_table(cache_handle_t *handle, request_rec *r, + key, len - key), apr_pstrmemdup(r->pool, (const char *) buffer + colon, *slider - colon)); (*slider)++; - if (buffer[*slider] == '\n') { + if (*slider < buffer_len && buffer[*slider] == '\n') { (*slider)++; } key = *slider;