mirror of
https://github.com/SELinuxProject/selinux
synced 2025-01-01 19:22:07 +00:00
libsepol: use reallocarray wrapper to avoid overflows
Use a wrapper to guard `realloc(p, a * b)` type allocations, to detect multiplication overflows, which result in too few memory being allocated. Use a custom implementation if the used C library does not offer one. Also use temporary variables for realloc(3) results in add_i_to_a() and fp_to_buffer(). Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
This commit is contained in:
parent
18303c85fb
commit
f0a5f6e330
@ -29,6 +29,12 @@ LOBJS += $(sort $(patsubst %.c,%.lo,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_
|
||||
override CFLAGS += -I$(CILDIR)/include
|
||||
endif
|
||||
|
||||
# check for reallocarray(3) availability
|
||||
H := \#
|
||||
ifeq (yes,$(shell printf '${H}define _GNU_SOURCE\n${H}include <stdlib.h>\nint main(void){void*p=reallocarray(NULL, 1, sizeof(char));return 0;}' | $(CC) -x c -o /dev/null - >/dev/null 2>&1 && echo yes))
|
||||
override CFLAGS += -DHAVE_REALLOCARRAY
|
||||
endif
|
||||
|
||||
LD_SONAME_FLAGS=-soname,$(LIBSO),--version-script=$(LIBMAP),-z,defs
|
||||
|
||||
LN=ln
|
||||
|
@ -161,7 +161,7 @@ int strs_add(struct strs *strs, char *s)
|
||||
char **new;
|
||||
unsigned i = strs->size;
|
||||
strs->size *= 2;
|
||||
new = realloc(strs->list, sizeof(char *)*strs->size);
|
||||
new = reallocarray(strs->list, strs->size, sizeof(char *));
|
||||
if (!new) {
|
||||
sepol_log_err("Out of memory");
|
||||
return -1;
|
||||
@ -220,7 +220,7 @@ int strs_add_at_index(struct strs *strs, char *s, unsigned index)
|
||||
while (index >= strs->size) {
|
||||
strs->size *= 2;
|
||||
}
|
||||
new = realloc(strs->list, sizeof(char *)*strs->size);
|
||||
new = reallocarray(strs->list, strs->size, sizeof(char *));
|
||||
if (!new) {
|
||||
sepol_log_err("Out of memory");
|
||||
return -1;
|
||||
|
@ -453,7 +453,7 @@ static int stack_push(struct stack *stack, void *ptr)
|
||||
void *new_stack;
|
||||
|
||||
if (stack->pos + 1 == stack->size) {
|
||||
new_stack = realloc(stack->stack, sizeof(*stack->stack) * (stack->size * 2));
|
||||
new_stack = reallocarray(stack->stack, stack->size * 2, sizeof(*stack->stack));
|
||||
if (new_stack == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
@ -4142,7 +4142,7 @@ exit:
|
||||
static int fp_to_buffer(FILE *fp, char **data, size_t *data_len)
|
||||
{
|
||||
int rc = -1;
|
||||
char *d = NULL;
|
||||
char *d = NULL, *d_tmp;
|
||||
size_t d_len = 0;
|
||||
size_t read_len = 0;
|
||||
size_t max_len = 1 << 17; // start at 128KB, this is enough to hold about half of all the existing pp files
|
||||
@ -4158,12 +4158,13 @@ static int fp_to_buffer(FILE *fp, char **data, size_t *data_len)
|
||||
d_len += read_len;
|
||||
if (d_len == max_len) {
|
||||
max_len *= 2;
|
||||
d = realloc(d, max_len);
|
||||
if (d == NULL) {
|
||||
d_tmp = realloc(d, max_len);
|
||||
if (d_tmp == NULL) {
|
||||
log_err("Out of memory");
|
||||
rc = -1;
|
||||
goto exit;
|
||||
}
|
||||
d = d_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,9 @@ static int type_vec_append(struct type_vec *v, uint32_t type)
|
||||
{
|
||||
if (v->capacity == v->count) {
|
||||
unsigned int new_capacity = v->capacity * 2;
|
||||
uint32_t *new_types = realloc(v->types,
|
||||
new_capacity * sizeof(*v->types));
|
||||
uint32_t *new_types = reallocarray(v->types,
|
||||
new_capacity,
|
||||
sizeof(*v->types));
|
||||
if (!new_types)
|
||||
return -1;
|
||||
|
||||
|
@ -92,3 +92,14 @@ static inline void* mallocarray(size_t nmemb, size_t size) {
|
||||
|
||||
return malloc(nmemb * size);
|
||||
}
|
||||
|
||||
#ifndef HAVE_REALLOCARRAY
|
||||
static inline void* reallocarray(void *ptr, size_t nmemb, size_t size) {
|
||||
if (size && nmemb > (size_t)-1 / size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return realloc(ptr, nmemb * size);
|
||||
}
|
||||
#endif
|
||||
|
@ -94,7 +94,7 @@ static void push(char *expr_ptr)
|
||||
else
|
||||
new_stack_len = stack_len * 2;
|
||||
|
||||
new_stack = realloc(stack, new_stack_len * sizeof(*stack));
|
||||
new_stack = reallocarray(stack, new_stack_len, sizeof(*stack));
|
||||
if (!new_stack) {
|
||||
ERR(NULL, "unable to allocate stack space");
|
||||
return;
|
||||
@ -449,8 +449,8 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,
|
||||
else
|
||||
new_expr_list_len = expr_list_len * 2;
|
||||
|
||||
new_expr_list = realloc(expr_list,
|
||||
new_expr_list_len * sizeof(*expr_list));
|
||||
new_expr_list = reallocarray(expr_list,
|
||||
new_expr_list_len, sizeof(*expr_list));
|
||||
if (!new_expr_list) {
|
||||
ERR(NULL, "failed to allocate expr buffer stack");
|
||||
rc = -ENOMEM;
|
||||
|
@ -183,8 +183,9 @@ int sepol_user_add_role(sepol_handle_t * handle,
|
||||
if (!role_cp)
|
||||
goto omem;
|
||||
|
||||
roles_realloc = realloc(user->roles,
|
||||
sizeof(char *) * (user->num_roles + 1));
|
||||
roles_realloc = reallocarray(user->roles,
|
||||
user->num_roles + 1,
|
||||
sizeof(char *));
|
||||
if (!roles_realloc)
|
||||
goto omem;
|
||||
|
||||
|
@ -226,17 +226,17 @@ int sepol_user_modify(sepol_handle_t * handle,
|
||||
void *tmp_ptr;
|
||||
|
||||
/* Ensure reverse lookup array has enough space */
|
||||
tmp_ptr = realloc(policydb->user_val_to_struct,
|
||||
(policydb->p_users.nprim +
|
||||
1) * sizeof(user_datum_t *));
|
||||
tmp_ptr = reallocarray(policydb->user_val_to_struct,
|
||||
policydb->p_users.nprim + 1,
|
||||
sizeof(user_datum_t *));
|
||||
if (!tmp_ptr)
|
||||
goto omem;
|
||||
policydb->user_val_to_struct = tmp_ptr;
|
||||
policydb->user_val_to_struct[policydb->p_users.nprim] = NULL;
|
||||
|
||||
tmp_ptr = realloc(policydb->sym_val_to_name[SYM_USERS],
|
||||
(policydb->p_users.nprim +
|
||||
1) * sizeof(char *));
|
||||
tmp_ptr = reallocarray(policydb->sym_val_to_name[SYM_USERS],
|
||||
policydb->p_users.nprim + 1,
|
||||
sizeof(char *));
|
||||
if (!tmp_ptr)
|
||||
goto omem;
|
||||
policydb->sym_val_to_name[SYM_USERS] = tmp_ptr;
|
||||
|
@ -40,6 +40,8 @@ struct val_to_name {
|
||||
* 0). Return 0 on success, -1 on out of memory. */
|
||||
int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a)
|
||||
{
|
||||
uint32_t *new;
|
||||
|
||||
if (cnt == NULL || a == NULL)
|
||||
return -1;
|
||||
|
||||
@ -48,17 +50,18 @@ int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a)
|
||||
* than be smart about it, for now we realloc() the array each
|
||||
* time a new uint32_t is added! */
|
||||
if (*a != NULL)
|
||||
*a = (uint32_t *) realloc(*a, (*cnt + 1) * sizeof(uint32_t));
|
||||
new = (uint32_t *) reallocarray(*a, *cnt + 1, sizeof(uint32_t));
|
||||
else { /* empty list */
|
||||
|
||||
*cnt = 0;
|
||||
*a = (uint32_t *) malloc(sizeof(uint32_t));
|
||||
new = (uint32_t *) malloc(sizeof(uint32_t));
|
||||
}
|
||||
if (*a == NULL) {
|
||||
if (new == NULL) {
|
||||
return -1;
|
||||
}
|
||||
(*a)[*cnt] = i;
|
||||
new[*cnt] = i;
|
||||
(*cnt)++;
|
||||
*a = new;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user