Skip to content

Commit 6e3ea71

Browse files
pks-tgitster
authored andcommitted
reftable/basics: stop using st_mult() in array allocators
We're using `st_mult()` as part of our macro helpers that allocate arrays. This is bad due two two reasons: - `st_mult()` causes us to die in case the multiplication overflows. - `st_mult()` ties us to the Git codebase. Refactor the code to instead detect overflows manually and return an error in such cases. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 445f9f4 commit 6e3ea71

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

reftable/basics.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,46 @@ void reftable_free(void *p);
117117
void *reftable_calloc(size_t nelem, size_t elsize);
118118
char *reftable_strdup(const char *str);
119119

120-
#define REFTABLE_ALLOC_ARRAY(x, alloc) (x) = reftable_malloc(st_mult(sizeof(*(x)), (alloc)))
120+
static inline int reftable_alloc_size(size_t nelem, size_t elsize, size_t *out)
121+
{
122+
if (nelem && elsize > SIZE_MAX / nelem)
123+
return -1;
124+
*out = nelem * elsize;
125+
return 0;
126+
}
127+
128+
#define REFTABLE_ALLOC_ARRAY(x, alloc) do { \
129+
size_t alloc_size; \
130+
if (reftable_alloc_size(sizeof(*(x)), (alloc), &alloc_size) < 0) { \
131+
errno = ENOMEM; \
132+
(x) = NULL; \
133+
} else { \
134+
(x) = reftable_malloc(alloc_size); \
135+
} \
136+
} while (0)
121137
#define REFTABLE_CALLOC_ARRAY(x, alloc) (x) = reftable_calloc((alloc), sizeof(*(x)))
122-
#define REFTABLE_REALLOC_ARRAY(x, alloc) (x) = reftable_realloc((x), st_mult(sizeof(*(x)), (alloc)))
138+
#define REFTABLE_REALLOC_ARRAY(x, alloc) do { \
139+
size_t alloc_size; \
140+
if (reftable_alloc_size(sizeof(*(x)), (alloc), &alloc_size) < 0) { \
141+
errno = ENOMEM; \
142+
(x) = NULL; \
143+
} else { \
144+
(x) = reftable_realloc((x), alloc_size); \
145+
} \
146+
} while (0)
123147

124148
static inline void *reftable_alloc_grow(void *p, size_t nelem, size_t elsize,
125149
size_t *allocp)
126150
{
127151
void *new_p;
128-
size_t alloc = *allocp * 2 + 1;
152+
size_t alloc = *allocp * 2 + 1, alloc_bytes;
129153
if (alloc < nelem)
130154
alloc = nelem;
131-
new_p = reftable_realloc(p, st_mult(elsize, alloc));
155+
if (reftable_alloc_size(elsize, alloc, &alloc_bytes) < 0) {
156+
errno = ENOMEM;
157+
return p;
158+
}
159+
new_p = reftable_realloc(p, alloc_bytes);
132160
if (!new_p)
133161
return p;
134162
*allocp = alloc;

0 commit comments

Comments
 (0)