djdelorie / rpms / glibc

Forked from rpms/glibc 3 years ago
Clone
8597553
commit 5898f4548efdcd7c0fd437a74eeb80facc51a117
8597553
Author: Florian Weimer <fweimer@redhat.com>
8597553
Date:   Wed Aug 30 20:10:56 2017 +0200
8597553
8597553
    dynarray: Set errno on overflow-induced allocation failure
8597553
    
8597553
    This allows the caller to return directly on such an error, with an
8597553
    appropriate errno value.
8597553
8597553
diff --git a/malloc/dynarray_emplace_enlarge.c b/malloc/dynarray_emplace_enlarge.c
8597553
index dfc70017cec23800..0fb032765cc99952 100644
8597553
--- a/malloc/dynarray_emplace_enlarge.c
8597553
+++ b/malloc/dynarray_emplace_enlarge.c
8597553
@@ -17,6 +17,7 @@
8597553
    <http://www.gnu.org/licenses/>.  */
8597553
 
8597553
 #include <dynarray.h>
8597553
+#include <errno.h>
8597553
 #include <malloc-internal.h>
8597553
 #include <stdlib.h>
8597553
 #include <string.h>
8597553
@@ -43,8 +44,11 @@ __libc_dynarray_emplace_enlarge (struct dynarray_header *list,
8597553
     {
8597553
       new_allocated = list->allocated + list->allocated / 2 + 1;
8597553
       if (new_allocated <= list->allocated)
8597553
-        /* Overflow.  */
8597553
-        return false;
8597553
+        {
8597553
+          /* Overflow.  */
8597553
+          __set_errno (ENOMEM);
8597553
+          return false;
8597553
+        }
8597553
     }
8597553
 
8597553
   size_t new_size;
8597553
diff --git a/malloc/dynarray_resize.c b/malloc/dynarray_resize.c
8597553
index e6dc9fbc68587de4..63c981bf61f67145 100644
8597553
--- a/malloc/dynarray_resize.c
8597553
+++ b/malloc/dynarray_resize.c
8597553
@@ -17,6 +17,7 @@
8597553
    <http://www.gnu.org/licenses/>.  */
8597553
 
8597553
 #include <dynarray.h>
8597553
+#include <errno.h>
8597553
 #include <malloc-internal.h>
8597553
 #include <stdlib.h>
8597553
 #include <string.h>
8597553
@@ -38,7 +39,11 @@ __libc_dynarray_resize (struct dynarray_header *list, size_t size,
8597553
 
8597553
   size_t new_size_bytes;
8597553
   if (check_mul_overflow_size_t (size, element_size, &new_size_bytes))
8597553
-    return false;
8597553
+    {
8597553
+      /* Overflow.  */
8597553
+      __set_errno (ENOMEM);
8597553
+      return false;
8597553
+    }
8597553
   void *new_array;
8597553
   if (list->array == scratch)
8597553
     {
8597553
diff --git a/malloc/tst-dynarray.c b/malloc/tst-dynarray.c
8597553
index 2206d75e318aaa3f..d11f7bb8a343a16a 100644
8597553
--- a/malloc/tst-dynarray.c
8597553
+++ b/malloc/tst-dynarray.c
8597553
@@ -18,6 +18,9 @@
8597553
 
8597553
 #include "tst-dynarray-shared.h"
8597553
 
8597553
+#include <errno.h>
8597553
+#include <stdint.h>
8597553
+
8597553
 #define DYNARRAY_STRUCT dynarray_long
8597553
 #define DYNARRAY_ELEMENT long
8597553
 #define DYNARRAY_PREFIX dynarray_long_
8597553
@@ -463,6 +466,31 @@ test_long_init (void)
8597553
   }
8597553
 }
8597553
 
8597553
+/* Test overflow in resize.  */
8597553
+static void
8597553
+test_long_overflow (void)
8597553
+{
8597553
+  {
8597553
+    struct dynarray_long dyn;
8597553
+    dynarray_long_init (&dyn);
8597553
+    errno = EINVAL;
8597553
+    TEST_VERIFY (!dynarray_long_resize
8597553
+                 (&dyn, (SIZE_MAX / sizeof (long)) + 1));
8597553
+    TEST_VERIFY (errno == ENOMEM);
8597553
+    TEST_VERIFY (dynarray_long_has_failed (&dyn));
8597553
+  }
8597553
+
8597553
+  {
8597553
+    struct dynarray_long_noscratch dyn;
8597553
+    dynarray_long_noscratch_init (&dyn);
8597553
+    errno = EINVAL;
8597553
+    TEST_VERIFY (!dynarray_long_noscratch_resize
8597553
+                 (&dyn, (SIZE_MAX / sizeof (long)) + 1));
8597553
+    TEST_VERIFY (errno == ENOMEM);
8597553
+    TEST_VERIFY (dynarray_long_noscratch_has_failed (&dyn));
8597553
+  }
8597553
+}
8597553
+
8597553
 /* Test NUL-terminated string construction with the add function and
8597553
    the simple finalize function.  */
8597553
 static void
8597553
@@ -538,6 +566,7 @@ do_test (void)
8597553
   test_int ();
8597553
   test_str ();
8597553
   test_long_init ();
8597553
+  test_long_overflow ();
8597553
   test_zstr ();
8597553
   return 0;
8597553
 }