backport patches from upstream

(cherry picked from commit c2ba662a7864600cc027fdb3d39f616df22d7a44)
This commit is contained in:
wjiang 2025-03-14 14:45:17 +08:00 committed by openeuler-sync-bot
parent 766a853c25
commit b993887e8d
18 changed files with 1529 additions and 1 deletions

View File

@ -0,0 +1,36 @@
From 84a33fb96b4876a49bfb739b9a2160d88e015209 Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Mon, 8 Jul 2024 12:50:32 -0400
Subject: [PATCH] checkpolicy: Check the right bits of an ibpkeycon rule subnet
prefix
The lower 64 bits of the subnet prefix for an ibpkeycon rule should
all be 0's. Unfortunately the check uses the s6_addr macro which refers
to the 16 entry array of 8-bit values in the union and does not refer
to the correct bits.
Use the s6_addr32 macro instead which refers to the 4 entry array of
32-bit values in the union and refers to the lower 64 bits.
Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
policy_define.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/policy_define.c b/policy_define.c
index 4931f23d..bfeda86b 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -5148,7 +5148,7 @@ int define_ibpkey_context(unsigned int low, unsigned int high)
goto out;
}
- if (subnet_prefix.s6_addr[2] || subnet_prefix.s6_addr[3]) {
+ if (subnet_prefix.s6_addr32[2] || subnet_prefix.s6_addr32[3]) {
yyerror("subnet prefix should be 0's in the low order 64 bits.");
rc = -1;
goto out;
--
2.33.0

View File

@ -0,0 +1,173 @@
From 6f2b689f63ec7c3fe51ee420d0046a870bd5f496 Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Wed, 28 Aug 2024 10:29:44 -0400
Subject: [PATCH] checkpolicy: Fix MLS users in optional blocks
When a user is created in an optional block, a user datum is added
to both the avrule_decl's symtab and the policydb's symtab, but
the semantic MLS information is only added to the avrule_decl's
user datum. This causes an error to occur during policy expansion
when user_copy_callback() is called. If this error did not occur
then the policydb's user datum would be written without any MLS
info and the policy would fail validation when read later.
When creating a user datum, search for a user datum with the same
key in the policydb's symtab. If that datum has no MLS information,
then copy the MLS information from the avrule_decl's datum. If it
does, then compare the default level, low level, and high level
sensitivities and give an error if they do not match. There is not
enough information to expand the categories for the high and low
levels, so merge the semantic categories. If the two category sets
are not equal an error will occur during the expansion phase.
A minimum policy to demonstrate the bug:
class CLASS1
sid kernel
class CLASS1 { PERM1 }
sensitivity SENS1;
dominance { SENS1 }
level SENS1;
mlsconstrain CLASS1 { PERM1 } ((h1 dom h2) and (l1 domby h1));
type TYPE1;
allow TYPE1 self : CLASS1 PERM1;
role ROLE1;
role ROLE1 types TYPE1;
optional {
require {
role ROLE1;
}
user USER2 roles ROLE1 level SENS1 range SENS1;
}
user USER1 roles ROLE1 level SENS1 range SENS1;
sid kernel USER1:ROLE1:TYPE1:SENS1
Signed-off-by: James Carter <jwcart2@gmail.com>
---
policy_define.c | 72 ++++++++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/policy_define.c b/policy_define.c
index f8a10154..af30da90 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -4287,6 +4287,50 @@ static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats
return 0;
}
+static int mls_semantic_cats_merge(mls_semantic_cat_t ** dst,
+ const mls_semantic_cat_t * src)
+{
+ mls_semantic_cat_t *new;
+
+ while (src) {
+ new = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
+ if (!new)
+ return -1;
+
+ mls_semantic_cat_init(new);
+ new->low = src->low;
+ new->high = src->high;
+ new->next = *dst;
+ *dst = new;
+
+ src = src->next;
+ }
+
+ return 0;
+}
+
+static int mls_add_or_check_level(mls_semantic_level_t *dst, const mls_semantic_level_t *src)
+{
+ if (!dst->sens) {
+ if (mls_semantic_level_cpy(dst, src) < 0) {
+ yyerror("out of memory");
+ return -1;
+ }
+ } else {
+ if (dst->sens != src->sens) {
+ return -1;
+ }
+ /* Duplicate cats won't cause problems, but different cats will
+ * result in an error during expansion */
+ if (mls_semantic_cats_merge(&dst->cat, src->cat) < 0) {
+ yyerror("out of memory");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static int parse_semantic_categories(char *id, level_datum_t * levdatum __attribute__ ((unused)),
mls_semantic_cat_t ** cats)
{
@@ -4345,7 +4389,7 @@ static int parse_semantic_categories(char *id, level_datum_t * levdatum __attrib
int define_user(void)
{
char *id;
- user_datum_t *usrdatum;
+ user_datum_t *usrdatum, *usr_global;
level_datum_t *levdatum;
int l;
@@ -4370,10 +4414,16 @@ int define_user(void)
return 0;
}
+ id = strdup(queue_head(id_queue));
+
if ((usrdatum = declare_user()) == NULL) {
+ free(id);
return -1;
}
+ usr_global = hashtab_search(policydbp->p_users.table, (hashtab_key_t) id);
+ free(id);
+
while ((id = queue_remove(id_queue))) {
if (set_user_roles(&usrdatum->roles, id))
continue;
@@ -4400,6 +4450,7 @@ int define_user(void)
usrdatum->dfltlevel.sens = levdatum->level->sens;
while ((id = queue_remove(id_queue))) {
+ /* This will add to any already existing categories */
if (parse_semantic_categories(id, levdatum,
&usrdatum->dfltlevel.cat)) {
free(id);
@@ -4425,6 +4476,7 @@ int define_user(void)
usrdatum->range.level[l].sens = levdatum->level->sens;
while ((id = queue_remove(id_queue))) {
+ /* This will add to any already existing categories */
if (parse_semantic_categories(id, levdatum,
&usrdatum->range.level[l].cat)) {
free(id);
@@ -4445,6 +4497,24 @@ int define_user(void)
return -1;
}
}
+
+ if (usr_global && usr_global != usrdatum) {
+ if (mls_add_or_check_level(&usr_global->dfltlevel,
+ &usrdatum->dfltlevel)) {
+ yyerror("Problem with user default level");
+ return -1;
+ }
+ if (mls_add_or_check_level(&usr_global->range.level[0],
+ &usrdatum->range.level[0])) {
+ yyerror("Problem with user low level");
+ return -1;
+ }
+ if (mls_add_or_check_level(&usr_global->range.level[1],
+ &usrdatum->range.level[1])) {
+ yyerror("Problem with user high level");
+ return -1;
+ }
+ }
}
return 0;
}
--
2.33.0

View File

@ -0,0 +1,45 @@
From 77747a36a9afd4b9e27af608301487b44d681b4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Wed, 6 Nov 2024 11:49:06 +0100
Subject: [PATCH] checkpolicy: avoid leak of identifier on required attribute
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Example policy generated by fuzzer:
class s
sid k
class s { i }
optional{
require{
attribute i;
}
}
type m;
typealias m alias i;
typeai
Reported-by: oss-fuzz (issue 377576480)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_define.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/policy_define.c b/policy_define.c
index dc404530..9ae8c4d4 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -1287,6 +1287,7 @@ static int add_aliases_to_type(type_datum_t * type)
aliasdatum->primary = type->s.value;
aliasdatum->flavor = TYPE_ALIAS;
+ free(id);
break;
}
default:{
--
2.33.0

View File

@ -0,0 +1,229 @@
From beca1ee16b291e1556bc905498cc814898edc07d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 5 Nov 2024 22:06:18 +0100
Subject: [PATCH] checkpolicy: avoid memory leaks on redeclarations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If declare_symbol() returns 1 the id and the datum are already defined
and not consumed by the function, so it they must be free'd by the
caller.
Example policy (generated by fuzzer):
class s sid e class s{i}optional{require{bool K;}bool K true;
Reported-by: oss-fuzz (issue 377544445)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
module_compiler.c | 2 +-
module_compiler.h | 2 +-
policy_define.c | 72 +++++++++++++++++++++++------------
3 files changed, 49 insertions(+), 27 deletions(-)
diff --git a/module_compiler.c b/module_compiler.c
index 4efd77bf..3a7ad1bb 100644
--- a/module_compiler.c
+++ b/module_compiler.c
@@ -196,7 +196,7 @@ static int create_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_
* not be restricted pointers. */
int declare_symbol(uint32_t symbol_type,
hashtab_key_t key, hashtab_datum_t datum,
- uint32_t * dest_value, uint32_t * datum_value)
+ uint32_t * dest_value, const uint32_t * datum_value)
{
avrule_decl_t *decl = stack_top->decl;
int ret = create_symbol(symbol_type, key, datum, dest_value, SCOPE_DECL);
diff --git a/module_compiler.h b/module_compiler.h
index e43bc6c0..2fe3455d 100644
--- a/module_compiler.h
+++ b/module_compiler.h
@@ -28,7 +28,7 @@ int define_policy(int pass, int module_header_given);
*/
int declare_symbol(uint32_t symbol_type,
hashtab_key_t key, hashtab_datum_t datum,
- uint32_t * dest_value, uint32_t * datum_value);
+ uint32_t * dest_value, const uint32_t * datum_value);
role_datum_t *declare_role(unsigned char isattr);
type_datum_t *declare_type(unsigned char primary, unsigned char isattr);
diff --git a/policy_define.c b/policy_define.c
index af30da90..dc404530 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -147,9 +147,9 @@ static int id_has_dot(const char *id)
int define_class(void)
{
- char *id = 0;
- class_datum_t *datum = 0;
- int ret;
+ char *id = NULL;
+ class_datum_t *datum = NULL;
+ int ret = -1;
uint32_t value;
if (pass == 2) {
@@ -166,27 +166,29 @@ int define_class(void)
datum = (class_datum_t *) malloc(sizeof(class_datum_t));
if (!datum) {
yyerror("out of memory");
- goto bad;
+ goto cleanup;
}
memset(datum, 0, sizeof(class_datum_t));
ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
switch (ret) {
case -3:{
yyerror("Out of memory!");
- goto bad;
+ goto cleanup;
}
case -2:{
yyerror2("duplicate declaration of class %s", id);
- goto bad;
+ goto cleanup;
}
case -1:{
yyerror("could not declare class here");
- goto bad;
+ goto cleanup;
}
- case 0:
- case 1:{
+ case 0: {
break;
}
+ case 1:{
+ goto cleanup;
+ }
default:{
assert(0); /* should never get here */
}
@@ -194,12 +196,10 @@ int define_class(void)
datum->s.value = value;
return 0;
- bad:
- if (id)
- free(id);
- if (datum)
- free(datum);
- return -1;
+ cleanup:
+ free(id);
+ free(datum);
+ return ret == 1 ? 0 : -1;
}
int define_permissive(void)
@@ -772,8 +772,13 @@ int define_sens(void)
yyerror("could not declare sensitivity level here");
goto bad;
}
- case 0:
+ case 0: {
+ break;
+ }
case 1:{
+ level_datum_destroy(datum);
+ free(datum);
+ free(id);
break;
}
default:{
@@ -813,8 +818,13 @@ int define_sens(void)
("could not declare sensitivity alias here");
goto bad_alias;
}
- case 0:
+ case 0: {
+ break;
+ }
case 1:{
+ level_datum_destroy(aliasdatum);
+ free(aliasdatum);
+ free(id);
break;
}
default:{
@@ -943,15 +953,20 @@ int define_category(void)
yyerror("could not declare category here");
goto bad;
}
- case 0:
+ case 0:{
+ datum->s.value = value;
+ break;
+ }
case 1:{
+ cat_datum_destroy(datum);
+ free(datum);
+ free(id);
break;
}
default:{
assert(0); /* should never get here */
}
}
- datum->s.value = value;
while ((id = queue_remove(id_queue))) {
if (id_has_dot(id)) {
@@ -967,11 +982,11 @@ int define_category(void)
}
cat_datum_init(aliasdatum);
aliasdatum->isalias = TRUE;
- aliasdatum->s.value = datum->s.value;
+ aliasdatum->s.value = value;
ret =
declare_symbol(SYM_CATS, id, aliasdatum, NULL,
- &datum->s.value);
+ &value);
switch (ret) {
case -3:{
yyerror("Out of memory!");
@@ -987,8 +1002,13 @@ int define_category(void)
("could not declare category aliases here");
goto bad_alias;
}
- case 0:
+ case 0:{
+ break;
+ }
case 1:{
+ cat_datum_destroy(aliasdatum);
+ free(aliasdatum);
+ free(id);
break;
}
default:{
@@ -1819,10 +1839,12 @@ int define_bool_tunable(int is_tunable)
yyerror("could not declare boolean here");
goto cleanup;
}
- case 0:
- case 1:{
+ case 0:{
break;
}
+ case 1:{
+ goto cleanup;
+ }
default:{
assert(0); /* should never get here */
}
@@ -1840,7 +1862,7 @@ int define_bool_tunable(int is_tunable)
return 0;
cleanup:
cond_destroy_bool(id, datum, NULL);
- return -1;
+ return ret == 1 ? 0 : -1;
}
avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
--
2.33.0

View File

@ -0,0 +1,63 @@
From 770ad3ecac91f59c3e3296ac63a7001630f98d86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 22 Jan 2024 14:54:57 +0100
Subject: [PATCH] checkpolicy: check allocation and free memory on error at
type definition
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_define.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/policy_define.c b/policy_define.c
index 053156df..ec19da9d 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -1399,7 +1399,7 @@ int define_typeattribute(void)
return 0;
}
-static int define_typebounds_helper(char *bounds_id, char *type_id)
+static int define_typebounds_helper(const char *bounds_id, const char *type_id)
{
type_datum_t *bounds, *type;
@@ -1482,15 +1482,26 @@ int define_type(int alias)
* old name based hierarchy.
*/
if ((id = queue_remove(id_queue))) {
- char *bounds, *delim;
+ const char *delim;
+
+ if ((delim = strrchr(id, '.'))) {
+ int ret;
+ char *bounds = strdup(id);
+ if (!bounds) {
+ yyerror("out of memory");
+ free(id);
+ return -1;
+ }
- if ((delim = strrchr(id, '.'))
- && (bounds = strdup(id))) {
bounds[(size_t)(delim - id)] = '\0';
- if (define_typebounds_helper(bounds, id))
- return -1;
+ ret = define_typebounds_helper(bounds, id);
free(bounds);
+ if (ret) {
+ free(id);
+ return -1;
+ }
+
}
free(id);
}
--
2.33.0

View File

@ -0,0 +1,55 @@
From 158fb95ef28af13ccc8a6f1474aaa2e69620afd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Wed, 15 Jan 2025 14:13:25 +0100
Subject: [PATCH] checkpolicy: check identifier before copying
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Avoid calling strdup(3) with a NULL pointer, which can happen with an
invalid policy context, e.g.:
class C
sid S
class C { P }
;
user U roles j;
sid S s:l:q:q:q
Fixes: 6f2b689f ("checkpolicy: Fix MLS users in optional blocks")
Reported-by: oss-fuzz (issue 390004173)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
policy_define.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/policy_define.c b/policy_define.c
index 2f811b67..96a481f7 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -4411,6 +4411,7 @@ static int parse_semantic_categories(char *id, level_datum_t * levdatum __attrib
int define_user(void)
{
+ const char *username;
char *id;
user_datum_t *usrdatum, *usr_global;
level_datum_t *levdatum;
@@ -4437,7 +4438,13 @@ int define_user(void)
return 0;
}
- id = strdup(queue_head(id_queue));
+ username = queue_head(id_queue);
+ if (!username) {
+ yyerror("no user name");
+ return -1;
+ }
+
+ id = strdup(username);
if ((usrdatum = declare_user()) == NULL) {
free(id);
--
2.33.0

View File

@ -0,0 +1,237 @@
From 187e75849e045636f02ff3a91ae5a67fa6855b92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 22 Jan 2024 14:54:58 +0100
Subject: [PATCH] checkpolicy: clean expression on error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The passed expression needs to be transferred into the policy or free'd
by the sink functions define_constraint() and define_validatetrans().
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_define.c | 68 ++++++++++++++++++++++---------------
1 file changed, 40 insertions(+), 28 deletions(-)
diff --git a/policy_define.c b/policy_define.c
index ec19da9d..97582630 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -3569,20 +3569,22 @@ int define_constraint(constraint_expr_t * expr)
return 0;
}
+ ebitmap_init(&classmap);
+
depth = -1;
for (e = expr; e; e = e->next) {
switch (e->expr_type) {
case CEXPR_NOT:
if (depth < 0) {
yyerror("illegal constraint expression");
- return -1;
+ goto bad;
}
break;
case CEXPR_AND:
case CEXPR_OR:
if (depth < 1) {
yyerror("illegal constraint expression");
- return -1;
+ goto bad;
}
depth--;
break;
@@ -3590,51 +3592,48 @@ int define_constraint(constraint_expr_t * expr)
case CEXPR_NAMES:
if (e->attr & CEXPR_XTARGET) {
yyerror("illegal constraint expression");
- return -1; /* only for validatetrans rules */
+ goto bad; /* only for validatetrans rules */
}
if (depth == (CEXPR_MAXDEPTH - 1)) {
yyerror("constraint expression is too deep");
- return -1;
+ goto bad;
}
depth++;
break;
default:
yyerror("illegal constraint expression");
- return -1;
+ goto bad;
}
}
if (depth != 0) {
yyerror("illegal constraint expression");
- return -1;
+ goto bad;
}
- ebitmap_init(&classmap);
while ((id = queue_remove(id_queue))) {
if (!is_id_in_scope(SYM_CLASSES, id)) {
yyerror2("class %s is not within scope", id);
free(id);
- return -1;
+ goto bad;
}
cladatum =
(class_datum_t *) hashtab_search(policydbp->p_classes.table,
(hashtab_key_t) id);
if (!cladatum) {
yyerror2("class %s is not defined", id);
- ebitmap_destroy(&classmap);
free(id);
- return -1;
+ goto bad;
}
if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
yyerror("out of memory");
- ebitmap_destroy(&classmap);
free(id);
- return -1;
+ goto bad;
}
node = malloc(sizeof(struct constraint_node));
if (!node) {
yyerror("out of memory");
free(node);
- return -1;
+ goto bad;
}
memset(node, 0, sizeof(constraint_node_t));
if (useexpr) {
@@ -3646,7 +3645,7 @@ int define_constraint(constraint_expr_t * expr)
if (!node->expr) {
yyerror("out of memory");
free(node);
- return -1;
+ goto bad;
}
node->permissions = 0;
@@ -3698,8 +3697,7 @@ int define_constraint(constraint_expr_t * expr)
yyerror2("permission %s is not"
" defined for class %s", id, policydbp->p_class_val_to_name[i]);
free(id);
- ebitmap_destroy(&classmap);
- return -1;
+ goto bad;
}
}
node->permissions |= (UINT32_C(1) << (perdatum->s.value - 1));
@@ -3710,6 +3708,13 @@ int define_constraint(constraint_expr_t * expr)
ebitmap_destroy(&classmap);
return 0;
+
+bad:
+ ebitmap_destroy(&classmap);
+ if (useexpr)
+ constraint_expr_destroy(expr);
+
+ return -1;
}
int define_validatetrans(constraint_expr_t * expr)
@@ -3728,20 +3733,22 @@ int define_validatetrans(constraint_expr_t * expr)
return 0;
}
+ ebitmap_init(&classmap);
+
depth = -1;
for (e = expr; e; e = e->next) {
switch (e->expr_type) {
case CEXPR_NOT:
if (depth < 0) {
yyerror("illegal validatetrans expression");
- return -1;
+ goto bad;
}
break;
case CEXPR_AND:
case CEXPR_OR:
if (depth < 1) {
yyerror("illegal validatetrans expression");
- return -1;
+ goto bad;
}
depth--;
break;
@@ -3749,47 +3756,45 @@ int define_validatetrans(constraint_expr_t * expr)
case CEXPR_NAMES:
if (depth == (CEXPR_MAXDEPTH - 1)) {
yyerror("validatetrans expression is too deep");
- return -1;
+ goto bad;
}
depth++;
break;
default:
yyerror("illegal validatetrans expression");
- return -1;
+ goto bad;
}
}
if (depth != 0) {
yyerror("illegal validatetrans expression");
- return -1;
+ goto bad;
}
- ebitmap_init(&classmap);
while ((id = queue_remove(id_queue))) {
if (!is_id_in_scope(SYM_CLASSES, id)) {
yyerror2("class %s is not within scope", id);
free(id);
- return -1;
+ goto bad;
}
cladatum =
(class_datum_t *) hashtab_search(policydbp->p_classes.table,
(hashtab_key_t) id);
if (!cladatum) {
yyerror2("class %s is not defined", id);
- ebitmap_destroy(&classmap);
free(id);
- return -1;
+ goto bad;
}
if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
yyerror("out of memory");
- ebitmap_destroy(&classmap);
free(id);
- return -1;
+ goto bad;
}
node = malloc(sizeof(struct constraint_node));
if (!node) {
yyerror("out of memory");
- return -1;
+ free(id);
+ goto bad;
}
memset(node, 0, sizeof(constraint_node_t));
if (useexpr) {
@@ -3809,6 +3814,13 @@ int define_validatetrans(constraint_expr_t * expr)
ebitmap_destroy(&classmap);
return 0;
+
+bad:
+ ebitmap_destroy(&classmap);
+ if (useexpr)
+ constraint_expr_destroy(expr);
+
+ return -1;
}
uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
--
2.33.0

View File

@ -0,0 +1,196 @@
From b75bf48b42d93bf03211eeb176495dbc667d4e99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 22 Jan 2024 14:54:55 +0100
Subject: [PATCH] checkpolicy: cleanup identifiers on error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Free identifiers removed from the queue but not yet owned by the policy
on errors.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_define.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/policy_define.c b/policy_define.c
index 260e609d..db7e9d0e 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -342,6 +342,7 @@ static int read_classes(ebitmap_t *e_classes)
while ((id = queue_remove(id_queue))) {
if (!is_id_in_scope(SYM_CLASSES, id)) {
yyerror2("class %s is not within scope", id);
+ free(id);
return -1;
}
cladatum = hashtab_search(policydbp->p_classes.table, id);
@@ -373,15 +374,18 @@ int define_default_user(int which)
while ((id = queue_remove(id_queue))) {
if (!is_id_in_scope(SYM_CLASSES, id)) {
yyerror2("class %s is not within scope", id);
+ free(id);
return -1;
}
cladatum = hashtab_search(policydbp->p_classes.table, id);
if (!cladatum) {
yyerror2("unknown class %s", id);
+ free(id);
return -1;
}
if (cladatum->default_user && cladatum->default_user != which) {
yyerror2("conflicting default user information for class %s", id);
+ free(id);
return -1;
}
cladatum->default_user = which;
@@ -405,15 +409,18 @@ int define_default_role(int which)
while ((id = queue_remove(id_queue))) {
if (!is_id_in_scope(SYM_CLASSES, id)) {
yyerror2("class %s is not within scope", id);
+ free(id);
return -1;
}
cladatum = hashtab_search(policydbp->p_classes.table, id);
if (!cladatum) {
yyerror2("unknown class %s", id);
+ free(id);
return -1;
}
if (cladatum->default_role && cladatum->default_role != which) {
yyerror2("conflicting default role information for class %s", id);
+ free(id);
return -1;
}
cladatum->default_role = which;
@@ -437,15 +444,18 @@ int define_default_type(int which)
while ((id = queue_remove(id_queue))) {
if (!is_id_in_scope(SYM_CLASSES, id)) {
yyerror2("class %s is not within scope", id);
+ free(id);
return -1;
}
cladatum = hashtab_search(policydbp->p_classes.table, id);
if (!cladatum) {
yyerror2("unknown class %s", id);
+ free(id);
return -1;
}
if (cladatum->default_type && cladatum->default_type != which) {
yyerror2("conflicting default type information for class %s", id);
+ free(id);
return -1;
}
cladatum->default_type = which;
@@ -469,15 +479,18 @@ int define_default_range(int which)
while ((id = queue_remove(id_queue))) {
if (!is_id_in_scope(SYM_CLASSES, id)) {
yyerror2("class %s is not within scope", id);
+ free(id);
return -1;
}
cladatum = hashtab_search(policydbp->p_classes.table, id);
if (!cladatum) {
yyerror2("unknown class %s", id);
+ free(id);
return -1;
}
if (cladatum->default_range && cladatum->default_range != which) {
yyerror2("conflicting default range information for class %s", id);
+ free(id);
return -1;
}
cladatum->default_range = which;
@@ -508,6 +521,7 @@ int define_common_perms(void)
comdatum = hashtab_search(policydbp->p_commons.table, id);
if (comdatum) {
yyerror2("duplicate declaration for common %s\n", id);
+ free(id);
return -1;
}
comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
@@ -770,12 +784,14 @@ int define_sens(void)
while ((id = queue_remove(id_queue))) {
if (id_has_dot(id)) {
yyerror("sensitivity aliases may not contain periods");
- goto bad_alias;
+ free(id);
+ return -1;
}
aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
if (!aliasdatum) {
yyerror("out of memory");
- goto bad_alias;
+ free(id);
+ return -1;
}
level_datum_init(aliasdatum);
aliasdatum->isalias = TRUE;
@@ -940,12 +956,14 @@ int define_category(void)
while ((id = queue_remove(id_queue))) {
if (id_has_dot(id)) {
yyerror("category aliases may not contain periods");
- goto bad_alias;
+ free(id);
+ return -1;
}
aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
if (!aliasdatum) {
yyerror("out of memory");
- goto bad_alias;
+ free(id);
+ return -1;
}
cat_datum_init(aliasdatum);
aliasdatum->isalias = TRUE;
@@ -3863,6 +3881,7 @@ uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
if (!is_id_in_scope(SYM_USERS, id)) {
yyerror2("user %s is not within scope",
id);
+ free(id);
constraint_expr_destroy(expr);
return 0;
}
@@ -3874,6 +3893,7 @@ uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
id);
if (!user) {
yyerror2("unknown user %s", id);
+ free(id);
constraint_expr_destroy(expr);
return 0;
}
@@ -3883,6 +3903,7 @@ uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
yyerror2("role %s is not within scope",
id);
constraint_expr_destroy(expr);
+ free(id);
return 0;
}
role =
@@ -3894,6 +3915,7 @@ uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
if (!role) {
yyerror2("unknown role %s", id);
constraint_expr_destroy(expr);
+ free(id);
return 0;
}
val = role->s.value;
@@ -3906,11 +3928,13 @@ uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
} else {
yyerror("invalid constraint expression");
constraint_expr_destroy(expr);
+ free(id);
return 0;
}
if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
yyerror("out of memory");
ebitmap_destroy(&expr->names);
+ free(id);
constraint_expr_destroy(expr);
return 0;
}
--
2.33.0

View File

@ -0,0 +1,91 @@
From c2fc48be68ee466207d870137681896b0b544691 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 22 Jan 2024 14:54:54 +0100
Subject: [PATCH] checkpolicy: cleanup resources on parse error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Close the input file and free all memory by the queue and lexer on a
syntax or parse error.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
parse_util.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/parse_util.c b/parse_util.c
index 8c1f393..5f92730 100644
--- a/parse_util.c
+++ b/parse_util.c
@@ -26,6 +26,7 @@ extern FILE *yyin;
extern void init_parser(int);
extern int yyparse(void);
extern void yyrestart(FILE *);
+extern int yylex_destroy(void);
extern queue_t id_queue;
extern unsigned int policydb_errors;
extern policydb_t *policydbp;
@@ -34,6 +35,8 @@ extern void set_source_file(const char *name);
int read_source_policy(policydb_t * p, const char *file, const char *progname)
{
+ int rc = -1;
+
yyin = fopen(file, "r");
if (!yyin) {
fprintf(stderr, "%s: unable to open %s: %s\n", progname, file, strerror(errno));
@@ -41,21 +44,26 @@ int read_source_policy(policydb_t * p, const char *file, const char *progname)
}
set_source_file(file);
- if ((id_queue = queue_create()) == NULL) {
+ id_queue = queue_create();
+ if (id_queue == NULL) {
fprintf(stderr, "%s: out of memory!\n", progname);
- return -1;
+ goto cleanup;
}
+ mlspol = p->mls;
policydbp = p;
policydbp->name = strdup(file);
- mlspol = p->mls;
+ if (!policydbp->name) {
+ fprintf(stderr, "%s: out of memory!\n", progname);
+ goto cleanup;
+ }
init_parser(1);
if (yyparse() || policydb_errors) {
fprintf(stderr,
"%s: error(s) encountered while parsing configuration\n",
progname);
- return -1;
+ goto cleanup;
}
rewind(yyin);
init_parser(2);
@@ -65,11 +73,15 @@ int read_source_policy(policydb_t * p, const char *file, const char *progname)
fprintf(stderr,
"%s: error(s) encountered while parsing configuration\n",
progname);
- return -1;
+ goto cleanup;
}
- queue_destroy(id_queue);
+ rc = 0;
+
+cleanup:
+ queue_destroy(id_queue);
fclose(yyin);
+ yylex_destroy();
- return 0;
+ return rc;
}
--
2.33.0

View File

@ -0,0 +1,40 @@
From 652e28838c1af8adf442dee8a805a65c1e58353a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 2 Apr 2024 17:29:25 +0200
Subject: [PATCH] checkpolicy: free complete role_allow_rule on error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Free the ebitmaps inside the rolesets on error.
Reported-by: oss-fuzz (issue 67769)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_define.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/policy_define.c b/policy_define.c
index 4fc6c417..1c019a3b 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -3310,6 +3310,7 @@ int define_role_allow(void)
while ((id = queue_remove(id_queue))) {
if (set_roles(&ra->roles, id)) {
+ role_allow_rule_destroy(ra);
free(ra);
return -1;
}
@@ -3317,6 +3318,7 @@ int define_role_allow(void)
while ((id = queue_remove(id_queue))) {
if (set_roles(&ra->new_roles, id)) {
+ role_allow_rule_destroy(ra);
free(ra);
return -1;
}
--
2.33.0

View File

@ -0,0 +1,57 @@
From 8b115c45ad116030d29bb2b84a268e4083d7548c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 22 Jan 2024 14:54:56 +0100
Subject: [PATCH] checkpolicy: free ebitmap on error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_define.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/policy_define.c b/policy_define.c
index db7e9d0e..053156df 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -2525,6 +2525,8 @@ static int define_te_avtab_helper(int which, avrule_t ** rule)
int add = 1, ret = 0;
int suppress = 0;
+ ebitmap_init(&tclasses);
+
avrule = (avrule_t *) malloc(sizeof(avrule_t));
if (!avrule) {
yyerror("memory error");
@@ -2571,7 +2573,6 @@ static int define_te_avtab_helper(int which, avrule_t ** rule)
}
}
- ebitmap_init(&tclasses);
ret = read_classes(&tclasses);
if (ret)
goto out;
@@ -2648,8 +2649,6 @@ static int define_te_avtab_helper(int which, avrule_t ** rule)
free(id);
}
- ebitmap_destroy(&tclasses);
-
avrule->perms = perms;
*rule = avrule;
@@ -2658,6 +2657,9 @@ static int define_te_avtab_helper(int which, avrule_t ** rule)
avrule_destroy(avrule);
free(avrule);
}
+
+ ebitmap_destroy(&tclasses);
+
return ret;
}
--
2.33.0

View File

@ -0,0 +1,39 @@
From 9f2f9e28475abfaf9c2c756726f6f829c9183308 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Sat, 30 Mar 2024 14:35:01 +0100
Subject: [PATCH] checkpolicy: free identifiers on invalid typebounds
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Free the two identifiers on an invalid typebounds in the error branch,
similar to the success branch.
Reported-by: oss-fuzz (issue 67700)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_define.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/policy_define.c b/policy_define.c
index 0cf938ea..92d1e5f2 100644
--- a/policy_define.c
+++ b/policy_define.c
@@ -1461,8 +1461,12 @@ int define_typebounds(void)
}
while ((id = queue_remove(id_queue))) {
- if (define_typebounds_helper(bounds, id))
+ if (define_typebounds_helper(bounds, id)) {
+ free(bounds);
+ free(id);
return -1;
+ }
+
free(id);
}
free(bounds);
--
2.33.0

View File

@ -0,0 +1,55 @@
From 63207ce82e8ea515704731c908945e8a90fa6843 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 22 Jan 2024 14:55:05 +0100
Subject: [PATCH] checkpolicy: free temporary bounds type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Free the temporary bounds type in the error branches.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
module_compiler.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/module_compiler.c b/module_compiler.c
index 119b7e36..464897cc 100644
--- a/module_compiler.c
+++ b/module_compiler.c
@@ -234,6 +234,7 @@ static int role_implicit_bounds(hashtab_t roles_tab,
if (!bounds) {
yyerror2("role %s doesn't exist, is implicit bounds of %s",
bounds_id, role_id);
+ free(bounds_id);
return -1;
}
@@ -243,6 +244,7 @@ static int role_implicit_bounds(hashtab_t roles_tab,
yyerror2("role %s has inconsistent bounds %s/%s",
role_id, bounds_id,
policydbp->p_role_val_to_name[role->bounds - 1]);
+ free(bounds_id);
return -1;
}
free(bounds_id);
@@ -479,6 +481,7 @@ static int user_implicit_bounds(hashtab_t users_tab,
if (!bounds) {
yyerror2("user %s doesn't exist, is implicit bounds of %s",
bounds_id, user_id);
+ free(bounds_id);
return -1;
}
@@ -488,6 +491,7 @@ static int user_implicit_bounds(hashtab_t users_tab,
yyerror2("user %s has inconsistent bounds %s/%s",
user_id, bounds_id,
policydbp->p_role_val_to_name[user->bounds - 1]);
+ free(bounds_id);
return -1;
}
free(bounds_id);
--
2.33.0

View File

@ -0,0 +1,50 @@
From 39b3cc51350a4ba670f9f38493311ec316e4d84d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 22 Mar 2024 15:50:49 +0100
Subject: [PATCH] checkpolicy: handle unprintable token
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In case the erroneous token is unprintable, e.g. a control character,
print its hex value instead.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_scan.l | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/policy_scan.l b/policy_scan.l
index c4d8e937..d7cf2896 100644
--- a/policy_scan.l
+++ b/policy_scan.l
@@ -321,6 +321,16 @@ GLBLUB { return(GLBLUB); }
%%
int yyerror(const char *msg)
{
+ const char *token;
+ char buf[8];
+
+ if (isprint((unsigned char)yytext[0])) {
+ token = yytext;
+ } else {
+ snprintf(buf, sizeof(buf), "%#x", yytext[0]);
+ token = buf;
+ }
+
if (source_file[0])
fprintf(stderr, "%s:%lu:",
source_file, source_lineno);
@@ -328,7 +338,7 @@ int yyerror(const char *msg)
fprintf(stderr, "(unknown source)::");
fprintf(stderr, "ERROR '%s' at token '%s' on line %lu:\n%s\n%s\n",
msg,
- yytext,
+ token,
policydb_lineno,
linebuf[0], linebuf[1]);
policydb_errors++;
--
2.33.0

View File

@ -0,0 +1,46 @@
From 0ffe97479c8e4ac720526a368bb23f3e6ed9b71a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 2 Apr 2024 17:29:20 +0200
Subject: [PATCH] checkpolicy: include <ctype.h> for isprint(3)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Include the necessary header for isprint(3) to avoid an implicit
function declaration:
policy_scan.l: In function yyerror:
policy_scan.l:342:13: warning: implicit declaration of function isprint [-Wimplicit-function-declaration]
342 | if (isprint((unsigned char)yytext[0])) {
| ^~~~~~~
policy_scan.l:36:1: note: include <ctype.h> or provide a declaration of isprint
35 | #include "y.tab.h"
+++ |+#include <ctype.h>
36 | #endif
This does not currently break the build cause -Werror is stripped for
the parsing code to avoid breakage on old flex/bison versions that might
not generate warning free code.
Fixes: 39b3cc51350a ("checkpolicy: handle unprintable token")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_scan.l | 1 +
1 file changed, 1 insertion(+)
diff --git a/policy_scan.l b/policy_scan.l
index d7cf2896..62f28c11 100644
--- a/policy_scan.l
+++ b/policy_scan.l
@@ -22,6 +22,7 @@
%{
#include <sys/types.h>
+#include <ctype.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
--
2.33.0

View File

@ -0,0 +1,36 @@
From f4330d57705205b52ec117803bf8543a2e59bb00 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 11 Mar 2024 15:57:04 +0100
Subject: [PATCH] checkpolicy: return YYerror on invalid character
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Inform bison about an invalid character by returning YYerror, so the
parser can cleanup internal state and return the failure via yyparse().
Currently the error is only observable via the global variable
policydb_errors, which needs to be checked separately.
Reported-by: oss-fuzz (issue #67270)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_scan.l | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/policy_scan.l b/policy_scan.l
index 19c05a58..1926129c 100644
--- a/policy_scan.l
+++ b/policy_scan.l
@@ -310,7 +310,7 @@ GLBLUB { return(GLBLUB); }
"]" |
"~" |
"*" { return(yytext[0]); }
-. { yyerror("unrecognized character");}
+. { yyerror("unrecognized character"); return YYerror; }
%%
int yyerror(const char *msg)
{
--
2.33.0

View File

@ -0,0 +1,59 @@
From ca77c5929905216fb1c0f70ed632664aa3ec85a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 22 Mar 2024 15:50:48 +0100
Subject: [PATCH] checkpolicy: use YYerror only when available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The special error value YYerror is only available since bison 3.6
(released 2020). For example the version used by oss-fuzz does not
support it.
Use a special token in case YYerror is not available. Only downside is
a duplicate error message, one from the manual yyerror() call and one
from within bison for the unexpected special token (which would be
omitted by using YYerror).
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
policy_parse.y | 1 +
policy_scan.l | 9 ++++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/policy_parse.y b/policy_parse.y
index e0103502..1b275ebc 100644
--- a/policy_parse.y
+++ b/policy_parse.y
@@ -155,6 +155,7 @@ typedef int (* require_func_t)(int pass);
%token FILESYSTEM
%token DEFAULT_USER DEFAULT_ROLE DEFAULT_TYPE DEFAULT_RANGE
%token LOW_HIGH LOW HIGH GLBLUB
+%token INVALID_CHAR
%left OR
%left XOR
diff --git a/policy_scan.l b/policy_scan.l
index 1926129c..c4d8e937 100644
--- a/policy_scan.l
+++ b/policy_scan.l
@@ -310,7 +310,14 @@ GLBLUB { return(GLBLUB); }
"]" |
"~" |
"*" { return(yytext[0]); }
-. { yyerror("unrecognized character"); return YYerror; }
+. { yyerror("unrecognized character");
+/* Available since bison 3.6, avoids duplicate error message */
+#ifdef YYerror
+ return YYerror;
+#else
+ return INVALID_CHAR;
+#endif
+ }
%%
int yyerror(const char *msg)
{
--
2.33.0

View File

@ -1,11 +1,29 @@
Name: checkpolicy Name: checkpolicy
Version: 3.5 Version: 3.5
Release: 1 Release: 2
Summary: SELinux policy compiler Summary: SELinux policy compiler
License: GPLv2 License: GPLv2
URL: https://github.com/SELinuxProject/selinux URL: https://github.com/SELinuxProject/selinux
Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/checkpolicy-%{version}.tar.gz Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/checkpolicy-%{version}.tar.gz
Patch0: backport-checkpolicy-cleanup-resources-on-parse-error.patch
Patch1: backport-checkpolicy-cleanup-identifiers-on-error.patch
Patch2: backport-checkpolicy-free-ebitmap-on-error.patch
Patch3: backport-checkpolicy-check-allocation-and-free-memory-on-erro.patch
Patch4: backport-checkpolicy-clean-expression-on-error.patch
Patch5: backport-checkpolicy-free-temporary-bounds-type.patch
Patch6: backport-checkpolicy-return-YYerror-on-invalid-character.patch
Patch7: backport-checkpolicy-use-YYerror-only-when-available.patch
Patch8: backport-checkpolicy-handle-unprintable-token.patch
Patch9: backport-checkpolicy-free-identifiers-on-invalid-typebounds.patch
Patch10: backport-checkpolicy-include-ctype.h-for-isprint-3.patch
Patch11: backport-checkpolicy-free-complete-role_allow_rule-on-error.patch
Patch12: backport-checkpolicy-Check-the-right-bits-of-an-ibpkeycon-rul.patch
Patch13: backport-checkpolicy-Fix-MLS-users-in-optional-blocks.patch
Patch14: backport-checkpolicy-avoid-leak-of-identifier-on-required-att.patch
Patch15: backport-checkpolicy-avoid-memory-leaks-on-redeclarations.patch
Patch16: backport-checkpolicy-check-identifier-before-copying.patch
BuildRequires: gcc byacc bison flex flex-static libsepol-static >= %{version} libselinux-devel >= %{version} BuildRequires: gcc byacc bison flex flex-static libsepol-static >= %{version} libselinux-devel >= %{version}
Conflicts: selinux-policy-base < 3.13.1-138 Conflicts: selinux-policy-base < 3.13.1-138
@ -54,6 +72,9 @@ install test/dispol %{buildroot}%{_bindir}/sedispol
%{_mandir}/*/* %{_mandir}/*/*
%changelog %changelog
* Fri Mar 14 2025 wangjiang <app@cameyan.com> - 3.5-2
- backport patches from upstream
* Mon Jul 17 2023 zhangguangzhi <zhangguangzhi3@huawei.com> - 3.5-1 * Mon Jul 17 2023 zhangguangzhi <zhangguangzhi3@huawei.com> - 3.5-1
- update version to 3.5 - update version to 3.5