1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-24 21:34:08 +03:00

alloc-util: introduce new helper alloca_safe()

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.
This commit is contained in:
Lennart Poettering 2021-10-13 12:05:54 +02:00
parent a69f1dd9ca
commit 9e1a759903

View File

@ -22,20 +22,25 @@ typedef void (*free_func_t)(void *p);
#define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t))) #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) \ #define newa(t, n) \
({ \ ({ \
size_t _n_ = n; \ size_t _n_ = n; \
assert(!size_multiply_overflow(sizeof(t), _n_)); \ assert(!size_multiply_overflow(sizeof(t), _n_)); \
assert(sizeof(t)*_n_ <= ALLOCA_MAX); \ (t*) alloca_safe(sizeof(t)*_n_); \
(t*) alloca((sizeof(t)*_n_) ?: 1); \
}) })
#define newa0(t, n) \ #define newa0(t, n) \
({ \ ({ \
size_t _n_ = n; \ size_t _n_ = n; \
assert(!size_multiply_overflow(sizeof(t), _n_)); \ assert(!size_multiply_overflow(sizeof(t), _n_)); \
assert(sizeof(t)*_n_ <= ALLOCA_MAX); \ (t*) alloca0((sizeof(t)*_n_)); \
(t*) alloca0((sizeof(t)*_n_) ?: 1); \
}) })
#define newdup(t, p, n) ((t*) memdup_multiply(p, 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_; \ void *_q_; \
size_t _l_ = l; \ size_t _l_ = l; \
assert(_l_ <= ALLOCA_MAX); \ _q_ = alloca_safe(_l_); \
_q_ = alloca(_l_ ?: 1); \
memcpy_safe(_q_, p, _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_; \ void *_q_; \
size_t _l_ = l; \ size_t _l_ = l; \
assert(_l_ <= ALLOCA_MAX); \ _q_ = alloca_safe(_l_ + 1); \
_q_ = alloca(_l_ + 1); \
((uint8_t*) _q_)[_l_] = 0; \ ((uint8_t*) _q_)[_l_] = 0; \
memcpy_safe(_q_, p, _l_); \ memcpy_safe(_q_, p, _l_); \
}) })
@ -144,8 +147,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
({ \ ({ \
char *_new_; \ char *_new_; \
size_t _len_ = n; \ size_t _len_ = n; \
assert(_len_ <= ALLOCA_MAX); \ _new_ = alloca_safe(_len_); \
_new_ = alloca(_len_ ?: 1); \
(void *) memset(_new_, 0, _len_); \ (void *) memset(_new_, 0, _len_); \
}) })
@ -155,8 +157,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
void *_ptr_; \ void *_ptr_; \
size_t _mask_ = (align) - 1; \ size_t _mask_ = (align) - 1; \
size_t _size_ = size; \ size_t _size_ = size; \
assert(_size_ <= ALLOCA_MAX); \ _ptr_ = alloca_safe(_size_ + _mask_); \
_ptr_ = alloca((_size_ + _mask_) ?: 1); \
(void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \ (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
}) })