SELinux Security Module development
 help / color / mirror / Atom feed
* [PATCH 1/3] libsepol: Fix out-of-bounds memory write in discard_tunbables()
@ 2026-04-14 19:11 James Carter
  2026-04-14 19:11 ` [PATCH 2/3] libsepol: When resolving names check if a block is abstract James Carter
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: James Carter @ 2026-04-14 19:11 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

The function discard_tunables() will walk all the avrule blocks
and do one of the following two options.
1) If preserve_tunables == 0, then it will evalutate tunable
expressions and add the appropriate true or false block to the
avrules list of the current enabled block.
2) If preserve_tunables !- 0, then it will remove the tunable flag
from all tunables making them booleans.

The function was allocating an array of pointers to cond_bool_datum_t
with a length of COND_EXPR_MAXDEPTH. The number of tunables was the
index and each tunable found would be pointed to be the array. This
is a potential buffer overflow because COND_EXPR_MAXDEPTH is the
limit on the depth of sub expressions, not the limit on the number
of items in an expression. Having more than COND_EXPR_MAXDEPTH
number of tunables in an expression that had a maximum sub
expression depth of less than COND_EXPR_MAXDEPTH would cause an
out-of-bounds memory write.

There is no need to wait to update a tunable datum's flag, so
just update the flags as tunables are found when preserve_tunables
is true.

This patch is based on a report and patch from the security firm
Trail of Bits.

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/src/expand.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index ed912b57..5b2b7b03 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -3042,22 +3042,21 @@ static void discard_tunables(sepol_handle_t *sh, policydb_t *pol)
 
 		for (cur_node = decl->cond_list; cur_node != NULL;
 		     cur_node = cur_node->next) {
-			int booleans, tunables, i;
+			int booleans = 0, tunables = 0;
 			cond_bool_datum_t *booldatum;
-			cond_bool_datum_t *tmp[COND_EXPR_MAXDEPTH];
-
-			booleans = tunables = 0;
-			memset(tmp, 0, sizeof(cond_bool_datum_t *) * COND_EXPR_MAXDEPTH);
 
 			for (cur_expr = cur_node->expr; cur_expr != NULL;
 			     cur_expr = cur_expr->next) {
 				if (cur_expr->expr_type != COND_BOOL)
 					continue;
 				booldatum = pol->bool_val_to_struct[cur_expr->boolean - 1];
-				if (booldatum->flags & COND_BOOL_FLAGS_TUNABLE)
-					tmp[tunables++] = booldatum;
-				else
+				if (booldatum->flags & COND_BOOL_FLAGS_TUNABLE) {
+					tunables++;
+					if (preserve_tunables)
+						booldatum->flags &= ~COND_BOOL_FLAGS_TUNABLE;
+				} else {
 					booleans++;
+				}
 			}
 
 			/* bool_copy_callback() at link phase has ensured
@@ -3069,10 +3068,6 @@ static void discard_tunables(sepol_handle_t *sh, policydb_t *pol)
 
 			if (booleans || preserve_tunables) {
 				cur_node->flags &= ~COND_NODE_FLAGS_TUNABLE;
-				if (tunables) {
-					for (i = 0; i < tunables; i++)
-						tmp[i]->flags &= ~COND_BOOL_FLAGS_TUNABLE;
-				}
 			} else {
 				cur_node->flags |= COND_NODE_FLAGS_TUNABLE;
 				cur_state = cond_evaluate_expr(pol, cur_node->expr);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-28 15:49 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-14 19:11 [PATCH 1/3] libsepol: Fix out-of-bounds memory write in discard_tunbables() James Carter
2026-04-14 19:11 ` [PATCH 2/3] libsepol: When resolving names check if a block is abstract James Carter
2026-04-27 18:17   ` Petr Lautrbach
2026-04-28 15:49     ` James Carter
2026-04-14 19:11 ` [PATCH 3/3] libsepol: Validate datum array entries for avrule blocks James Carter
2026-04-22 19:07 ` [PATCH 1/3] libsepol: Fix out-of-bounds memory write in discard_tunbables() James Carter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox