fix int overflow in ap_timeout_parameter_parse
signed integer overflow in ap_timeout_parameter_parse under fuzzing
@@ -2676,6 +2676,7 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
char *endp;
const char *time_str;
apr_int64_t tout;
+ apr_uint64_t check;
tout = apr_strtoi64(timeout_parameter, &endp, 10);
if (errno) {
@@ -2688,16 +2689,20 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
time_str = endp;
}
+ if (tout < 0) {
+ return APR_ERANGE;
+ }
+
switch (*time_str) {
/* Time is in seconds */
case 's':
case 'S':
- *timeout = (apr_interval_time_t) apr_time_from_sec(tout);
+ check = apr_time_from_sec(tout);
break;
case 'h':
case 'H':
/* Time is in hours */
- *timeout = (apr_interval_time_t) apr_time_from_sec(tout * 3600);
+ check = apr_time_from_sec(tout * 3600);
break;
case 'm':
case 'M':
@@ -2705,12 +2710,12 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
/* Time is in milliseconds */
case 's':
case 'S':
- *timeout = (apr_interval_time_t) tout * 1000;
+ check = tout * 1000;
break;
/* Time is in minutes */
case 'i':
case 'I':
- *timeout = (apr_interval_time_t) apr_time_from_sec(tout * 60);
+ check = apr_time_from_sec(tout * 60);
break;
default:
return APR_EGENERAL;
@@ -2719,6 +2724,10 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
default:
return APR_EGENERAL;
}
+ if (check > APR_INT64_MAX || check < 0) {
+ return APR_ERANGE;
+ }
+ *timeout = (apr_interval_time_t) check;
return APR_SUCCESS;
}
