about summary refs log tree commit diff
path: root/shared/nm-std-aux/nm-std-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/nm-std-aux/nm-std-utils.c')
-rw-r--r--shared/nm-std-aux/nm-std-utils.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/shared/nm-std-aux/nm-std-utils.c b/shared/nm-std-aux/nm-std-utils.c
index 6f7f4c58..18692b19 100644
--- a/shared/nm-std-aux/nm-std-utils.c
+++ b/shared/nm-std-aux/nm-std-utils.c
@@ -1,10 +1,12 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include "nm-default.h"
+#include "nm-default-std.h"
 
 #include "nm-std-utils.h"
 
 #include <stdint.h>
+#include <assert.h>
+#include <limits.h>
 
 /*****************************************************************************/
 
@@ -50,7 +52,7 @@ nm_utils_get_next_realloc_size(bool true_realloc, size_t requested)
          * We get thus sizes of 104, 232, 488, 1000, 2024, 4072, 8168... */
 
         if (NM_UNLIKELY(requested > SIZE_MAX / 2u - 24u))
-            return SIZE_MAX;
+            goto out_huge;
 
         x = requested + 24u;
         n = 128u;
@@ -63,8 +65,10 @@ nm_utils_get_next_realloc_size(bool true_realloc, size_t requested)
         return n - 24u;
     }
 
-    if (NM_UNLIKELY(requested > SIZE_MAX - 0x1000u - 24u))
-        return SIZE_MAX;
+    if (NM_UNLIKELY(requested > SIZE_MAX - 0x1000u - 24u)) {
+        /* overflow happened. */
+        goto out_huge;
+    }
 
     /* For large allocations (with !true_realloc) we allocate memory in chunks of
      * 4K (- 24 bytes extra), assuming that the memory gets mmapped and thus
@@ -72,4 +76,15 @@ nm_utils_get_next_realloc_size(bool true_realloc, size_t requested)
     n = ((requested + (0x0FFFu + 24u)) & ~((size_t) 0x0FFFu)) - 24u;
     nm_assert(n >= requested);
     return n;
+
+out_huge:
+    if (sizeof(size_t) > 4u) {
+        /* on s390x (64 bit), gcc with LTO can complain that the size argument to
+         * malloc must not be larger than 9223372036854775807.
+         *
+         * Work around that by returning SSIZE_MAX. It should be plenty still! */
+        assert(requested <= (size_t) SSIZE_MAX);
+        return (size_t) SSIZE_MAX;
+    }
+    return SIZE_MAX;
 }