Skip to content

Commit dda614a

Browse files
committed
util: update allocation macros/functions
Let's copy in a new version from systemd
1 parent e009fbe commit dda614a

File tree

4 files changed

+53
-15
lines changed

4 files changed

+53
-15
lines changed

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ foreach ident : [
8888
['copy_file_range', '''#define _GNU_SOURCE
8989
#include <sys/syscall.h>
9090
#include <unistd.h>'''],
91+
['reallocarray', '''#include <malloc.h>'''],
9192
]
9293
have = cc.has_function(ident[0], args : '-D_GNU_SOURCE', prefix : ident[1])
9394
conf.set10('HAVE_' + ident[0].to_upper(), have)

src/casync.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ int ca_sync_add_store_path(CaSync *s, const char *path) {
10791079
return r;
10801080
}
10811081

1082-
array = realloc_multiply(s->rstores, sizeof(CaStore*), s->n_rstores+1);
1082+
array = reallocarray(s->rstores, sizeof(CaStore*), s->n_rstores+1);
10831083
if (!array) {
10841084
ca_store_unref(store);
10851085
return -ENOMEM;
@@ -1110,7 +1110,7 @@ int ca_sync_add_store_remote(CaSync *s, const char *url) {
11101110
return r;
11111111
}
11121112

1113-
array = realloc_multiply(s->remote_rstores, sizeof(CaRemote*), s->n_remote_rstores+1);
1113+
array = reallocarray(s->remote_rstores, sizeof(CaRemote*), s->n_remote_rstores+1);
11141114
if (!array) {
11151115
ca_remote_unref(remote);
11161116
return -ENOMEM;
@@ -1145,7 +1145,7 @@ static int ca_sync_extend_seeds_array(CaSync *s) {
11451145

11461146
assert(s);
11471147

1148-
new_seeds = realloc_multiply(s->seeds, sizeof(CaSeed*), s->n_seeds+1);
1148+
new_seeds = reallocarray(s->seeds, sizeof(CaSeed*), s->n_seeds+1);
11491149
if (!new_seeds)
11501150
return -ENOMEM;
11511151

src/util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ int strv_push(char ***l, char *value) {
919919
if (m < n)
920920
return -ENOMEM;
921921

922-
c = realloc_multiply(*l, sizeof(char*), m);
922+
c = reallocarray(*l, sizeof(char*), m);
923923
if (!c)
924924
return -ENOMEM;
925925

src/util.h

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,32 @@
2424
#include "gcc-macro.h"
2525
#include "log.h"
2626

27-
#define new(t, n) ((t*) malloc((n) * sizeof(t)))
28-
#define new0(t, n) ((t*) calloc((n), sizeof(t)))
27+
/* If for some reason more than 4M are allocated on the stack, let's abort immediately. It's better than
28+
* proceeding and smashing the stack limits. Note that by default RLIMIT_STACK is 8M on Linux. */
29+
#define ALLOCA_MAX (4U*1024U*1024U)
2930

30-
#define newa(t, n) ((t*) alloca((n) * sizeof(t)))
31+
#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
32+
#define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t)))
33+
34+
#define newa(t, n) \
35+
({ \
36+
size_t _n_ = n; \
37+
assert(!size_multiply_overflow(sizeof(t), _n_)); \
38+
assert(sizeof(t)*_n_ <= ALLOCA_MAX); \
39+
(t*) alloca(sizeof(t)*_n_); \
40+
})
41+
42+
#define newa0(t, n) \
43+
({ \
44+
size_t _n_ = n; \
45+
assert(!size_multiply_overflow(sizeof(t), _n_)); \
46+
assert(sizeof(t)*_n_ <= ALLOCA_MAX); \
47+
(t*) alloca0(sizeof(t)*_n_); \
48+
})
49+
50+
#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
51+
52+
#define malloc0(n) (calloc(1, (n)))
3153

3254
#define XCONCATENATE(x, y) x ## y
3355
#define CONCATENATE(x, y) XCONCATENATE(x, y)
@@ -63,8 +85,6 @@
6385
((_A) > (_B)) ? (_A) : (_B), \
6486
(void)0))
6587

66-
67-
6888
int loop_write(int fd, const void *p, size_t l);
6989
int loop_write_block(int fd, const void *p, size_t l);
7090
ssize_t loop_read(int fd, void *p, size_t l);
@@ -330,22 +350,39 @@ char *strv_find(char **l, const char *name) _pure_;
330350
#define strv_contains(l, s) (!!strv_find((l), (s)))
331351

332352
static inline bool size_multiply_overflow(size_t size, size_t need) {
333-
return need != 0 && size > (SIZE_MAX / need);
353+
return _unlikely_(need != 0 && size > (SIZE_MAX / need));
334354
}
335355

336356
_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) {
337-
if (_unlikely_(size_multiply_overflow(size, need)))
357+
if (size_multiply_overflow(size, need))
338358
return NULL;
339359

340-
return malloc(size * need);
360+
return malloc(size * need ?: 1);
341361
}
342362

343-
_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t size, size_t need) {
344-
if (_unlikely_(size_multiply_overflow(size, need)))
363+
#if !HAVE_REALLOCARRAY
364+
_alloc_(2, 3) static inline void *reallocarray(void *p, size_t need, size_t size) {
365+
if (size_multiply_overflow(size, need))
345366
return NULL;
346367

347-
return realloc(p, size * need);
368+
return realloc(p, size * need ?: 1);
348369
}
370+
#endif
371+
372+
_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) {
373+
if (size_multiply_overflow(size, need))
374+
return NULL;
375+
376+
return memdup(p, size * need);
377+
}
378+
379+
#define free_and_replace(a, b) \
380+
({ \
381+
free(a); \
382+
(a) = (b); \
383+
(b) = NULL; \
384+
0; \
385+
})
349386

350387
#define STRV_FOREACH(s, l) \
351388
for ((s) = (l); (s) && *(s); (s)++)

0 commit comments

Comments
 (0)