summaryrefslogtreecommitdiffstats
path: root/server/util.c
diff options
context:
space:
mode:
authorChristophe Jaillet <jailletc36@apache.org>2021-08-10 20:49:20 +0200
committerChristophe Jaillet <jailletc36@apache.org>2021-08-10 20:49:20 +0200
commit9226cbc6b92492615856b567ac7f7557f196634b (patch)
tree4b86ffdb5bf21daed0ea1130490416750d4a383c /server/util.c
parentap_timeout_parameter_parse: axe unsigned < 0 check (diff)
downloadapache2-9226cbc6b92492615856b567ac7f7557f196634b.tar.xz
apache2-9226cbc6b92492615856b567ac7f7557f196634b.zip
Follow up to 1892038, 1892063.
Improve fix to please a fuzzer which reports: util.c:2713:26: runtime error: signed integer overflow: 9999999999999999 * 1000 cannot be represented in type 'long' Compute the maximum limit for each case 's', 'h', 'ms' and 'mi' and make sure that the input is below this value. While at it, move a comment to make things more consistent and use 'apr_time_from_msec() instead of hand writing it. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1892185 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/util.c')
-rw-r--r--server/util.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/server/util.c b/server/util.c
index 4a35eac6b0..d87417f762 100644
--- a/server/util.c
+++ b/server/util.c
@@ -2668,6 +2668,7 @@ AP_DECLARE(char *) ap_append_pid(apr_pool_t *p, const char *string,
* in timeout_parameter.
* @return Status value indicating whether the parsing was successful or not.
*/
+#define CHECK_OVERFLOW(a, b) if (a > b) return APR_ERANGE
AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
const char *timeout_parameter,
apr_interval_time_t *timeout,
@@ -2697,11 +2698,13 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
/* Time is in seconds */
case 's':
case 'S':
+ CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX));
check = apr_time_from_sec(tout);
break;
+ /* Time is in hours */
case 'h':
case 'H':
- /* Time is in hours */
+ CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX / 3600));
check = apr_time_from_sec(tout * 3600);
break;
case 'm':
@@ -2710,11 +2713,13 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
/* Time is in milliseconds */
case 's':
case 'S':
- check = tout * 1000;
+ CHECK_OVERFLOW(tout, apr_time_as_msec(APR_INT64_MAX));
+ check = apr_time_from_msec(tout);
break;
/* Time is in minutes */
case 'i':
case 'I':
+ CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX / 60));
check = apr_time_from_sec(tout * 60);
break;
default:
@@ -2724,12 +2729,11 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
default:
return APR_EGENERAL;
}
- if (check > APR_INT64_MAX || check < tout) {
- return APR_ERANGE;
- }
- *timeout = (apr_interval_time_t) check;
+
+ *timeout = (apr_interval_time_t)check;
return APR_SUCCESS;
}
+#undef CHECK_OVERFLOW
AP_DECLARE(int) ap_parse_strict_length(apr_off_t *len, const char *str)
{