diff options
author | 2018-12-21 10:21:41 +0100 | |
---|---|---|
committer | 2018-12-21 16:39:34 +0100 | |
commit | 830464c3e44c9a9c06dc613555663a3e7389d8b9 (patch) | |
tree | 4157d80c047a6aae028658501691c0a3cc5a2f83 | |
parent | analyze: add assert to verify we are not dividing by 0 (diff) | |
download | systemd-830464c3e44c9a9c06dc613555663a3e7389d8b9.tar.gz systemd-830464c3e44c9a9c06dc613555663a3e7389d8b9.tar.bz2 systemd-830464c3e44c9a9c06dc613555663a3e7389d8b9.zip |
tree-wide: make new/new0/malloc_multiply/reallocarray safe for size 0
All underlying glibc calls are free to return NULL if the size argument
is 0. We most often call those functions with a fixed argument, or at least
something which obviously cannot be zero, but it's too easy to forget.
E.g. coverity complains about "rows = new0(JsonVariant*, n_rows-1);" in
format-table.c There is an assert that n_rows > 0, so we could hit this
corner case here. Let's simplify callers and make those functions "safe".
CID #1397035.
The compiler is mostly able to optimize this away:
$ size build{,-opt}/src/shared/libsystemd-shared-239.so
(before)
text data bss dec hex filename
2643329 580940 3112 3227381 313ef5 build/src/shared/libsystemd-shared-239.so (-O0 -g)
2170013 578588 3089 2751690 29fcca build-opt/src/shared/libsystemd-shared-239.so (-03 -flto -g)
(after)
text data bss dec hex filename
2644017 580940 3112 3228069 3141a5 build/src/shared/libsystemd-shared-239.so
2170765 578588 3057 2752410 29ff9a build-opt/src/shared/libsystemd-shared-239.so
-rw-r--r-- | src/basic/alloc-util.c | 2 | ||||
-rw-r--r-- | src/basic/alloc-util.h | 6 |
2 files changed, 4 insertions, 4 deletions
diff --git a/src/basic/alloc-util.c b/src/basic/alloc-util.c index 405445eac..ab7a42c4e 100644 --- a/src/basic/alloc-util.c +++ b/src/basic/alloc-util.c @@ -12,7 +12,7 @@ void* memdup(const void *p, size_t l) { assert(l == 0 || p); - ret = malloc(l); + ret = malloc(l ?: 1); if (!ret) return NULL; diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h index 7d237720b..ff7a46793 100644 --- a/src/basic/alloc-util.h +++ b/src/basic/alloc-util.h @@ -12,7 +12,7 @@ typedef void (*free_func_t)(void *p); #define new(t, n) ((t*) malloc_multiply(sizeof(t), (n))) -#define new0(t, n) ((t*) calloc((n), sizeof(t))) +#define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t))) #define newa(t, n) \ ({ \ @@ -77,7 +77,7 @@ _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t if (size_multiply_overflow(size, need)) return NULL; - return malloc(size * need); + return malloc(size * need ?: 1); } #if !HAVE_REALLOCARRAY @@ -85,7 +85,7 @@ _alloc_(2, 3) static inline void *reallocarray(void *p, size_t need, size_t size if (size_multiply_overflow(size, need)) return NULL; - return realloc(p, size * need); + return realloc(p, size * need ?: 1); } #endif |