Compare commits
10 Commits
259af10f20
...
bfcfa5915c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfcfa5915c | ||
|
|
b993887e8d | ||
|
|
766a853c25 | ||
|
|
a8243a9af7 | ||
|
|
b8a7a78130 | ||
|
|
06df40169a | ||
|
|
39bdfb477c | ||
|
|
192fb9e6c6 | ||
|
|
7c0ef1bd78 | ||
|
|
4fadd3003c |
@ -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
|
||||
|
||||
173
backport-checkpolicy-Fix-MLS-users-in-optional-blocks.patch
Normal file
173
backport-checkpolicy-Fix-MLS-users-in-optional-blocks.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
229
backport-checkpolicy-avoid-memory-leaks-on-redeclarations.patch
Normal file
229
backport-checkpolicy-avoid-memory-leaks-on-redeclarations.patch
Normal 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
|
||||
@ -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
|
||||
|
||||
55
backport-checkpolicy-check-identifier-before-copying.patch
Normal file
55
backport-checkpolicy-check-identifier-before-copying.patch
Normal 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
|
||||
|
||||
237
backport-checkpolicy-clean-expression-on-error.patch
Normal file
237
backport-checkpolicy-clean-expression-on-error.patch
Normal 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
|
||||
|
||||
196
backport-checkpolicy-cleanup-identifiers-on-error.patch
Normal file
196
backport-checkpolicy-cleanup-identifiers-on-error.patch
Normal 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
|
||||
|
||||
91
backport-checkpolicy-cleanup-resources-on-parse-error.patch
Normal file
91
backport-checkpolicy-cleanup-resources-on-parse-error.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
57
backport-checkpolicy-free-ebitmap-on-error.patch
Normal file
57
backport-checkpolicy-free-ebitmap-on-error.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
55
backport-checkpolicy-free-temporary-bounds-type.patch
Normal file
55
backport-checkpolicy-free-temporary-bounds-type.patch
Normal 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
|
||||
|
||||
50
backport-checkpolicy-handle-unprintable-token.patch
Normal file
50
backport-checkpolicy-handle-unprintable-token.patch
Normal 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
|
||||
|
||||
46
backport-checkpolicy-include-ctype.h-for-isprint-3.patch
Normal file
46
backport-checkpolicy-include-ctype.h-for-isprint-3.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
59
backport-checkpolicy-use-YYerror-only-when-available.patch
Normal file
59
backport-checkpolicy-use-YYerror-only-when-available.patch
Normal 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
|
||||
|
||||
Binary file not shown.
BIN
checkpolicy-3.5.tar.gz
Normal file
BIN
checkpolicy-3.5.tar.gz
Normal file
Binary file not shown.
@ -1,12 +1,30 @@
|
||||
Name: checkpolicy
|
||||
Version: 3.1
|
||||
Version: 3.5
|
||||
Release: 2
|
||||
Summary: SELinux policy compiler
|
||||
License: GPLv2
|
||||
URL: https://github.com/SELinuxProject/selinux
|
||||
Source0: https://github.com/SELinuxProject/selinux/releases/download/20200710/checkpolicy-3.1.tar.gz
|
||||
Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/checkpolicy-%{version}.tar.gz
|
||||
|
||||
BuildRequires: gcc byacc bison flex flex-static libsepol-static libselinux-devel
|
||||
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}
|
||||
|
||||
Conflicts: selinux-policy-base < 3.13.1-138
|
||||
|
||||
@ -46,7 +64,7 @@ install test/dispol %{buildroot}%{_bindir}/sedispol
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%license COPYING
|
||||
%license LICENSE
|
||||
%{_bindir}/*
|
||||
|
||||
%files help
|
||||
@ -54,6 +72,21 @@ install test/dispol %{buildroot}%{_bindir}/sedispol
|
||||
%{_mandir}/*/*
|
||||
|
||||
%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
|
||||
- update version to 3.5
|
||||
|
||||
* Fri Mar 10 2023 zhangchenfeng <zhangchenfeng1@huawei.com> - 3.4-2
|
||||
- backport upstrem bugfix
|
||||
|
||||
* Thu Feb 2 2023 zhangguangzhi <zhangguangzhi3@huawei.com> - 3.4-1
|
||||
- update version to 3.4
|
||||
|
||||
* Tue Jan 18 2022 yixiangzhike <yixiangzhike007@163.com> - 3.3-1
|
||||
- update to 3.3
|
||||
|
||||
* Fri Jul 30 2021 chenyanpanHW <chenyanpan@huawei.com> - 3.1-2
|
||||
- DESC: delete -Sgit from %autosetup, and delete BuildRequires git
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user