mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 09:21:26 +03:00
alloc-util: whenever any of our alloca() wrappers is used to allocate overly large memory blocks, hit an assert()
Of course, this should never happen, but let's better be safe than sorry, and abort rather than continue when a too large memory block is allocated, simply asa safety precaution. An early abort is better than continuing with a likely memory corruption later.
This commit is contained in:
parent
7c45deb20d
commit
4aee28c67b
@ -10,20 +10,28 @@
|
||||
|
||||
typedef void (*free_func_t)(void *p);
|
||||
|
||||
/* If for some reason more than 4M are allocated on the stack, let's abort immediately. It's better than
|
||||
* proceeding and smashing the stack limits. Note that by default RLIMIT_STACK is 8M on Linux. */
|
||||
#define ALLOCA_MAX (4U*1024U*1024U)
|
||||
|
||||
#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
|
||||
|
||||
#define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t)))
|
||||
|
||||
#define newa(t, n) \
|
||||
({ \
|
||||
assert(!size_multiply_overflow(sizeof(t), n)); \
|
||||
(t*) alloca(sizeof(t)*(n)); \
|
||||
#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_); \
|
||||
})
|
||||
|
||||
#define newa0(t, n) \
|
||||
({ \
|
||||
assert(!size_multiply_overflow(sizeof(t), n)); \
|
||||
(t*) alloca0(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_); \
|
||||
})
|
||||
|
||||
#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
|
||||
@ -51,16 +59,20 @@ void* memdup_suffix0(const void *p, size_t l) _alloc_(2);
|
||||
#define memdupa(p, l) \
|
||||
({ \
|
||||
void *_q_; \
|
||||
_q_ = alloca(l); \
|
||||
memcpy(_q_, p, l); \
|
||||
size_t _l_ = l; \
|
||||
assert(_l_ <= ALLOCA_MAX); \
|
||||
_q_ = alloca(_l_); \
|
||||
memcpy(_q_, p, _l_); \
|
||||
})
|
||||
|
||||
#define memdupa_suffix0(p, l) \
|
||||
({ \
|
||||
void *_q_; \
|
||||
_q_ = alloca(l + 1); \
|
||||
((uint8_t*) _q_)[l] = 0; \
|
||||
memcpy(_q_, p, l); \
|
||||
size_t _l_ = l; \
|
||||
assert(_l_ <= ALLOCA_MAX); \
|
||||
_q_ = alloca(_l_ + 1); \
|
||||
((uint8_t*) _q_)[_l_] = 0; \
|
||||
memcpy(_q_, p, _l_); \
|
||||
})
|
||||
|
||||
static inline void freep(void *p) {
|
||||
@ -116,6 +128,7 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
|
||||
({ \
|
||||
char *_new_; \
|
||||
size_t _len_ = n; \
|
||||
assert(_len_ <= ALLOCA_MAX); \
|
||||
_new_ = alloca(_len_); \
|
||||
(void *) memset(_new_, 0, _len_); \
|
||||
})
|
||||
@ -125,16 +138,18 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
|
||||
({ \
|
||||
void *_ptr_; \
|
||||
size_t _mask_ = (align) - 1; \
|
||||
_ptr_ = alloca((size) + _mask_); \
|
||||
size_t _size_ = size; \
|
||||
assert(_size_ <= ALLOCA_MAX); \
|
||||
_ptr_ = alloca(_size_ + _mask_); \
|
||||
(void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
|
||||
})
|
||||
|
||||
#define alloca0_align(size, align) \
|
||||
({ \
|
||||
void *_new_; \
|
||||
size_t _size_ = (size); \
|
||||
_new_ = alloca_align(_size_, (align)); \
|
||||
(void*)memset(_new_, 0, _size_); \
|
||||
size_t _xsize_ = (size); \
|
||||
_new_ = alloca_align(_xsize_, (align)); \
|
||||
(void*)memset(_new_, 0, _xsize_); \
|
||||
})
|
||||
|
||||
/* Takes inspiration from Rusts's Option::take() method: reads and returns a pointer, but at the same time resets it to
|
||||
|
Loading…
Reference in New Issue
Block a user