Hi there,

I stumbled across an edge case where apr_pstrmemdup could
detect an invalid combination of parameters but doesn't.
The patch against /trunk below addresses the problem with
minimal overhead for valid parameter values.

-- Stefan^2.

[[[
Make apr_pstrmemdup() detect cases where the string length is given
as APR_SIZE_MAX.

Note that this is virtually never allowed for correct code because
the source string would need to already be at least APR_SIZE_MAX
bytes long.  However, it may well act as a last line of defence in
case of caller malfunction.  This is consistent with the overflow
checks in the pool allocator.

* strings/apr_strings.c
  (apr_pstrmemdup): Test for arithmetic overflow.
]]]

[[[
Index: strings/apr_strings.c
===================================================================
--- strings/apr_strings.c       (revision 1716414)
+++ strings/apr_strings.c       (working copy)
@@ -103,7 +103,21 @@ APR_DECLARE(char *) apr_pstrmemdup(apr_p
     if (s == NULL) {
         return NULL;
     }
-    res = apr_palloc(a, n + 1);
+
+    if (n + 1 == 0) {
+        apr_abortfunc_t abort_fn = apr_pool_abort_get(a);
+        if (abort_fn)
+          abort_fn(APR_ENOMEM);
+
+        /* If we were not told how to terminate the process, behave
+ * consistently to APR pool allocations. Those would return + * NULL, causing a segfault further down the line. */
+        res = NULL;
+    }
+    else {
+        res = apr_palloc(a, n + 1);
+    }
+
     memcpy(res, s, n);
     res[n] = '\0';
     return res;
]]]

Reply via email to