From 7ea44d0402334e40f31730d889c5ad60e158692d Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Fri, 6 Aug 2021 13:10:45 +0000
Subject: [PATCH] fix int overflow in ap_timeout_parameter_parse

signed integer overflow in ap_timeout_parameter_parse under fuzzing


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1892038 13f79535-47bb-0310-9956-ffa450edef68
---
 server/util.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/server/util.c b/server/util.c
index 2d7708ae851..6f9dbd4d657 100644
--- a/server/util.c
+++ b/server/util.c
@@ -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,14 +2689,18 @@ 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':
-        *timeout = (apr_interval_time_t) apr_time_from_sec(tout);
+        check = apr_time_from_sec(tout);
         break;
     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':
         switch (*(++time_str)) {
@@ -2705,11 +2710,11 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
         switch (*(++time_str)) {
         /* Time is in milliseconds */
         case 's':
-            *timeout = (apr_interval_time_t) tout * 1000;
+            check = tout * 1000;
             break;
         /* Time is in minutes */
         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;
 }
 
