X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fsystemd.git;a=blobdiff_plain;f=src%2Fbasic%2Falloc-util.h;h=38d1546b551fcca6d38d2037e12f8a22e098d296;hp=12b602e1855781b640d61c29b17ca71c9602500b;hb=53e1b683907c2f12330f00feb9630150196f064d;hpb=64529a2921a8972878b3f953935f286ce77914e0 diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h index 12b602e1855..38d1546b551 100644 --- a/src/basic/alloc-util.h +++ b/src/basic/alloc-util.h @@ -1,5 +1,4 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - +/* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once /*** @@ -22,6 +21,7 @@ ***/ #include +#include #include #include @@ -37,6 +37,8 @@ #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n))) +#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n))) + #define malloc0(n) (calloc(1, (n))) static inline void *mfree(void *memory) { @@ -44,7 +46,16 @@ static inline void *mfree(void *memory) { return NULL; } +#define free_and_replace(a, b) \ + ({ \ + free(a); \ + (a) = (b); \ + (b) = NULL; \ + 0; \ + }) + void* memdup(const void *p, size_t l) _alloc_(2); +void* memdup_suffix0(const void*p, size_t l) _alloc_(2); static inline void freep(void *p) { free(*(void**) p); @@ -52,25 +63,36 @@ static inline void freep(void *p) { #define _cleanup_free_ _cleanup_(freep) -_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) { - if (_unlikely_(b != 0 && a > ((size_t) -1) / b)) +static inline bool size_multiply_overflow(size_t size, size_t need) { + return _unlikely_(need != 0 && size > (SIZE_MAX / need)); +} + +_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) { + if (size_multiply_overflow(size, need)) + return NULL; + + return malloc(size * need); +} + +_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t size, size_t need) { + if (size_multiply_overflow(size, need)) return NULL; - return malloc(a * b); + return realloc(p, size * need); } -_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) { - if (_unlikely_(b != 0 && a > ((size_t) -1) / b)) +_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) { + if (size_multiply_overflow(size, need)) return NULL; - return realloc(p, a * b); + return memdup(p, size * need); } -_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) { - if (_unlikely_(b != 0 && a > ((size_t) -1) / b)) +_alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) { + if (size_multiply_overflow(size, need)) return NULL; - return memdup(p, a * b); + return memdup_suffix0(p, size * need); } void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);