]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
alloc-util: introduce new helper alloca_safe()
authorLennart Poettering <lennart@poettering.net>
Wed, 13 Oct 2021 10:05:54 +0000 (12:05 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 14 Oct 2021 13:57:52 +0000 (15:57 +0200)
This is like alloca(), but does two things:

1. Verifies the allocation is smaller than ALLOCA_MAX
2. Ensures we allocate at least one byte

This was previously done manually in all invocations. This adds a handy
helper that does that implicitly.

src/basic/alloc-util.h

index e587fe79e7a90903fc4fa477b5ca04351d4b8912..ef25ff3a369c3464f1a58d28b34421db9a1a8326 100644 (file)
@@ -22,20 +22,25 @@ typedef void (*free_func_t)(void *p);
 
 #define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t)))
 
+#define alloca_safe(n)                                                  \
+        ({                                                              \
+                size_t _nn_ = n;                                        \
+                assert(_nn_ <= ALLOCA_MAX);                             \
+                alloca(_nn_ == 0 ? 1 : _nn_);                           \
+        })                                                              \
+
 #define newa(t, n)                                                      \
         ({                                                              \
                 size_t _n_ = n;                                         \
                 assert(!size_multiply_overflow(sizeof(t), _n_));        \
-                assert(sizeof(t)*_n_ <= ALLOCA_MAX);                    \
-                (t*) alloca((sizeof(t)*_n_) ?: 1);                      \
+                (t*) alloca_safe(sizeof(t)*_n_);                        \
         })
 
 #define newa0(t, n)                                                     \
         ({                                                              \
                 size_t _n_ = n;                                         \
                 assert(!size_multiply_overflow(sizeof(t), _n_));        \
-                assert(sizeof(t)*_n_ <= ALLOCA_MAX);                    \
-                (t*) alloca0((sizeof(t)*_n_) ?: 1);                     \
+                (t*) alloca0((sizeof(t)*_n_));                          \
         })
 
 #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
@@ -67,8 +72,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
         ({                                      \
                 void *_q_;                      \
                 size_t _l_ = l;                 \
-                assert(_l_ <= ALLOCA_MAX);      \
-                _q_ = alloca(_l_ ?: 1);         \
+                _q_ = alloca_safe(_l_);         \
                 memcpy_safe(_q_, p, _l_);       \
         })
 
@@ -76,8 +80,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
         ({                                      \
                 void *_q_;                      \
                 size_t _l_ = l;                 \
-                assert(_l_ <= ALLOCA_MAX);      \
-                _q_ = alloca(_l_ + 1);          \
+                _q_ = alloca_safe(_l_ + 1);     \
                 ((uint8_t*) _q_)[_l_] = 0;      \
                 memcpy_safe(_q_, p, _l_);       \
         })
@@ -144,8 +147,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
         ({                                              \
                 char *_new_;                            \
                 size_t _len_ = n;                       \
-                assert(_len_ <= ALLOCA_MAX);            \
-                _new_ = alloca(_len_ ?: 1);             \
+                _new_ = alloca_safe(_len_);             \
                 (void *) memset(_new_, 0, _len_);       \
         })
 
@@ -155,8 +157,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
                 void *_ptr_;                                            \
                 size_t _mask_ = (align) - 1;                            \
                 size_t _size_ = size;                                   \
-                assert(_size_ <= ALLOCA_MAX);                           \
-                _ptr_ = alloca((_size_ + _mask_) ?: 1);                 \
+                _ptr_ = alloca_safe(_size_ + _mask_);                   \
                 (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_);         \
         })