[PATCH 6/6 v7] libsepol: Add overflow checks
James Carter <[email protected]>
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <[email protected]> |
The function stack_push() uses the common idiom of "*= 2" to grow the size of the stack, but there is not check for overflow. Use the __builtin_smul_overflow() function to report an overflow and return an error. There are several calls of stack_push() that does not check for an error. Add checks for an error for these calls. Acked-by: Stephen Smalley <[email protected]> Signed-off-by: James Carter <[email protected]> --- v7: No changes libsepol/src/module_to_cil.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c index 00db3d7f..2aaf4feb 100644 --- a/libsepol/src/module_to_cil.c +++ b/libsepol/src/module_to_cil.c @@ -445,15 +445,21 @@ static int stack_push(struct stack *stack, void *ptr) { int rc = -1; void *new_stack; + int new_size; if (stack->pos + 1 == stack->size) { - new_stack = reallocarray(stack->stack, stack->size * 2, + if (__builtin_smul_overflow(stack->size, 2, &new_size)) { + ERR(NULL, "Overflow"); + goto exit; + } + new_stack = reallocarray(stack->stack, new_size, sizeof(*stack->stack)); if (new_stack == NULL) { + ERR(NULL, "Out of memory"); goto exit; } stack->stack = new_stack; - stack->size *= 2; + stack->size = new_size; } stack->pos++; @@ -1482,7 +1488,6 @@ static int cond_expr_to_cil(int indent, struct policydb *pdb, rc = stack_push(stack, new_val); if (rc != 0) { - ERR(NULL, "Out of memory"); goto exit; } new_val = NULL; @@ -2163,7 +2168,6 @@ static int constraint_expr_to_string(struct policydb *pdb, rc = stack_push(stack, new_val); if (rc != 0) { - ERR(NULL, "Out of memory"); goto exit; } @@ -4183,7 +4187,10 @@ static int module_block_to_cil(struct policydb *pdb, struct avrule_block *block, (*indent)++; } - stack_push(stack, decl); + rc = stack_push(stack, decl); + if (rc != 0) { + goto exit; + } rc = block_to_cil(pdb, block, stack, *indent); if (rc != 0) { @@ -4210,7 +4217,10 @@ static int global_block_to_cil(struct policydb *pdb, struct avrule_block *block, "Warning: 'else' not allowed in global block. Dropping from output."); } - stack_push(stack, decl); + rc = stack_push(stack, decl); + if (rc != 0) { + goto exit; + } // type aliases and commons are only stored in the global symtab. // However, to get scoping correct, we assume they are in the @@ -4284,7 +4294,10 @@ static int linked_block_to_cil(struct policydb *pdb, struct avrule_block *block, } } - stack_push(stack, decl); + rc = stack_push(stack, decl); + if (rc != 0) { + goto exit; + } rc = block_to_cil(pdb, block, stack, 0); if (rc != 0) { @@ -4595,7 +4608,11 @@ static int fp_to_buffer(FILE *fp, char **data, size_t *data_len) while ((read_len = fread(d + d_len, 1, max_len - d_len, fp)) > 0) { d_len += read_len; if (d_len == max_len) { - max_len *= 2; + if (__builtin_mul_overflow(max_len, 2, &max_len)) { + ERR(NULL, "Overflow"); + rc = -1; + goto exit; + } d_tmp = realloc(d, max_len); if (d_tmp == NULL) { ERR(NULL, "Out of memory"); -- 2.55.0