!92 同步代码,与22.03-LTS-SP3保持一致

From: @jinlun123123 
Reviewed-by: @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
This commit is contained in:
openeuler-ci-bot 2024-06-11 03:15:33 +00:00 committed by Gitee
commit 8aca5b4ab0
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
29 changed files with 1823 additions and 3 deletions

View File

@ -0,0 +1,91 @@
From 0d1445067c67d38e7d5c14155999afb10cc2e1a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 14 Jul 2023 20:44:12 +0200
Subject: [PATCH] hashtab: update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Avoid overflowing number of elements in hashtab_insert().
Use identical type for hashed values to avoid implicit conversions.
Declare tag parameter of hashtab_hash_eval() const since it is only
printed.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libsepol/include/sepol/policydb/hashtab.h | 2 +-
libsepol/src/hashtab.c | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/libsepol/include/sepol/policydb/hashtab.h b/libsepol/include/sepol/policydb/hashtab.h
index 060e8c9c5..3fcd1fdce 100644
--- a/libsepol/include/sepol/policydb/hashtab.h
+++ b/libsepol/include/sepol/policydb/hashtab.h
@@ -108,7 +108,7 @@ extern int hashtab_map(hashtab_t h,
hashtab_datum_t d,
void *args), void *args);
-extern void hashtab_hash_eval(hashtab_t h, char *tag);
+extern void hashtab_hash_eval(hashtab_t h, const char *tag);
#ifdef __cplusplus
}
diff --git a/libsepol/src/hashtab.c b/libsepol/src/hashtab.c
index 4a827fd31..b1a9bdc2f 100644
--- a/libsepol/src/hashtab.c
+++ b/libsepol/src/hashtab.c
@@ -103,10 +103,10 @@ static void hashtab_check_resize(hashtab_t h)
int hashtab_insert(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum)
{
- int hvalue;
+ unsigned int hvalue;
hashtab_ptr_t prev, cur, newnode;
- if (!h)
+ if (!h || h->nel == UINT32_MAX)
return SEPOL_ENOMEM;
hashtab_check_resize(h);
@@ -144,7 +144,7 @@ int hashtab_remove(hashtab_t h, hashtab_key_t key,
void (*destroy) (hashtab_key_t k,
hashtab_datum_t d, void *args), void *args)
{
- int hvalue;
+ unsigned int hvalue;
hashtab_ptr_t cur, last;
if (!h)
@@ -176,7 +176,7 @@ int hashtab_remove(hashtab_t h, hashtab_key_t key,
hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t key)
{
- int hvalue;
+ unsigned int hvalue;
hashtab_ptr_t cur;
if (!h)
@@ -240,10 +240,10 @@ int hashtab_map(hashtab_t h,
return SEPOL_OK;
}
-void hashtab_hash_eval(hashtab_t h, char *tag)
+void hashtab_hash_eval(hashtab_t h, const char *tag)
{
unsigned int i;
- int chain_len, slots_used, max_chain_len;
+ size_t chain_len, slots_used, max_chain_len;
hashtab_ptr_t cur;
slots_used = 0;
@@ -264,6 +264,6 @@ void hashtab_hash_eval(hashtab_t h, char *tag)
}
printf
- ("%s: %d entries and %d/%d buckets used, longest chain length %d\n",
+ ("%s: %d entries and %zu/%d buckets used, longest chain length %zu\n",
tag, h->nel, slots_used, h->size, max_chain_len);
}

View File

@ -0,0 +1,75 @@
From c3f0124b1817dd4bdc79c86491d77a7a2b08d479 Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Wed, 16 Mar 2022 16:15:57 -0400
Subject: [PATCH] libsepol: Validate conditional expressions
When validating a policydb, validate the conditional expressions
including the values of the booleans within them.
Found by oss-fuzz (#45523)
Signed-off-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/c3f0124b1817dd4bdc79c86491d77a7a2b08d479
Conflict: NA
---
libsepol/src/policydb_validate.c | 43 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index 40e68ac..da3c7c5 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -470,9 +470,52 @@ bad:
return -1;
}
+static int validate_cond_expr(sepol_handle_t *handle, struct cond_expr *expr, validate_t *bool)
+{
+ int depth = -1;
+
+ for (; expr; expr = expr->next) {
+ switch(expr->expr_type) {
+ case COND_BOOL:
+ if (validate_value(expr->bool, bool))
+ goto bad;
+ if (depth == (COND_EXPR_MAXDEPTH - 1))
+ goto bad;
+ depth++;
+ break;
+ case COND_NOT:
+ if (depth < 0)
+ goto bad;
+ break;
+ case COND_OR:
+ case COND_AND:
+ case COND_XOR:
+ case COND_EQ:
+ case COND_NEQ:
+ if (depth < 1)
+ goto bad;
+ depth--;
+ break;
+ default:
+ goto bad;
+ }
+ }
+
+ if (depth != 0)
+ goto bad;
+
+ return 0;
+
+bad:
+ ERR(handle, "Invalid cond expression");
+ return -1;
+}
+
static int validate_cond_list(sepol_handle_t *handle, cond_list_t *cond, validate_t flavors[])
{
for (; cond; cond = cond->next) {
+ if (validate_cond_expr(handle, cond->expr, &flavors[SYM_BOOLS]))
+ goto bad;
if (validate_cond_av_list(handle, cond->true_list, flavors))
goto bad;
if (validate_cond_av_list(handle, cond->false_list, flavors))

View File

@ -0,0 +1,35 @@
From d3c2992ed0358c8e86a83c7f55fc529cba545298 Mon Sep 17 00:00:00 2001
From: Huaxin Lu <luhuaxin1@huawei.com>
Date: Thu, 16 Nov 2023 07:32:07 +0800
Subject: [PATCH] libsepol: add check for category value before printing
In mls_semantic_level_expand(), there is a explicitly determine
whether category is 0, which may cause an potential integer
overflow in error branch.
Signed-off-by: Huaxin Lu <luhuaxin1@huawei.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/d3c2992ed0358c8e86a83c7f55fc529cba545298
Conflict: NA
---
libsepol/src/expand.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index ee5f9185..e63414b1 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -945,8 +945,8 @@ int mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l,
for (cat = sl->cat; cat; cat = cat->next) {
if (!cat->low || cat->low > cat->high) {
ERR(h, "Category range is not valid %s.%s",
- p->p_cat_val_to_name[cat->low - 1],
- p->p_cat_val_to_name[cat->high - 1]);
+ cat->low > 0 ? p->p_cat_val_to_name[cat->low - 1] : "Invalid",
+ cat->high > 0 ? p->p_cat_val_to_name[cat->high - 1] : "Invalid");
return -1;
}
for (i = cat->low - 1; i < cat->high; i++) {
--
2.33.0

View File

@ -0,0 +1,39 @@
From 44375cb4a21dfdf3ac037237c5529049123336c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 9 Nov 2023 14:51:19 +0100
Subject: [PATCH] libsepol: adjust type for saturation check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Change the type for the number of primary names in a symtab to uint32_t,
which conforms to the bytes read and the type used in the symtab.
The type is important for the saturation check via is_saturated(), since
it checks against -1 casted to the specific type.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/44375cb4a21dfdf3ac037237c5529049123336c2
Conflict: NA
---
libsepol/src/policydb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index f608aba4..bc7bc9dc 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -4120,8 +4120,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
{
unsigned int i, j, r_policyvers;
- uint32_t buf[5];
- size_t len, nprim, nel;
+ uint32_t buf[5], nprim;
+ size_t len, nel;
char *policydb_str;
const struct policydb_compat_info *info;
unsigned int policy_type, bufindex;
--
2.33.0

View File

@ -0,0 +1,34 @@
From a55cd37461f2e1ef4cec3b09aa8b99f2d12a529d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 11 Dec 2023 15:48:25 +0100
Subject: [PATCH] libsepol: avoid integer overflow in add_i_to_a()
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>
Reference: https://github.com/SELinuxProject/selinux/commit/a55cd37461f2e1ef4cec3b09aa8b99f2d12a529d
Conflict: NA
---
libsepol/src/util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libsepol/src/util.c b/libsepol/src/util.c
index 571f6c93..4a6f7d11 100644
--- a/libsepol/src/util.c
+++ b/libsepol/src/util.c
@@ -40,7 +40,9 @@ struct val_to_name {
* 0). Return 0 on success, -1 on out of memory. */
int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a)
{
- if (cnt == NULL || a == NULL)
+ uint32_t *new;
+
+ if (cnt == NULL || *cnt == UINT32_MAX || a == NULL)
return -1;
/* FIX ME: This is not very elegant! We use an array that we
--
2.33.0

View File

@ -0,0 +1,39 @@
From 3b05202621539843069bb1477da0d6cfdd384ebc Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Mon, 8 Jan 2024 19:51:09 +0800
Subject: [PATCH] libsepol: avoid leak in OOM branch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In case the member sid_key failed to allocate, free the parent struct.
Reported by Clang Analyzer:
module_to_cil.c:2607:9: warning: Potential leak of memory pointed to by 'item' [unix.Malloc]
2607 | return rc;
| ^~
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/5e425b4165b801666e478b19efbf8ddb14d82a02
Conflict: Context adaptation
---
libsepol/src/module_to_cil.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index cc8066d..9a45cee 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -2570,6 +2570,7 @@ static int ocontext_isid_to_cil(struct policydb *pdb, const char *const *sid_to_
item->sid_key = strdup(sid);
if (!item->sid_key) {
log_err("Out of memory");
+ free(item);
rc = -1;
goto exit;
}
--
2.33.0

View File

@ -0,0 +1,63 @@
From 541aab88459128e2d48bd1fad2c190154a5288c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 9 Nov 2023 14:53:15 +0100
Subject: [PATCH] libsepol: avoid memory corruption on realloc failure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Use a single pointer variable for the realloc(3) result to not
immediately override the source pointer.
Also don't unnecessarily copy the first character.
Reported by Clang Analyzer:
services.c:810:14: warning: Assigned value is garbage or undefined [core.uninitialized.Assign]
810 | **r_buf = **new_buf;
| ^ ~~~~~~~~~
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/541aab88459128e2d48bd1fad2c190154a5288c0
Conflict: NA
---
libsepol/src/services.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
index aa1ad52c..0eeee7ec 100644
--- a/libsepol/src/services.c
+++ b/libsepol/src/services.c
@@ -787,8 +787,8 @@ mls_ops:
if (r_buf && ((s[0] == 0) || ((s[0] == 1 &&
(flags & SHOW_GRANTED) == SHOW_GRANTED)))) {
- int len, new_buf_len;
- char *p, **new_buf = r_buf;
+ int len;
+ char *p;
/*
* These contain the constraint components that are added to the
* callers reason buffer.
@@ -801,13 +801,13 @@ mls_ops:
len = snprintf(p, reason_buf_len - reason_buf_used,
"%s", buffers[x]);
if (len < 0 || len >= reason_buf_len - reason_buf_used) {
- new_buf_len = reason_buf_len + REASON_BUF_SIZE;
- *new_buf = realloc(*r_buf, new_buf_len);
- if (!*new_buf) {
+ int new_buf_len = reason_buf_len + REASON_BUF_SIZE;
+ char *new_buf = realloc(*r_buf, new_buf_len);
+ if (!new_buf) {
ERR(NULL, "failed to realloc reason buffer");
goto out1;
}
- **r_buf = **new_buf;
+ *r_buf = new_buf;
reason_buf_len = new_buf_len;
continue;
} else {
--
2.33.0

View File

@ -0,0 +1,37 @@
From f9fd25005f815d996c4344967a8ad13dee853303 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Wed, 1 Nov 2023 17:37:25 +0100
Subject: [PATCH] libsepol: avtab: check read counts for saturation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ensure counts are not set to the maximum value of their type.
Also limit their size during fuzzing to prevent OOM reports.
Reported-by: oss-fuzz (issue 60572), caused at the time by the filetrans
prefix proposal
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/f9fd25005f815d996c4344967a8ad13dee853303
Conflict: NA
---
libsepol/src/avtab.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c
index 1ef5ee00..7c2328b7 100644
--- a/libsepol/src/avtab.c
+++ b/libsepol/src/avtab.c
@@ -600,7 +600,7 @@ int avtab_read(avtab_t * a, struct policy_file *fp, uint32_t vers)
goto bad;
}
nel = le32_to_cpu(buf[0]);
- if (!nel) {
+ if (zero_or_saturated(nel)) {
ERR(fp->handle, "table is empty");
goto bad;
}
--
2.33.0

View File

@ -0,0 +1,33 @@
From df666f70534ef225b97899f997b4077aeb285972 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 6 Jul 2023 15:57:18 +0200
Subject: [PATCH] libsepol: check for overflow in put_entry()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
put_entry() is used during writing binary policies. Avoid short writes
due to an overflow.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libsepol/src/services.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
index 72772dbd29..6bddc287e1 100644
--- a/libsepol/src/services.c
+++ b/libsepol/src/services.c
@@ -1711,7 +1711,10 @@ int next_entry(void *buf, struct policy_file *fp, size_t bytes)
size_t put_entry(const void *ptr, size_t size, size_t n,
struct policy_file *fp)
{
- size_t bytes = size * n;
+ size_t bytes;
+
+ if (__builtin_mul_overflow(size, n, &bytes))
+ return 0;
switch (fp->type) {
case PF_USE_STDIO:

View File

@ -0,0 +1,87 @@
From 903e8cf26e2ab874618e0fdaef537bc3d9a8b69d Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Fri, 13 Oct 2023 09:26:50 -0400
Subject: [PATCH] libsepol/cil: Do not allow classpermissionset to use
anonymous classpermission
Macros can use classpermission arguments. These are used in two
different ways. Either a named classpermission is passed (which is
declared using a classpermisison rule) or an anonymous classpermission
is passed (something like "(CLASS (PERM))").
Usually this will look like either of the following:
Ex1/
(classpermission cp1)
(classpermisisonset cp1 (CLASS (PERM)))
(macro m1 ((classpermisison ARG1))
(allow t1 self ARG1)
)
(call m1 (cp1))
or
Ex2/
(macro m2 ((classpermission ARG2))
(allow t2 self ARG2)
)
(call m2 ((CLASS (PERM))))
The following would also be valid:
Ex3/
(classpermission cp3)
(macro m3 ((classpermission ARG3))
(classpermissionset ARG3 (CLASS (PERM)))
(allow t3 self ARG3)
)
(call m3 (cp3))
The oss-fuzzer did the equivalent of the following:
(classpermission cp4)
(macro m4 ((classpermission ARG4))
(classpermissionset ARG4 (CLASS (PERM1)))
(allow t4 self ARG4)
)
(call m4 (CLASS (PERM2)))
It passed an anonymous classpermission into a macro where there
was a classpermissionset rule. Suprisingly, everything worked well
until it was time to destroy the AST. There is no way to distinguish
between the anonymous classpermission being passed in which needs
to be destroyed and the classpermission in the classpermissionset
rule which is destroyed when the classpermissionset rule is
destroyed. This led to CIL trying to destroy the classpermission
in the classpermissionset rule twice.
To fix this, when resolving the classpermission name in the
classpermissionset rule, check if the datum returned is for
an anonymous classpermission (it has no name) and return an
error if it is.
This fixes oss-fuzz issue 60670.
Signed-off-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/903e8cf26e2ab874618e0fdaef537bc3d9a8b69d
Conflict: Context adaptation
---
libsepol/cil/src/cil_resolve_ast.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index 4e8a375d6..427a320c9 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -253,6 +253,12 @@ int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_cla
goto exit;
}
+ if (!datum->fqn) {
+ cil_tree_log(current, CIL_ERR, "Anonymous classpermission used in a classpermissionset");
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
rc = cil_resolve_classperms_list(current, cps->classperms, extra_args);
if (rc != SEPOL_OK) {
goto exit;
--
2.33.0

View File

@ -0,0 +1,257 @@
From e81c466bca9a06e2ada7d783fe31dd44c9e04432 Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Thu, 20 Apr 2023 08:58:01 -0400
Subject: [PATCH] libsepol/cil: Fix class permission verification in CIL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Before the CIL post processing phase (where expressions are evaluated,
various ebitmaps are set, etc) there is a pre-verification where
checks are made to find self references or loops in bounds, attribute
sets, and class permissions. The class permission checking is faulty
in two ways.
First, it does not check for the use of "all" in a permission expression
for a class that has no permissions. An error will still be generated
later and secilc will exit cleanly, but without an error message that
explains the problem.
Second, it does not properly handle lists in permission expressions.
For example, "(C ((P)))" is a legitimate class permission. The
permissions expression contains one item that is a list containing
one permission. This permission expression will be properly evaluated.
Unfortunately, the class permission verification assumes that each
item in the permission expression is either an operator or a
permission datum and a segmenation fault will occur.
Refactor the class permission checking to give a proper error when
"all" is used in a permission expression for a class that has no
permissions and so that it can handle lists in permission
expressions. Also, check for the actual flavor of each item in
the permission expression and return an error if an unexpected
flavor is found.
The failure to properly handle lists in permission expressions was
found by oss-fuzz (#58085).
Tested-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: James Carter <jwcart2@gmail.com>
---
libsepol/cil/src/cil_verify.c | 167 +++++++++++++++++++++++-----------
1 file changed, 114 insertions(+), 53 deletions(-)
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
index 4640dc59de..3f58969df2 100644
--- a/libsepol/cil/src/cil_verify.c
+++ b/libsepol/cil/src/cil_verify.c
@@ -1700,31 +1700,109 @@ static int __add_perm_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_d
return SEPOL_OK;
}
-static int __cil_verify_classperms(struct cil_list *classperms,
- struct cil_symtab_datum *orig,
- struct cil_symtab_datum *parent,
- struct cil_symtab_datum *cur,
- enum cil_flavor flavor,
- unsigned steps, unsigned limit)
+static int __cil_verify_classperms(struct cil_list *classperms, struct cil_symtab_datum *orig, struct cil_symtab_datum *cur, unsigned steps, unsigned limit);
+
+static int __cil_verify_map_perm(struct cil_class *class, struct cil_perm *perm, struct cil_symtab_datum *orig, unsigned steps, unsigned limit)
+{
+ int rc;
+
+ if (!perm->classperms) {
+ cil_tree_log(NODE(class), CIL_ERR, "No class permissions for map class %s, permission %s", DATUM(class)->name, DATUM(perm)->name);
+ goto exit;
+ }
+
+ rc = __cil_verify_classperms(perm->classperms, orig, &perm->datum, steps, limit);
+ if (rc != SEPOL_OK) {
+ cil_tree_log(NODE(class), CIL_ERR, "There was an error verifying class permissions for map class %s, permission %s", DATUM(class)->name, DATUM(perm)->name);
+ goto exit;
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return SEPOL_ERR;
+}
+
+
+static int __cil_verify_perms(struct cil_class *class, struct cil_list *perms, struct cil_symtab_datum *orig, unsigned steps, unsigned limit)
{
int rc = SEPOL_ERR;
- struct cil_list_item *curr;
+ int count = 0;
+ struct cil_list_item *i = NULL;
- if (classperms == NULL) {
- if (flavor == CIL_MAP_PERM) {
- cil_tree_log(NODE(cur), CIL_ERR, "Map class %s does not have a classmapping for %s", parent->name, cur->name);
+ if (!perms) {
+ cil_tree_log(NODE(class), CIL_ERR, "No permissions for class %s in class permissions", DATUM(class)->name);
+ goto exit;
+ }
+
+ cil_list_for_each(i, perms) {
+ count++;
+ if (i->flavor == CIL_LIST) {
+ rc = __cil_verify_perms(class, i->data, orig, steps, limit);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ } else if (i->flavor == CIL_DATUM) {
+ struct cil_perm *perm = i->data;
+ if (FLAVOR(perm) == CIL_MAP_PERM) {
+ rc = __cil_verify_map_perm(class, perm, orig, steps, limit);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+ } else if (i->flavor == CIL_OP) {
+ enum cil_flavor op = (enum cil_flavor)(uintptr_t)i->data;
+ if (op == CIL_ALL) {
+ struct cil_list *perm_list;
+ struct cil_list_item *j = NULL;
+ int count2 = 0;
+ cil_list_init(&perm_list, CIL_MAP_PERM);
+ cil_symtab_map(&class->perms, __add_perm_to_list, perm_list);
+ cil_list_for_each(j, perm_list) {
+ count2++;
+ struct cil_perm *perm = j->data;
+ if (FLAVOR(perm) == CIL_MAP_PERM) {
+ rc = __cil_verify_map_perm(class, perm, orig, steps, limit);
+ if (rc != SEPOL_OK) {
+ cil_list_destroy(&perm_list, CIL_FALSE);
+ goto exit;
+ }
+ }
+ }
+ cil_list_destroy(&perm_list, CIL_FALSE);
+ if (count2 == 0) {
+ cil_tree_log(NODE(class), CIL_ERR, "Operator \"all\" used for %s which has no permissions associated with it", DATUM(class)->name);
+ goto exit;
+ }
+ }
} else {
- cil_tree_log(NODE(cur), CIL_ERR, "Classpermission %s does not have a classpermissionset", cur->name);
+ cil_tree_log(NODE(class), CIL_ERR, "Permission list for %s has an unexpected flavor: %d", DATUM(class)->name, i->flavor);
+ goto exit;
}
+ }
+
+ if (count == 0) {
+ cil_tree_log(NODE(class), CIL_ERR, "Empty permissions list for class %s in class permissions", DATUM(class)->name);
+ goto exit;
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return SEPOL_ERR;
+}
+
+static int __cil_verify_classperms(struct cil_list *classperms, struct cil_symtab_datum *orig, struct cil_symtab_datum *cur, unsigned steps, unsigned limit)
+{
+ int rc;
+ struct cil_list_item *i;
+
+ if (classperms == NULL) {
goto exit;
}
if (steps > 0 && orig == cur) {
- if (flavor == CIL_MAP_PERM) {
- cil_tree_log(NODE(cur), CIL_ERR, "Found circular class permissions involving the map class %s and permission %s", parent->name, cur->name);
- } else {
- cil_tree_log(NODE(cur), CIL_ERR, "Found circular class permissions involving the set %s", cur->name);
- }
+ cil_tree_log(NODE(cur), CIL_ERR, "Found circular class permissions involving %s", cur->name);
goto exit;
} else {
steps++;
@@ -1735,44 +1813,20 @@ static int __cil_verify_classperms(struct cil_list *classperms,
}
}
- cil_list_for_each(curr, classperms) {
- if (curr->flavor == CIL_CLASSPERMS) {
- struct cil_classperms *cp = curr->data;
- if (FLAVOR(cp->class) != CIL_CLASS) { /* MAP */
- struct cil_list_item *i = NULL;
- cil_list_for_each(i, cp->perms) {
- if (i->flavor != CIL_OP) {
- struct cil_perm *cmp = i->data;
- rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
- if (rc != SEPOL_OK) {
- goto exit;
- }
- } else {
- enum cil_flavor op = (enum cil_flavor)(uintptr_t)i->data;
- if (op == CIL_ALL) {
- struct cil_class *mc = cp->class;
- struct cil_list *perm_list;
- struct cil_list_item *j = NULL;
-
- cil_list_init(&perm_list, CIL_MAP_PERM);
- cil_symtab_map(&mc->perms, __add_perm_to_list, perm_list);
- cil_list_for_each(j, perm_list) {
- struct cil_perm *cmp = j->data;
- rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
- if (rc != SEPOL_OK) {
- cil_list_destroy(&perm_list, CIL_FALSE);
- goto exit;
- }
- }
- cil_list_destroy(&perm_list, CIL_FALSE);
- }
- }
- }
+ cil_list_for_each(i, classperms) {
+ if (i->flavor == CIL_CLASSPERMS) {
+ struct cil_classperms *cp = i->data;
+ rc = __cil_verify_perms(cp->class, cp->perms, orig, steps, limit);
+ if (rc != SEPOL_OK) {
+ goto exit;
}
} else { /* SET */
- struct cil_classperms_set *cp_set = curr->data;
+ struct cil_classperms_set *cp_set = i->data;
struct cil_classpermission *cp = cp_set->set;
- rc = __cil_verify_classperms(cp->classperms, orig, NULL, &cp->datum, CIL_CLASSPERMISSION, steps, limit);
+ if (!cp->classperms) {
+ cil_tree_log(NODE(cur), CIL_ERR, "Classpermission %s does not have a classpermissionset", DATUM(cp)->name);
+ }
+ rc = __cil_verify_classperms(cp->classperms, orig, &cp->datum, steps, limit);
if (rc != SEPOL_OK) {
goto exit;
}
@@ -1787,9 +1841,15 @@ static int __cil_verify_classperms(struct cil_list *classperms,
static int __cil_verify_classpermission(struct cil_tree_node *node)
{
+ int rc;
struct cil_classpermission *cp = node->data;
- return __cil_verify_classperms(cp->classperms, &cp->datum, NULL, &cp->datum, CIL_CLASSPERMISSION, 0, 2);
+ rc = __cil_verify_classperms(cp->classperms, &cp->datum, &cp->datum, 0, 2);
+ if (rc != SEPOL_OK) {
+ cil_tree_log(node, CIL_ERR, "Error verifying class permissions for classpermission %s", DATUM(cp)->name);
+ }
+
+ return rc;
}
struct cil_verify_map_args {
@@ -1804,8 +1864,9 @@ static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k,
struct cil_perm *cmp = (struct cil_perm *)d;
int rc;
- rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &map_args->class->datum, &cmp->datum, CIL_MAP_PERM, 0, 2);
+ rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &cmp->datum, 0, 2);
if (rc != SEPOL_OK) {
+ cil_tree_log(NODE(cmp), CIL_ERR, "Error verifying class permissions for map class %s, permission %s", DATUM(map_args->class)->name, DATUM(cmp)->name);
map_args->rc = rc;
}

View File

@ -0,0 +1,51 @@
From f5d664ebeb09d837a0551f6df0c8f038937a1b67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 12 May 2023 11:23:11 +0200
Subject: [PATCH] libsepol: dump non-mls validatetrans rules as such
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The functions constraint_expr_to_str() prepare a string representation
for validatetrans and mlsvalidatetrans rules. To decide what keyword to
use the type of expression is consulted. Currently the extra target
type (CEXPR_XTARGET) is considered to be an MLS statement while its not,
e.g.:
validatetrans CLASS1 t3 == ATTR1;
Actually check for MLS expression types only.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libsepol/src/kernel_to_cil.c | 2 +-
libsepol/src/kernel_to_conf.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
index e9cd89c299..7e279e3ff5 100644
--- a/libsepol/src/kernel_to_cil.c
+++ b/libsepol/src/kernel_to_cil.c
@@ -172,7 +172,7 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr
goto exit;
}
- if (curr->attr >= CEXPR_XTARGET) {
+ if (curr->attr >= CEXPR_L1L2) {
*use_mls = 1;
}
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
index c48a71147a..4c93cc10c3 100644
--- a/libsepol/src/kernel_to_conf.c
+++ b/libsepol/src/kernel_to_conf.c
@@ -169,7 +169,7 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr
goto exit;
}
- if (curr->attr >= CEXPR_XTARGET) {
+ if (curr->attr >= CEXPR_L1L2) {
*use_mls = 1;
}

View File

@ -0,0 +1,133 @@
From bd1b7848c66b69bdb1ef25332c90c47d61656437 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 9 Nov 2023 14:51:20 +0100
Subject: [PATCH] libsepol: enhance saturation check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Several values while parsing kernel policies, like symtab sizes or
string lengths, are checked for saturation. They may not be set to the
maximum value, to avoid overflows or occupying a reserved value, and
many of those sizes must not be 0. This is currently handled via the
two macros is_saturated() and zero_or_saturated().
Both macros are tweaked for the fuzzer, because the fuzzer can create
input with huge sizes. While there is no subsequent data to provide
the announced sizes, which will be caught later, memory of the requested
size is allocated, which would lead to OOM reports. Thus the sizes for
the fuzzer are limited to 2^16. This has the drawback of the fuzzer
not checking the complete input space.
Check the sizes in question for actual enough bytes available in the
input. This is (only) possible for mapped memory, which the fuzzer
uses.
Application like setools do currently not benefit from this change,
since they load the policy via a stream. There are currently multiple
interfaces to load a policy, so reworking them to use mapped memory by
default might be subject for future work.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/bd1b7848c66b69bdb1ef25332c90c47d61656437
Conflict: Context adaptation
---
src/avtab.c | 2 +-
src/policydb.c | 9 ++++++---
src/private.h | 18 ++++++++++++++++--
src/services.c | 2 +-
4 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c
index 32cd052..e87361b 100644
--- a/libsepol/src/avtab.c
+++ b/libsepol/src/avtab.c
@@ -600,7 +600,7 @@ int avtab_read(avtab_t * a, struct policy_file *fp, uint32_t vers)
goto bad;
}
nel = le32_to_cpu(buf[0]);
- if (zero_or_saturated(nel)) {
+ if (zero_or_saturated(nel) || exceeds_available_bytes(fp, nel, sizeof(uint32_t) * 3)) {
ERR(fp->handle, "table is empty");
goto bad;
}
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index c601908..9ce6999 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -3927,6 +3927,9 @@ static int scope_index_read(scope_index_t * scope_index,
if (rc < 0)
return -1;
scope_index->class_perms_len = le32_to_cpu(buf[0]);
+ if (is_saturated(scope_index->class_perms_len) ||
+ exceeds_available_bytes(fp, scope_index->class_perms_len, sizeof(uint32_t) * 3))
+ return -1;
if (scope_index->class_perms_len == 0) {
scope_index->class_perms_map = NULL;
return 0;
@@ -4107,7 +4110,8 @@ static int scope_read(policydb_t * p, int symnum, struct policy_file *fp)
goto cleanup;
scope->scope = le32_to_cpu(buf[0]);
scope->decl_ids_len = le32_to_cpu(buf[1]);
- if (scope->decl_ids_len == 0) {
+ if (zero_or_saturated(scope->decl_ids_len) ||
+ exceeds_available_bytes(fp, scope->decl_ids_len, sizeof(uint32_t))) {
ERR(fp->handle, "invalid scope with no declaration");
goto cleanup;
}
@@ -4397,6 +4401,9 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
if (rc < 0)
goto bad;
nprim = le32_to_cpu(buf[0]);
+ if (is_saturated(nprim) ||
+ exceeds_available_bytes(fp, nprim, sizeof(uint32_t) * 3))
+ goto bad;
nel = le32_to_cpu(buf[1]);
if (nel && !nprim) {
ERR(fp->handle, "unexpected items in symbol table with no symbol");
diff --git a/libsepol/src/private.h b/libsepol/src/private.h
index a16d957..1993d77 100644
--- a/libsepol/src/private.h
+++ b/libsepol/src/private.h
@@ -44,8 +44,22 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
-#define is_saturated(x) (x == (typeof(x))-1)
-#define zero_or_saturated(x) ((x == 0) || is_saturated(x))
+static inline int exceeds_available_bytes(const struct policy_file *fp, size_t x, size_t req_elem_size)
+{
+ size_t req_size;
+
+ /* Remaining input size is only available for mmap'ed memory */
+ if (fp->type != PF_USE_MEMORY)
+ return 0;
+
+ if (__builtin_mul_overflow(x, req_elem_size, &req_size))
+ return 1;
+
+ return req_size > fp->len;
+}
+
+#define is_saturated(x) ((x) == (typeof(x))-1)
+#define zero_or_saturated(x) (((x) == 0) || is_saturated(x))
#define spaceship_cmp(a, b) (((a) > (b)) - ((a) < (b)))
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
index 017cfaf..8a80b3a 100644
--- a/libsepol/src/services.c
+++ b/libsepol/src/services.c
@@ -1742,7 +1742,7 @@ int str_read(char **strp, struct policy_file *fp, size_t len)
int rc;
char *str;
- if (zero_or_saturated(len)) {
+ if (zero_or_saturated(len) || exceeds_available_bytes(fp, len, sizeof(char))) {
errno = EINVAL;
return -1;
}
--
2.33.0

View File

@ -0,0 +1,38 @@
From cae65d9a10623bb9063a2e3ca5357bb1602d55af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 12 May 2023 11:30:01 +0200
Subject: [PATCH] libsepol: expand: skip invalid cat
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bail out on expanding levels with invalid low category.
UBSAN report:
expand.c:952:21: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'uint32_t' (aka 'unsigned int')
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/cae65d9a10623bb9063a2e3ca5357bb1602d55af
Conflict: NA
---
libsepol/src/expand.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index c08d3a35..8795229a 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -943,7 +943,7 @@ int mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l,
return -1;
}
for (cat = sl->cat; cat; cat = cat->next) {
- if (cat->low > cat->high) {
+ if (!cat->low || cat->low > cat->high) {
ERR(h, "Category range is not valid %s.%s",
p->p_cat_val_to_name[cat->low - 1],
p->p_cat_val_to_name[cat->high - 1]);
--
2.33.0

View File

@ -0,0 +1,28 @@
From ace9ec17ffaa1ad0be165cd8ad77998cb368ca2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 14 Jul 2023 20:44:13 +0200
Subject: [PATCH] libsepol: expand: use identical type to avoid implicit
conversion
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>
---
libsepol/src/expand.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index 8795229a39..4c9f84cf9d 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -2350,7 +2350,7 @@ static int type_attr_map(hashtab_key_t key
policydb_t *p = state->out;
unsigned int i;
ebitmap_node_t *tnode;
- int value;
+ uint32_t value;
type = (type_datum_t *) datum;
value = type->s.value;

View File

@ -0,0 +1,55 @@
From 6ed7dcf2f6f71d6db5fa89e0b965c10a165f315c Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Mon, 8 Jan 2024 17:09:46 +0800
Subject: [PATCH] libsepol: more strict validation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ensure the ibendport port is not 0 (similar to the kernel).
More general depth test for boolean expressions.
Ensure the boolean id is not set for logic operators.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/7b754f703d704c9d9931497536771e6124ca2418
Conflict: Context adaptation
---
libsepol/src/policydb_validate.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index da3c7c5..09f0813 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -479,13 +479,15 @@ static int validate_cond_expr(sepol_handle_t *handle, struct cond_expr *expr, va
case COND_BOOL:
if (validate_value(expr->bool, bool))
goto bad;
- if (depth == (COND_EXPR_MAXDEPTH - 1))
+ if (depth >= (COND_EXPR_MAXDEPTH - 1))
goto bad;
depth++;
break;
case COND_NOT:
if (depth < 0)
goto bad;
+ if (expr->bool != 0)
+ goto bad;
break;
case COND_OR:
case COND_AND:
@@ -494,6 +496,8 @@ static int validate_cond_expr(sepol_handle_t *handle, struct cond_expr *expr, va
case COND_NEQ:
if (depth < 1)
goto bad;
+ if (expr->bool != 0)
+ goto bad;
depth--;
break;
default:
--
2.33.0

View File

@ -0,0 +1,61 @@
From b1b3467a476b109f20ad581d73c56262205a021e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Wed, 1 Nov 2023 17:37:24 +0100
Subject: [PATCH] libsepol: reject avtab entries with invalid specifier
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Neverallow avtab entries are not supported (normal and extended). Reject
them to avoid lookup confusions via avtab_search(), e.g. when searching
for a invalid key of AVTAB_TRANSITION|AVTAB_NEVERALLOW and the result of
only AVTAB_NEVERALLOW has no transition value.
Simplify the check for the number of specifiers by using the compiler
popcount builtin (already used in libsepol).
Reported-by: oss-fuzz (issue 60568), caused at the time by the filetrans
prefix proposal
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/b1b3467a476b109f20ad581d73c56262205a021e
Conflict: NA
---
libsepol/src/avtab.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c
index 6ab49c5e..1ef5ee00 100644
--- a/libsepol/src/avtab.c
+++ b/libsepol/src/avtab.c
@@ -441,7 +441,6 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
avtab_key_t key;
avtab_datum_t datum;
avtab_extended_perms_t xperms;
- unsigned set;
unsigned int i;
int rc;
@@ -535,13 +534,13 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
key.target_class = le16_to_cpu(buf16[items++]);
key.specified = le16_to_cpu(buf16[items++]);
- set = 0;
- for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
- if (key.specified & spec_order[i])
- set++;
+ if (key.specified & ~(AVTAB_AV | AVTAB_TYPE | AVTAB_XPERMS | AVTAB_ENABLED)) {
+ ERR(fp->handle, "invalid specifier");
+ return -1;
}
- if (!set || set > 1) {
- ERR(fp->handle, "more than one specifier");
+
+ if (__builtin_popcount(key.specified & ~AVTAB_ENABLED) != 1) {
+ ERR(fp->handle, "not exactly one specifier");
return -1;
}
--
2.33.0

View File

@ -0,0 +1,54 @@
From 68c3a9991679702a7adc6e040e5703a7abb50b16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 28 Nov 2023 19:23:32 +0100
Subject: [PATCH] libsepol: reject invalid class datums
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Internally class values are stored in multiple placed in a 16-bit wide
integer. Reject class values exceeding the maximum representable value.
This avoids truncations in the helper
policydb_string_to_security_class(), which gets called before validation
of the policy:
policydb.c:4082:9: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 2113929220 (32-bit, unsigned) to type 'sepol_security_class_t' (aka 'unsigned short') changed the value to 4 (16-bit, unsigned)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/68c3a9991679702a7adc6e040e5703a7abb50b16
Conflict: Context adaptation
---
libsepol/src/policydb.c | 2 ++
libsepol/src/policydb_validate.c | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 6ba4f9168..f10a8a95a 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -2250,6 +2250,8 @@ static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
if (is_saturated(len2))
goto bad;
cladatum->s.value = le32_to_cpu(buf[2]);
+ if (cladatum->s.value > UINT16_MAX)
+ goto bad;
if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE))
goto bad;
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index 6d8641f..69a436b 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -199,7 +199,7 @@ bad:
static int validate_class_datum(sepol_handle_t *handle, class_datum_t *class, validate_t flavors[])
{
- if (validate_value(class->s.value, &flavors[SYM_CLASSES]))
+ if (class->s.value > UINT16_MAX || validate_value(class->s.value, &flavors[SYM_CLASSES]))
goto bad;
if (validate_constraint_nodes(handle, class->constraints, flavors))
goto bad;
--
2.33.0

View File

@ -0,0 +1,47 @@
From 4724538b62e4eb846057b227ce12052749bd4473 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 28 Nov 2023 19:23:34 +0100
Subject: [PATCH] libsepol: reject linking modules with no avrules
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Standard policy modules generated by compilers have at least one global
av rule. Reject modules otherwise, e.g. generated by a fuzzer.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/4724538b62e4eb846057b227ce12052749bd4473
Conflict: NA
---
libsepol/src/link.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/libsepol/src/link.c b/libsepol/src/link.c
index 3b7742bc..b8272308 100644
--- a/libsepol/src/link.c
+++ b/libsepol/src/link.c
@@ -2019,7 +2019,7 @@ static int debug_requirements(link_state_t * state, policydb_t * p)
memset(&req, 0, sizeof(req));
for (cur = p->global; cur != NULL; cur = cur->next) {
- if (cur->enabled != NULL)
+ if (cur->enabled != NULL || cur->branch_list == NULL)
continue;
ret = is_decl_requires_met(state, cur->branch_list, &req);
@@ -2142,6 +2142,11 @@ static int enable_avrules(link_state_t * state, policydb_t * pol)
/* 1) enable all of the non-else blocks */
for (block = pol->global; block != NULL; block = block->next) {
block->enabled = block->branch_list;
+ if (!block->enabled) {
+ ERR(state->handle, "Global block has no avrules!");
+ ret = SEPOL_ERR;
+ goto out;
+ }
block->enabled->enabled = 1;
for (decl = block->branch_list->next; decl != NULL;
decl = decl->next)
--
2.33.0

View File

@ -0,0 +1,75 @@
From e22b7dee0d8de9bc49992fa80b9ceb53925ea36c Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Mon, 8 Jan 2024 17:16:30 +0800
Subject: [PATCH] libsepol: reject unsupported policy capabilities
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Kernel policies with unsupported policy capabilities enabled can
currently be parsed, since they result just in a bit set inside an
ebitmap. Writing such a loaded policy into the traditional language or
CIL will fail however, since the unsupported policy capabilities can not
be converted into a name.
Reject kernel policies with invalid policy capabilities.
Reported-by: oss-fuzz (issue 60573)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/7cf2bfb59313eeef59e916834c3243b7a0ce7b4f
Conflict: Context adaptation
---
libsepol/src/policydb_validate.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index 09f0813..9553812 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -1,6 +1,7 @@
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/ebitmap.h>
+#include <sepol/policydb/polcaps.h>
#include <sepol/policydb/policydb.h>
#include "debug.h"
@@ -771,6 +772,23 @@ bad:
return -1;
}
+static int validate_policycaps(sepol_handle_t *handle, const policydb_t *p)
+{
+ ebitmap_node_t *node;
+ uint32_t i;
+
+ ebitmap_for_each_positive_bit(&p->policycaps, node, i) {
+ if (!sepol_polcap_getname(i))
+ goto bad;
+ }
+
+ return 0;
+
+bad:
+ ERR(handle, "Invalid policy capability");
+ return -1;
+}
+
static void validate_array_destroy(validate_t flavors[])
{
unsigned int i;
@@ -790,6 +808,9 @@ int policydb_validate(sepol_handle_t *handle, policydb_t *p)
if (validate_array_init(p, flavors))
goto bad;
+ if (validate_policycaps(handle, p))
+ goto bad;
+
if (p->policy_type == POLICY_KERN) {
if (validate_avtab(handle, &p->te_avtab, flavors))
goto bad;
--
2.33.0

View File

@ -0,0 +1,50 @@
From 4f1435dd51f832fa3b122e5e98be2a5ab176780c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 28 Nov 2023 19:23:29 +0100
Subject: [PATCH] libsepol: use correct type to avoid truncations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Avoid truncations of the read 32 bit unsigned integer:
conditional.c:764:8: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 3758096384 (32-bit, unsigned) to type 'int' changed the value to -536870912 (32-bit, signed)
conditional.c:831:8: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 4280295456 (32-bit, unsigned) to type 'int' changed the value to -14671840 (32-bit, signed)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/4f1435dd51f832fa3b122e5e98be2a5ab176780c
Conflict: NA
---
libsepol/src/conditional.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libsepol/src/conditional.c b/libsepol/src/conditional.c
index 24380ea0..420c7b6c 100644
--- a/libsepol/src/conditional.c
+++ b/libsepol/src/conditional.c
@@ -746,8 +746,8 @@ static int expr_isvalid(policydb_t * p, cond_expr_t * expr)
static int cond_read_node(policydb_t * p, cond_node_t * node, void *fp)
{
- uint32_t buf[2];
- int len, i, rc;
+ uint32_t buf[2], i, len;
+ int rc;
cond_expr_t *expr = NULL, *last = NULL;
rc = next_entry(buf, fp, sizeof(uint32_t));
@@ -821,8 +821,8 @@ static int cond_read_node(policydb_t * p, cond_node_t * node, void *fp)
int cond_read_list(policydb_t * p, cond_list_t ** list, void *fp)
{
cond_node_t *node, *last = NULL;
- uint32_t buf[1];
- int i, len, rc;
+ uint32_t buf[1], i, len;
+ int rc;
rc = next_entry(buf, fp, sizeof(uint32_t));
if (rc < 0)
--
2.33.0

View File

@ -0,0 +1,67 @@
From 8fdb3eb2725040a81e8a600cf6edd3ff4d93c81f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 9 Dec 2021 17:49:15 +0100
Subject: [PATCH] libsepol: validate MLS levels
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Validate the level map of the policy to ensure no level refers to a non
existent category.
READ of size 8 at 0x602000000c58 thread T0
#0 0x568d2c in cats_ebitmap_len ./libsepol/src/kernel_to_conf.c:1003:14
#1 0x568d2c in cats_ebitmap_to_str ./libsepol/src/kernel_to_conf.c:1038:19
#2 0x55e371 in write_level_rules_to_conf ./libsepol/src/kernel_to_conf.c:1106:11
#3 0x55e371 in write_mls_rules_to_conf ./libsepol/src/kernel_to_conf.c:1140:7
#4 0x55adb1 in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3103:7
#5 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#6 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#7 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#8 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#9 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#10 0x7f741d0d67ec in __libc_start_main csu/../csu/libc-start.c:332:16
#11 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/8fdb3eb2725040a81e8a600cf6edd3ff4d93c81f
Conflict: Context adaptation
---
libsepol/src/policydb_validate.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index d4dfab5cd1..03ab4445a8 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -294,6 +294,27 @@ bad:
return -1;
}
+static int validate_mls_level(mls_level_t *level, validate_t *sens, validate_t *cats)
+{
+ if (validate_value(level->sens, sens))
+ goto bad;
+ if (validate_ebitmap(&level->cat, cats))
+ goto bad;
+
+ return 0;
+
+ bad:
+ return -1;
+}
+
+static int validate_level_datum(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
+{
+ level_datum_t *level = d;
+ validate_t *flavors = args;
+
+ return validate_mls_level(level->level, &flavors[SYM_LEVELS], &flavors[SYM_CATS]);
+}
+
static int validate_mls_range(mls_range_t *range, validate_t *sens, validate_t *cats)
{
if (validate_mls_level(&range->level[0], sens, cats))
--
2.33.0

View File

@ -0,0 +1,28 @@
From ac015a3996e894754350ea8ae97e66644899a2c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 12 May 2023 11:29:59 +0200
Subject: [PATCH] libsepol: validate: check low category is not bigger than
high
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>
---
libsepol/src/policydb_validate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index e0d290ff32..b34f83ecb5 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -545,6 +545,8 @@ static int validate_mls_semantic_cat(const mls_semantic_cat_t *cat, const valida
goto bad;
if (validate_value(cat->high, cats))
goto bad;
+ if (cat->low > cat->high)
+ goto bad;
}
return 0;

View File

@ -0,0 +1,35 @@
From e54bedce80267b4fbd79b16f548a278c097bd675 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 11 Dec 2023 15:55:40 +0100
Subject: [PATCH] libsepol: validate empty common classes in scope indices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Validate no common classes inside scope indices are defined.
Reported-by: oss-fuzz (issue 64849)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/e54bedce80267b4fbd79b16f548a278c097bd675
Conflict: Context adaptation
---
libsepol/src/policydb_validate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index bd8e9f8f3..d86f885e4 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -730,6 +730,8 @@ bad:
static int validate_scope_index(sepol_handle_t *handle, scope_index_t *scope_index, validate_t flavors[])
{
+ if (!ebitmap_is_empty(&scope_index->scope[SYM_COMMONS]))
+ goto bad;
if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES]))
goto bad;
if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES]))
--
2.33.0

View File

@ -0,0 +1,80 @@
From fffb16093c6eb4a316f530ac5813459277dfd40b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 9 Dec 2021 17:49:16 +0100
Subject: [PATCH] libsepol: validate expanded user range and level
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Check those contains valid values.
==57532==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000001178 at pc 0x000000564c04 bp 0x7ffed7a5ad90 sp 0x7ffed7a5ad88
READ of size 8 at 0x603000001178 thread T0
#0 0x564c03 in level_to_str ./libsepol/src/kernel_to_conf.c:1901:19
#1 0x564c03 in range_to_str ./libsepol/src/kernel_to_conf.c:1926:9
#2 0x564c03 in write_user_decl_rules_to_conf ./libsepol/src/kernel_to_conf.c:2367:12
#3 0x55b137 in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3184:7
#4 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#5 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#6 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#7 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#8 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#9 0x7f2c2e1a77ec in __libc_start_main csu/../csu/libc-start.c:332:16
#10 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/fffb16093c6eb4a316f530ac5813459277dfd40b
Conflict: Context adaptation
---
libsepol/src/policydb_validate.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index 03ab4445a8..adaa3fb2d8 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -294,7 +294,20 @@ bad:
return -1;
}
-static int validate_user_datum(sepol_handle_t *handle, user_datum_t *user, validate_t flavors[])
+static int validate_mls_range(mls_range_t *range, validate_t *sens, validate_t *cats)
+{
+ if (validate_mls_level(&range->level[0], sens, cats))
+ goto bad;
+ if (validate_mls_level(&range->level[1], sens, cats))
+ goto bad;
+
+ return 0;
+
+ bad:
+ return -1;
+}
+
+static int validate_user_datum(sepol_handle_t *handle, user_datum_t *user, validate_t flavors[], int mls)
{
if (validate_value(user->s.value, &flavors[SYM_USERS]))
goto bad;
@@ -304,6 +317,10 @@ static int validate_user_datum(sepol_handle_t *handle, user_datum_t *user, valid
goto bad;
if (validate_mls_semantic_level(&user->dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
goto bad;
+ if (mls && validate_mls_range(&user->exp_range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
+ goto bad;
+ if (mls && validate_mls_level(&user->exp_dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
+ goto bad;
if (user->bounds && validate_value(user->bounds, &flavors[SYM_USERS]))
goto bad;
@@ -364,7 +381,7 @@ static int validate_datum_arrays(sepol_handle_t *handle, policydb_t *p, validate
if (p->user_val_to_struct[i]) {
if (ebitmap_get_bit(&flavors[SYM_USERS].gaps, i))
goto bad;
- if (validate_user_datum(handle, p->user_val_to_struct[i], flavors))
+ if (validate_user_datum(handle, p->user_val_to_struct[i], flavors, p->mls))
goto bad;
} else {
if (!ebitmap_get_bit(&flavors[SYM_USERS].gaps, i))
--
2.33.0

View File

@ -0,0 +1,103 @@
From 8628133757c2100118ef5bd2f135eb1bc4a6f33c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 9 Dec 2021 17:49:22 +0100
Subject: [PATCH] libsepol: validate ocontexts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Check the literal contexts in ocontext statements are defined.
==91274==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f60b0afe8c6 bp 0x7ffd42edc990 sp 0x7ffd42edc148 T0)
==91274==The signal is caused by a READ memory access.
==91274==Hint: address points to the zero page.
#0 0x7f60b0afe8c6 string/../sysdeps/x86_64/multiarch/../strlen.S:120
#1 0x4bd128 in __interceptor_strlen (./out/binpolicy-fuzzer+0x4bd128)
#2 0x5eb387 in create_str_helper ./libsepol/src/kernel_to_common.c:69:10
#3 0x5eb11e in create_str ./libsepol/src/kernel_to_common.c:99:8
#4 0x56ad7b in context_to_str ./libsepol/src/kernel_to_conf.c:2408:9
#5 0x56a717 in write_sid_context_rules_to_conf ./libsepol/src/kernel_to_conf.c:2441:9
#6 0x55b26c in write_selinux_isid_rules_to_conf ./libsepol/src/kernel_to_conf.c:2476:9
#7 0x55b26c in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3206:8
#8 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#9 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#10 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#11 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#12 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#13 0x7f60b0a887ec in __libc_start_main csu/../csu/libc-start.c:332:16
#14 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/8628133757c2100118ef5bd2f135eb1bc4a6f33c
Conflict: NA
---
libsepol/src/policydb_validate.c | 46 ++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index 57eb2550..bedf3b90 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -736,6 +736,49 @@ static int validate_filename_trans_hashtab(sepol_handle_t *handle, hashtab_t fil
return 0;
}
+static int validate_context(context_struct_t *con, validate_t flavors[], int mls)
+{
+ if (validate_value(con->user, &flavors[SYM_USERS]))
+ return -1;
+ if (validate_value(con->role, &flavors[SYM_ROLES]))
+ return -1;
+ if (validate_value(con->type, &flavors[SYM_TYPES]))
+ return -1;
+ if (mls && validate_mls_range(&con->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
+ return -1;
+
+ return 0;
+}
+
+static int validate_ocontexts(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
+{
+ ocontext_t *octx;
+ unsigned int i;
+
+ for (i = 0; i < OCON_NUM; i++) {
+ for (octx = p->ocontexts[i]; octx; octx = octx->next) {
+ if (validate_context(&octx->context[0], flavors, p->mls))
+ goto bad;
+
+ if (p->target_platform == SEPOL_TARGET_SELINUX) {
+ switch (i) {
+ case OCON_FS:
+ case OCON_NETIF:
+ if (validate_context(&octx->context[1], flavors, p->mls))
+ goto bad;
+ break;
+ }
+ }
+ }
+ }
+
+ return 0;
+
+bad:
+ ERR(handle, "Invalid ocontext");
+ return -1;
+}
+
/*
* Functions to validate a module policydb
*/
@@ -936,6 +979,9 @@ int validate_policydb(sepol_handle_t *handle, policydb_t *p)
goto bad;
}
+ if (validate_ocontexts(handle, p, flavors))
+ goto bad;
+
if (validate_scopes(handle, p->scope, p->global))
goto bad;
--
2.33.0

View File

@ -0,0 +1,41 @@
From 4cf37608b563327ce433ce392931a9eb8bda9524 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 12 May 2023 11:29:58 +0200
Subject: [PATCH] libsepol: validate old style range trans classes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
For old style range transition rules the class defaults to process.
However the policy might not declare the process class leading to
setting a wrong bit later on via:
if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1))
UBSAN report:
policydb.c:3684:56: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'uint32_t' (aka 'unsigned int')
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
---
libsepol/src/policydb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index b79c19b94c..605d290a71 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -3650,10 +3650,10 @@ static int range_read(policydb_t * p, struct policy_file *fp)
if (rc < 0)
goto err;
rt->target_class = le32_to_cpu(buf[0]);
- if (!value_isvalid(rt->target_class, p->p_classes.nprim))
- goto err;
} else
rt->target_class = p->process_class;
+ if (!value_isvalid(rt->target_class, p->p_classes.nprim))
+ goto err;
r = calloc(1, sizeof(*r));
if (!r)
goto err;

View File

@ -0,0 +1,50 @@
From cf6ddded1650098c05f4245df41395420cf41838 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Thu, 9 Nov 2023 14:51:21 +0100
Subject: [PATCH] libsepol: validate the identifier for initials SID is valid
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Check the identifier for initial SIDs is less than the maximum known ID.
The kernel will ignore all unknown IDs, see
security/selinux/ss/policydb.c:policydb_load_isids().
Without checking huge IDs result in OOM events, while writing policies,
e.g. in write_sids_to_conf() or write_sids_to_cil(), due to allocation
of large (continuous) string lists.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Reference: https://github.com/SELinuxProject/selinux/commit/cf6ddded1650098c05f4245df41395420cf41838
Conflict: Context adaptation
---
libsepol/src/policydb_validate.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
index 016ab6550..32ad5a18b 100644
--- a/libsepol/src/policydb_validate.c
+++ b/libsepol/src/policydb_validate.c
@@ -5,6 +5,7 @@
#include <sepol/policydb/policydb.h>
#include "debug.h"
+#include "kernel_to_common.h"
#include "policydb_validate.h"
typedef struct validate {
@@ -635,6 +636,10 @@ static int validate_ocontexts(sepol_handle_t *handle, policydb_t *p, validate_t
if (p->target_platform == SEPOL_TARGET_SELINUX) {
switch (i) {
+ case OCON_ISID:
+ if (octx->sid[0] == SEPOL_SECSID_NULL || octx->sid[0] >= SELINUX_SID_SZ)
+ goto bad;
+ break;
case OCON_FS:
case OCON_NETIF:
if (validate_context(&octx->context[1], flavors, p->mls))
--
2.33.0

View File

@ -1,6 +1,6 @@
Name: libsepol
Version: 3.3
Release: 5
Release: 7
Summary: SELinux binary policy manipulation library
License: LGPLv2+
URL: https://github.com/SELinuxProject/selinux/wiki/Releases
@ -13,7 +13,35 @@ Patch0004: backport-libsepol-do-not-modify-policy-during-write.patch
Patch0005: backport-libsepol-enclose-macro-parameters-and-replacement-lists-in-parentheses.patch
Patch0006: backport-libsepol-rename-validate_policydb-to-policydb_validate.patch
Patch0007: backport-libsepol-fix-missing-double-quotes-in-typetransition-CIL-rule.patch
Patch0008: backport-libsepol-reorder-calloc-3-arguments.patch
Patch0008: backport-hashtab-update.patch
Patch0009: backport-libsepol-check-for-overflow-in-put_entry.patch
Patch0010: backport-libsepol-dump-non-mls-validatetrans-rules-as-such.patch
Patch0011: backport-libsepol-expand-use-identical-type-to-avoid-implicit-conversion.patch
Patch0012: backport-libsepol-cil-Fix-class-permission-verification-in-CIL.patch
Patch0013: backport-libsepol-validate-old-style-range-trans-classes.patch
Patch0014: backport-libsepol-validate-check-low-category-is-not-bigger-than-high.patch
Patch0015: backport-libsepol-Validate-conditional-expressions.patch
Patch0016: backport-libsepol-reject-avtab-entries-with-invalid-specifier.patch
Patch0017: backport-libsepol-avtab-check-read-counts-for-saturation.patch
Patch0018: backport-libsepol-expand-skip-invalid-cat.patch
Patch0019: backport-libsepol-more-strict-validation.patch
Patch0020: backport-libsepol-reject-unsupported-policy-capabilities.patch
Patch0021: backport-libsepol-adjust-type-for-saturation-check.patch
Patch0022: backport-libsepol-enhance-saturation-check.patch
Patch0023: backport-libsepol-avoid-leak-in-OOM-branch.patch
Patch0024: backport-libsepol-avoid-memory-corruption-on-realloc-failure.patch
Patch0025: backport-libsepol-cil-Do-not-allow-classpermissionset-to-use-.patch
Patch0026: backport-libsepol-add-check-for-category-value-before-printin.patch
Patch0027: backport-libsepol-use-correct-type-to-avoid-truncations.patch
Patch0028: backport-libsepol-reject-invalid-class-datums.patch
Patch0029: backport-libsepol-reject-linking-modules-with-no-avrules.patch
Patch0030: backport-libsepol-avoid-integer-overflow-in-add_i_to_a.patch
Patch0031: backport-libsepol-validate-empty-common-classes-in-scope-indi.patch
Patch0032: backport-libsepol-validate-expanded-user-range-and-level.patch
Patch0033: backport-libsepol-validate-MLS-levels.patch
Patch0034: backport-libsepol-validate-ocontexts.patch
Patch0035: backport-libsepol-validate-the-identifier-for-initials-SID-is.patch
Patch0036: backport-libsepol-reorder-calloc-3-arguments.patch
BuildRequires: gcc flex
@ -73,9 +101,15 @@ make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
%{_mandir}/man3/*
%changelog
* Tue Mar 26 2024 gengqihu <gengqihu2@h-partners.com> - 3.3-5
* Tue Mar 26 2024 gengqihu <gengqihu2@h-partners.com> - 3.3-7
- backport bugfix from upstream
* Mon Mar 4 2024 zhengxiaoxiao <zhengxiaoxiao2@huawei.com> - 3.3-6
- backport upstream patch
* Mon Nov 27 2023 luhuaxin <luhuaxin1@huawei.com> - 3.3-5
- backport upstream patch
* Fri Nov 18 2022 jinlun <jinlun@huawei.com> - 3.3-4
- backport upstream patch and update release to adapt baseline