]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/alloc-util.h
tree-wide: Introduce free_and_replace_full()
[thirdparty/systemd.git] / src / basic / alloc-util.h
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3
4 #include <alloca.h>
5 #include <stddef.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "macro.h"
10
11 #if HAS_FEATURE_MEMORY_SANITIZER
12 # include <sanitizer/msan_interface.h>
13 #endif
14
15 typedef void (*free_func_t)(void *p);
16 typedef void* (*mfree_func_t)(void *p);
17
18 /* If for some reason more than 4M are allocated on the stack, let's abort immediately. It's better than
19 * proceeding and smashing the stack limits. Note that by default RLIMIT_STACK is 8M on Linux. */
20 #define ALLOCA_MAX (4U*1024U*1024U)
21
22 #define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
23
24 #define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t)))
25
26 #define alloca_safe(n) \
27 ({ \
28 size_t _nn_ = n; \
29 assert(_nn_ <= ALLOCA_MAX); \
30 alloca(_nn_ == 0 ? 1 : _nn_); \
31 }) \
32
33 #define newa(t, n) \
34 ({ \
35 size_t _n_ = n; \
36 assert(!size_multiply_overflow(sizeof(t), _n_)); \
37 (t*) alloca_safe(sizeof(t)*_n_); \
38 })
39
40 #define newa0(t, n) \
41 ({ \
42 size_t _n_ = n; \
43 assert(!size_multiply_overflow(sizeof(t), _n_)); \
44 (t*) alloca0((sizeof(t)*_n_)); \
45 })
46
47 #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
48
49 #define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n)))
50
51 #define malloc0(n) (calloc(1, (n) ?: 1))
52
53 #define free_and_replace_full(a, b, free_func) \
54 ({ \
55 typeof(a)* _a = &(a); \
56 typeof(b)* _b = &(b); \
57 free_func(*_a); \
58 *_a = *_b; \
59 *_b = NULL; \
60 0; \
61 })
62
63 #define free_and_replace(a, b) \
64 free_and_replace_full(a, b, free)
65
66 void* memdup(const void *p, size_t l) _alloc_(2);
67 void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, since we return a buffer one byte larger than the specified size */
68
69 #define memdupa(p, l) \
70 ({ \
71 void *_q_; \
72 size_t _l_ = l; \
73 _q_ = alloca_safe(_l_); \
74 memcpy_safe(_q_, p, _l_); \
75 })
76
77 #define memdupa_suffix0(p, l) \
78 ({ \
79 void *_q_; \
80 size_t _l_ = l; \
81 _q_ = alloca_safe(_l_ + 1); \
82 ((uint8_t*) _q_)[_l_] = 0; \
83 memcpy_safe(_q_, p, _l_); \
84 })
85
86 static inline void unsetp(void *p) {
87 /* A trivial "destructor" that can be used in cases where we want to
88 * unset a pointer from a _cleanup_ function. */
89
90 *(void**)p = NULL;
91 }
92
93 static inline void freep(void *p) {
94 *(void**)p = mfree(*(void**) p);
95 }
96
97 #define _cleanup_free_ _cleanup_(freep)
98
99 static inline bool size_multiply_overflow(size_t size, size_t need) {
100 return _unlikely_(need != 0 && size > (SIZE_MAX / need));
101 }
102
103 _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) {
104 if (size_multiply_overflow(size, need))
105 return NULL;
106
107 return malloc(size * need ?: 1);
108 }
109
110 #if !HAVE_REALLOCARRAY
111 _alloc_(2, 3) static inline void *reallocarray(void *p, size_t need, size_t size) {
112 if (size_multiply_overflow(size, need))
113 return NULL;
114
115 return realloc(p, size * need ?: 1);
116 }
117 #endif
118
119 _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) {
120 if (size_multiply_overflow(size, need))
121 return NULL;
122
123 return memdup(p, size * need);
124 }
125
126 /* Note that we can't decorate this function with _alloc_() since the returned memory area is one byte larger
127 * than the product of its parameters. */
128 static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) {
129 if (size_multiply_overflow(size, need))
130 return NULL;
131
132 return memdup_suffix0(p, size * need);
133 }
134
135 void* greedy_realloc(void **p, size_t need, size_t size);
136 void* greedy_realloc0(void **p, size_t need, size_t size);
137
138 #define GREEDY_REALLOC(array, need) \
139 greedy_realloc((void**) &(array), (need), sizeof((array)[0]))
140
141 #define GREEDY_REALLOC0(array, need) \
142 greedy_realloc0((void**) &(array), (need), sizeof((array)[0]))
143
144 #define alloca0(n) \
145 ({ \
146 char *_new_; \
147 size_t _len_ = n; \
148 _new_ = alloca_safe(_len_); \
149 memset(_new_, 0, _len_); \
150 })
151
152 /* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */
153 #define alloca_align(size, align) \
154 ({ \
155 void *_ptr_; \
156 size_t _mask_ = (align) - 1; \
157 size_t _size_ = size; \
158 _ptr_ = alloca_safe(_size_ + _mask_); \
159 (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
160 })
161
162 #define alloca0_align(size, align) \
163 ({ \
164 void *_new_; \
165 size_t _xsize_ = (size); \
166 _new_ = alloca_align(_xsize_, (align)); \
167 memset(_new_, 0, _xsize_); \
168 })
169
170 #if HAS_FEATURE_MEMORY_SANITIZER
171 # define msan_unpoison(r, s) __msan_unpoison(r, s)
172 #else
173 # define msan_unpoison(r, s)
174 #endif
175
176 /* This returns the number of usable bytes in a malloc()ed region as per malloc_usable_size(), in a way that
177 * is compatible with _FORTIFY_SOURCES. If _FORTIFY_SOURCES is used many memory operations will take the
178 * object size as returned by __builtin_object_size() into account. Hence, let's return the smaller size of
179 * malloc_usable_size() and __builtin_object_size() here, so that we definitely operate in safe territory by
180 * both the compiler's and libc's standards. Note that __builtin_object_size() evaluates to SIZE_MAX if the
181 * size cannot be determined, hence the MIN() expression should be safe with dynamically sized memory,
182 * too. Moreover, when NULL is passed malloc_usable_size() is documented to return zero, and
183 * __builtin_object_size() returns SIZE_MAX too, hence we also return a sensible value of 0 in this corner
184 * case. */
185 #define MALLOC_SIZEOF_SAFE(x) \
186 MIN(malloc_usable_size(x), __builtin_object_size(x, 0))
187
188 /* Inspired by ELEMENTSOF() but operates on malloc()'ed memory areas: typesafely returns the number of items
189 * that fit into the specified memory block */
190 #define MALLOC_ELEMENTSOF(x) \
191 (__builtin_choose_expr( \
192 __builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
193 MALLOC_SIZEOF_SAFE(x)/sizeof((x)[0]), \
194 VOID_0))
195
196
197 /* These are like strdupa()/strndupa(), but honour ALLOCA_MAX */
198 #define strdupa_safe(s) \
199 ({ \
200 const char *_t = (s); \
201 (char*) memdupa_suffix0(_t, strlen(_t)); \
202 })
203
204 #define strndupa_safe(s, n) \
205 ({ \
206 const char *_t = (s); \
207 (char*) memdupa_suffix0(_t, strnlen(_t, (n))); \
208 })
209
210 #include "memory-util.h"