Skip to content

Commit 7ddf99a

Browse files
jwcart2stephensmalley
authored andcommitted
libsepol: Improve the validation of type aliases
A maliciously crafted binary policy could have a type alias that refers to an attribute or that ultimately refers back to itself in a loop. Validate that type aliases ultimately refer to a primary type and not to an attribute or themselves. Signed-off-by: James Carter <jwcart2@gmail.com> Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
1 parent 6e4b718 commit 7ddf99a

1 file changed

Lines changed: 46 additions & 25 deletions

File tree

libsepol/src/policydb_validate.c

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <sepol/policydb/services.h>
88

99
#include "debug.h"
10+
#include "private.h"
1011
#include "kernel_to_common.h"
1112
#include "policydb_validate.h"
1213

@@ -660,19 +661,23 @@ static int validate_type_datum(sepol_handle_t *handle, const type_datum_t *type,
660661
{
661662
if (validate_value(type->s.value, &flavors[SYM_TYPES]))
662663
goto bad;
663-
if (type->primary && validate_value(type->primary, &flavors[SYM_TYPES]))
664+
665+
switch (type->flags) {
666+
case 0:
667+
case TYPE_FLAGS_NEVERAUDIT:
668+
case TYPE_FLAGS_PERMISSIVE:
669+
case TYPE_FLAGS_NEVERAUDIT | TYPE_FLAGS_PERMISSIVE:
670+
case TYPE_FLAGS_EXPAND_ATTR_TRUE:
671+
case TYPE_FLAGS_EXPAND_ATTR_FALSE:
672+
case TYPE_FLAGS_EXPAND_ATTR:
673+
break;
674+
default:
664675
goto bad;
676+
}
665677

666-
switch (type->flavor) {
667-
case TYPE_TYPE:
668-
case TYPE_ALIAS:
669-
if (!ebitmap_is_empty(&type->types))
670-
goto bad;
671-
if (type->bounds &&
672-
validate_simpletype(type->bounds, p, flavors))
678+
if (type->flavor == TYPE_ATTRIB) {
679+
if (type->primary != 1)
673680
goto bad;
674-
break;
675-
case TYPE_ATTRIB:
676681
if (p->policy_type == POLICY_KERN) {
677682
if (!ebitmap_is_empty(&type->types))
678683
goto bad;
@@ -683,21 +688,37 @@ static int validate_type_datum(sepol_handle_t *handle, const type_datum_t *type,
683688
}
684689
if (type->bounds)
685690
goto bad;
686-
break;
687-
default:
688-
goto bad;
689-
}
690-
691-
switch (type->flags) {
692-
case 0:
693-
case TYPE_FLAGS_NEVERAUDIT:
694-
case TYPE_FLAGS_PERMISSIVE:
695-
case TYPE_FLAGS_NEVERAUDIT | TYPE_FLAGS_PERMISSIVE:
696-
case TYPE_FLAGS_EXPAND_ATTR_TRUE:
697-
case TYPE_FLAGS_EXPAND_ATTR_FALSE:
698-
case TYPE_FLAGS_EXPAND_ATTR:
699-
break;
700-
default:
691+
} else if ((type->flavor == TYPE_TYPE) ||
692+
(type->flavor == TYPE_ALIAS)) {
693+
if (!ebitmap_is_empty(&type->types))
694+
goto bad;
695+
if (type->bounds &&
696+
validate_simpletype(type->bounds, p, flavors))
697+
goto bad;
698+
if ((type->flavor == TYPE_TYPE) && type->primary) {
699+
if (type->primary > 1)
700+
goto bad;
701+
} else {
702+
const type_datum_t *t = type;
703+
uint32_t v;
704+
int repeats = 0;
705+
while ((t->flavor == TYPE_ALIAS) || (t->primary == 0)) {
706+
if (repeats >= MAX_ALIAS_REPEATS)
707+
break;
708+
v = (t->primary) ? t->primary : t->s.value;
709+
if (validate_value(v, &flavors[SYM_TYPES]))
710+
break;
711+
t = p->type_val_to_struct[v - 1];
712+
if (t == type)
713+
break;
714+
repeats++;
715+
}
716+
if ((t->flavor != TYPE_TYPE) || (t->primary != 1)) {
717+
ERR(handle, "Alias validation failed");
718+
goto bad;
719+
}
720+
}
721+
} else {
701722
goto bad;
702723
}
703724

0 commit comments

Comments
 (0)