]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* server/util.c (ap_escape_shell_cmd, ap_escape_path_segment, trunk trunk
authorJoe Orton <jorton@apache.org>
Thu, 16 Apr 2026 07:49:22 +0000 (07:49 +0000)
committerJoe Orton <jorton@apache.org>
Thu, 16 Apr 2026 07:49:22 +0000 (07:49 +0000)
  ap_os_escape_path, ap_escape_urlencoded): Add integer overflow
  checks before apr_palloc buffer size calculations.  Compute
  strlen into a local variable and assert that the multiplied
  size does not exceed APR_SIZE_MAX.

Submitted by: Koda Reef <koda.reef5@gmail.com>
Github: closes #615

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1933099 13f79535-47bb-0310-9956-ffa450edef68

server/util.c

index bca2636fd2ba3aea259c657b05903eec6afee4f1..eda0eceaf9c33b39eab48139308b23d7b6d47160 100644 (file)
@@ -1816,8 +1816,10 @@ AP_DECLARE(char *) ap_escape_shell_cmd(apr_pool_t *p, const char *str)
     char *cmd;
     unsigned char *d;
     const unsigned char *s;
+    apr_size_t len = strlen(str);
 
-    cmd = apr_palloc(p, 2 * strlen(str) + 1);        /* Be safe */
+    ap_assert(len <= (APR_SIZE_MAX - 1) / 2);
+    cmd = apr_palloc(p, 2 * len + 1);
     d = (unsigned char *)cmd;
     s = (const unsigned char *)str;
     for (; *s; ++s) {
@@ -2073,7 +2075,9 @@ AP_DECLARE(char *) ap_escape_path_segment_buffer(char *copy, const char *segment
 
 AP_DECLARE(char *) ap_escape_path_segment(apr_pool_t *p, const char *segment)
 {
-    return ap_escape_path_segment_buffer(apr_palloc(p, 3 * strlen(segment) + 1), segment);
+    apr_size_t len = strlen(segment);
+    ap_assert(len <= (APR_SIZE_MAX - 1) / 3);
+    return ap_escape_path_segment_buffer(apr_palloc(p, 3 * len + 1), segment);
 }
 
 AP_DECLARE(char *) ap_os_escape_path(apr_pool_t *p, const char *path, int partial)
@@ -2082,11 +2086,17 @@ AP_DECLARE(char *) ap_os_escape_path(apr_pool_t *p, const char *path, int partia
      * Allocate another +1 to allow the caller to add a trailing '/' (see
      * comment in 'ap_sub_req_lookup_dirent')
      */
-    char *copy = apr_palloc(p, 3 * strlen(path) + 3 + 1);
-    const unsigned char *s = (const unsigned char *)path;
-    unsigned char *d = (unsigned char *)copy;
+    apr_size_t len = strlen(path);
+    char *copy;
+    const unsigned char *s;
+    unsigned char *d;
     unsigned c;
 
+    ap_assert(len <= (APR_SIZE_MAX - 4) / 3);
+    copy = apr_palloc(p, 3 * len + 3 + 1);
+    s = (const unsigned char *)path;
+    d = (unsigned char *)copy;
+
     if (!partial) {
         const char *colon = ap_strchr_c(path, ':');
         const char *slash = ap_strchr_c(path, '/');
@@ -2133,7 +2143,9 @@ AP_DECLARE(char *) ap_escape_urlencoded_buffer(char *copy, const char *buffer)
 
 AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *buffer)
 {
-    return ap_escape_urlencoded_buffer(apr_palloc(p, 3 * strlen(buffer) + 1), buffer);
+    apr_size_t len = strlen(buffer);
+    ap_assert(len <= (APR_SIZE_MAX - 1) / 3);
+    return ap_escape_urlencoded_buffer(apr_palloc(p, 3 * len + 1), buffer);
 }
 
 /* ap_escape_uri is now a macro for os_escape_path */