Archive-only list for patches
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev,
	"Christian Göttsche" <cgzones@googlemail.com>,
	"Stephen Smalley" <stephen.smalley.work@gmail.com>,
	"Paul Moore" <paul@paul-moore.com>,
	"Sasha Levin" <sashal@kernel.org>
Subject: [PATCH 7.1 067/101] selinux: more strict policy parsing
Date: Tue, 25 Aug 2026 15:25:45 +0200	[thread overview]
Message-ID: <20260825132544.627544007@linuxfoundation.org> (raw)
In-Reply-To: <20260825132541.986300899@linuxfoundation.org>

7.1-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christian Göttsche <cgzones@googlemail.com>

[ Upstream commit 18fa21f10d008a0fc22565109c7d38f304295912 ]

Be more strict during parsing of policies and reject invalid values.

Add some error messages in the case of policy parse failures, to
enhance debugging, either on a malformed policy or a too strict check.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: fixed checkpatch.pl warnings, style problems]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Stable-dep-of: b98a8ac50775 ("selinux: require a class's permission values to cover its permission count")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/selinux/include/security.h |    1 
 security/selinux/ss/avtab.c         |   35 +++++-
 security/selinux/ss/avtab.h         |   13 ++
 security/selinux/ss/conditional.c   |   18 +--
 security/selinux/ss/constraint.h    |    1 
 security/selinux/ss/policydb.c      |  196 +++++++++++++++++++++++++++++-------
 security/selinux/ss/policydb.h      |   23 +++-
 security/selinux/ss/services.c      |    6 -
 8 files changed, 233 insertions(+), 60 deletions(-)

--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -236,6 +236,7 @@ int security_read_policy(void **data, si
 int security_read_state_kernel(void **data, size_t *len);
 int security_policycap_supported(unsigned int req_cap);
 
+/* Maximum supported number of permissions per class */
 #define SEL_VEC_MAX 32
 struct av_decision {
 	u32 allowed;
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -316,7 +316,7 @@ int avtab_read_item(struct avtab *a, str
 	struct avtab_extended_perms xperms;
 	__le32 buf32[ARRAY_SIZE(xperms.perms.p)];
 	int rc;
-	unsigned int set, vers = pol->policyvers;
+	unsigned int vers = pol->policyvers;
 
 	memset(&key, 0, sizeof(struct avtab_key));
 	memset(&datum, 0, sizeof(struct avtab_datum));
@@ -327,9 +327,12 @@ int avtab_read_item(struct avtab *a, str
 			pr_err("SELinux: avtab: truncated entry\n");
 			return rc;
 		}
+		/* Read five or more items: source type, target type,
+		 * target class, AV type, and at least one datum.
+		 */
 		items2 = le32_to_cpu(buf32[0]);
-		if (items2 > ARRAY_SIZE(buf32)) {
-			pr_err("SELinux: avtab: entry overflow\n");
+		if (items2 < 5 || items2 > ARRAY_SIZE(buf32)) {
+			pr_err("SELinux: avtab: invalid item count\n");
 			return -EINVAL;
 		}
 		rc = next_entry(buf32, fp, sizeof(u32) * items2);
@@ -358,6 +361,13 @@ int avtab_read_item(struct avtab *a, str
 			return -EINVAL;
 		}
 
+		if (!policydb_type_isvalid(pol, key.source_type) ||
+		    !policydb_type_isvalid(pol, key.target_type) ||
+		    !policydb_class_isvalid(pol, key.target_class)) {
+			pr_err("SELinux: avtab: invalid type or class\n");
+			return -EINVAL;
+		}
+
 		val = le32_to_cpu(buf32[items++]);
 		enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0;
 
@@ -376,6 +386,11 @@ int avtab_read_item(struct avtab *a, str
 
 		for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
 			if (val & spec_order[i]) {
+				if (items >= items2) {
+					pr_err("SELinux: avtab: entry has too many items (%d/%d)\n",
+					       items + 1, items2);
+					return -EINVAL;
+				}
 				key.specified = spec_order[i] | enabled;
 				datum.u.data = le32_to_cpu(buf32[items++]);
 				rc = insertf(a, &key, &datum, p);
@@ -411,9 +426,13 @@ int avtab_read_item(struct avtab *a, str
 		return -EINVAL;
 	}
 
-	set = hweight16(key.specified & (AVTAB_XPERMS | AVTAB_TYPE | AVTAB_AV));
-	if (!set || set > 1) {
-		pr_err("SELinux:  avtab:  more than one specifier\n");
+	if (hweight16(key.specified & ~AVTAB_ENABLED) != 1) {
+		pr_err("SELinux:  avtab:  not exactly one specifier\n");
+		return -EINVAL;
+	}
+
+	if (key.specified & ~AVTAB_SPECIFIER_MASK) {
+		pr_err("SELinux:  avtab:  invalid specifier\n");
 		return -EINVAL;
 	}
 
@@ -438,6 +457,10 @@ int avtab_read_item(struct avtab *a, str
 			pr_err("SELinux: avtab: truncated entry\n");
 			return rc;
 		}
+		if (!avtab_is_valid_xperm_specified(xperms.specified))
+			pr_warn_once_policyload(pol,
+						"SELinux: avtab: unsupported xperm specifier %#x\n",
+						xperms.specified);
 		rc = next_entry(&xperms.driver, fp, sizeof(u8));
 		if (rc) {
 			pr_err("SELinux: avtab: truncated entry\n");
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -44,6 +44,7 @@ struct avtab_key {
 	 AVTAB_XPERMS_DONTAUDIT)
 #define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */
 #define AVTAB_ENABLED	  0x8000 /* reserved for used in cond_avtab */
+#define AVTAB_SPECIFIER_MASK (AVTAB_AV | AVTAB_TYPE | AVTAB_XPERMS | AVTAB_ENABLED)
 	u16 specified; /* what field is specified */
 };
 
@@ -68,6 +69,18 @@ struct avtab_extended_perms {
 	struct extended_perms_data perms;
 };
 
+static inline bool avtab_is_valid_xperm_specified(u8 specified)
+{
+	switch (specified) {
+	case AVTAB_XPERMS_IOCTLFUNCTION:
+	case AVTAB_XPERMS_IOCTLDRIVER:
+	case AVTAB_XPERMS_NLMSG:
+		return true;
+	default:
+		return false;
+	}
+}
+
 struct avtab_datum {
 	union {
 		u32 data; /* access vector or type value */
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -199,19 +199,12 @@ int cond_index_bool(void *key, void *dat
 	return 0;
 }
 
-static int bool_isvalid(struct cond_bool_datum *b)
-{
-	if (!(b->state == 0 || b->state == 1))
-		return 0;
-	return 1;
-}
-
 int cond_read_bool(struct policydb *p, struct symtab *s, struct policy_file *fp)
 {
 	char *key = NULL;
 	struct cond_bool_datum *booldatum;
 	__le32 buf[3];
-	u32 len;
+	u32 len, val;
 	int rc;
 
 	booldatum = kzalloc_obj(*booldatum);
@@ -223,11 +216,12 @@ int cond_read_bool(struct policydb *p, s
 		goto err;
 
 	booldatum->value = le32_to_cpu(buf[0]);
-	booldatum->state = le32_to_cpu(buf[1]);
+	val = le32_to_cpu(buf[1]);
 
 	rc = -EINVAL;
-	if (!bool_isvalid(booldatum))
+	if (!val_is_boolean(val))
 		goto err;
+	booldatum->state = (int)val;
 
 	len = le32_to_cpu(buf[2]);
 
@@ -241,6 +235,7 @@ int cond_read_bool(struct policydb *p, s
 
 	return 0;
 err:
+	pr_err("SELinux: conditional: failed to read boolean\n");
 	cond_destroy_bool(key, booldatum, NULL);
 	return rc;
 }
@@ -362,7 +357,8 @@ static int expr_node_isvalid(struct poli
 		return 0;
 	}
 
-	if (expr->boolean > p->p_bools.nprim) {
+	if (expr->expr_type == COND_BOOL &&
+	    (expr->boolean == 0 || expr->boolean > p->p_bools.nprim)) {
 		pr_err("SELinux: conditional expressions uses unknown bool.\n");
 		return 0;
 	}
--- a/security/selinux/ss/constraint.h
+++ b/security/selinux/ss/constraint.h
@@ -50,6 +50,7 @@ struct constraint_expr {
 	u32 op; /* operator */
 
 	struct ebitmap names; /* names */
+	/* internally unused, only forwarded via policydb_write() */
 	struct type_set *type_names;
 
 	struct constraint_expr *next; /* next expression */
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -638,13 +638,11 @@ static int sens_index(void *key, void *d
 	levdatum = datum;
 	p = datap;
 
-	if (!levdatum->isalias) {
-		if (!levdatum->level.sens ||
-		    levdatum->level.sens > p->p_levels.nprim)
-			return -EINVAL;
+	if (!levdatum->level.sens || levdatum->level.sens > p->p_levels.nprim)
+		return -EINVAL;
 
+	if (!levdatum->isalias)
 		p->sym_val_to_name[SYM_LEVELS][levdatum->level.sens - 1] = key;
-	}
 
 	return 0;
 }
@@ -657,12 +655,11 @@ static int cat_index(void *key, void *da
 	catdatum = datum;
 	p = datap;
 
-	if (!catdatum->isalias) {
-		if (!catdatum->value || catdatum->value > p->p_cats.nprim)
-			return -EINVAL;
+	if (!catdatum->value || catdatum->value > p->p_cats.nprim)
+		return -EINVAL;
 
+	if (!catdatum->isalias)
 		p->sym_val_to_name[SYM_CATS][catdatum->value - 1] = key;
-	}
 
 	return 0;
 }
@@ -1159,6 +1156,9 @@ static int perm_read(struct policydb *p,
 
 	len = le32_to_cpu(buf[0]);
 	perdatum->value = le32_to_cpu(buf[1]);
+	rc = -EINVAL;
+	if (perdatum->value < 1 || perdatum->value > SEL_VEC_MAX)
+		goto bad;
 
 	rc = str_read(&key, GFP_KERNEL, fp, len);
 	if (rc)
@@ -1196,6 +1196,9 @@ static int common_read(struct policydb *
 	len = le32_to_cpu(buf[0]);
 	comdatum->value = le32_to_cpu(buf[1]);
 	nel = le32_to_cpu(buf[3]);
+	rc = -EINVAL;
+	if (nel > SEL_VEC_MAX)
+		goto bad;
 
 	rc = symtab_init(&comdatum->permissions, nel);
 	if (rc)
@@ -1345,7 +1348,7 @@ static int class_read(struct policydb *p
 	char *key = NULL;
 	struct class_datum *cladatum;
 	__le32 buf[6];
-	u32 i, len, len2, ncons, nel;
+	u32 i, len, len2, ncons, nel, val;
 	int rc;
 
 	cladatum = kzalloc_obj(*cladatum);
@@ -1358,8 +1361,16 @@ static int class_read(struct policydb *p
 
 	len = le32_to_cpu(buf[0]);
 	len2 = le32_to_cpu(buf[1]);
-	cladatum->value = le32_to_cpu(buf[2]);
 	nel = le32_to_cpu(buf[4]);
+	rc = -EINVAL;
+	if (nel > SEL_VEC_MAX)
+		goto bad;
+
+	val = le32_to_cpu(buf[2]);
+	rc = -EINVAL;
+	if (val > U16_MAX)
+		goto bad;
+	cladatum->value = val;
 
 	rc = symtab_init(&cladatum->permissions, nel);
 	if (rc)
@@ -1427,16 +1438,59 @@ static int class_read(struct policydb *p
 		if (rc)
 			goto bad;
 
-		cladatum->default_user = le32_to_cpu(buf[0]);
-		cladatum->default_role = le32_to_cpu(buf[1]);
-		cladatum->default_range = le32_to_cpu(buf[2]);
+		rc = -EINVAL;
+		val = le32_to_cpu(buf[0]);
+		switch (val) {
+		case 0:
+		case DEFAULT_SOURCE:
+		case DEFAULT_TARGET:
+			cladatum->default_user = val;
+			break;
+		default:
+			goto bad;
+		}
+		val = le32_to_cpu(buf[1]);
+		switch (val) {
+		case 0:
+		case DEFAULT_SOURCE:
+		case DEFAULT_TARGET:
+			cladatum->default_role = val;
+			break;
+		default:
+			goto bad;
+		}
+		val = le32_to_cpu(buf[2]);
+		switch (val) {
+		case 0:
+		case DEFAULT_SOURCE_LOW:
+		case DEFAULT_SOURCE_HIGH:
+		case DEFAULT_SOURCE_LOW_HIGH:
+		case DEFAULT_TARGET_LOW:
+		case DEFAULT_TARGET_HIGH:
+		case DEFAULT_TARGET_LOW_HIGH:
+		case DEFAULT_GLBLUB:
+			cladatum->default_range = val;
+			break;
+		default:
+			goto bad;
+		}
 	}
 
 	if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) {
 		rc = next_entry(buf, fp, sizeof(u32) * 1);
 		if (rc)
 			goto bad;
-		cladatum->default_type = le32_to_cpu(buf[0]);
+		rc = -EINVAL;
+		val = le32_to_cpu(buf[0]);
+		switch (val) {
+		case 0:
+		case DEFAULT_TARGET:
+		case DEFAULT_SOURCE:
+			cladatum->default_type = val;
+			break;
+		default:
+			goto bad;
+		}
 	}
 
 	rc = symtab_insert(s, key, cladatum);
@@ -1446,6 +1500,8 @@ static int class_read(struct policydb *p
 	return 0;
 bad:
 	cls_destroy(key, cladatum, NULL);
+	if (rc)
+		pr_err("SELinux:  invalid class\n");
 	return rc;
 }
 
@@ -1637,7 +1693,7 @@ static int sens_read(struct policydb *p,
 	struct level_datum *levdatum;
 	int rc;
 	__le32 buf[2];
-	u32 len;
+	u32 len, val;
 
 	levdatum = kzalloc_obj(*levdatum);
 	if (!levdatum)
@@ -1648,7 +1704,11 @@ static int sens_read(struct policydb *p,
 		goto bad;
 
 	len = le32_to_cpu(buf[0]);
-	levdatum->isalias = le32_to_cpu(buf[1]);
+	val = le32_to_cpu(buf[1]);
+	rc = -EINVAL;
+	if (!val_is_boolean(val))
+		goto bad;
+	levdatum->isalias = val;
 
 	rc = str_read(&key, GFP_KERNEL, fp, len);
 	if (rc)
@@ -1664,6 +1724,8 @@ static int sens_read(struct policydb *p,
 	return 0;
 bad:
 	sens_destroy(key, levdatum, NULL);
+	if (rc)
+		pr_err("SELinux:  invalid sensitivity\n");
 	return rc;
 }
 
@@ -1673,7 +1735,7 @@ static int cat_read(struct policydb *p,
 	struct cat_datum *catdatum;
 	int rc;
 	__le32 buf[3];
-	u32 len;
+	u32 len, val;
 
 	catdatum = kzalloc_obj(*catdatum);
 	if (!catdatum)
@@ -1685,7 +1747,11 @@ static int cat_read(struct policydb *p,
 
 	len = le32_to_cpu(buf[0]);
 	catdatum->value = le32_to_cpu(buf[1]);
-	catdatum->isalias = le32_to_cpu(buf[2]);
+	val = le32_to_cpu(buf[2]);
+	rc = -EINVAL;
+	if (!val_is_boolean(val))
+		goto bad;
+	catdatum->isalias = val;
 
 	rc = str_read(&key, GFP_KERNEL, fp, len);
 	if (rc)
@@ -1697,6 +1763,8 @@ static int cat_read(struct policydb *p,
 	return 0;
 bad:
 	cat_destroy(key, catdatum, NULL);
+	if (rc)
+		pr_err("SELinux:  invalid category\n");
 	return rc;
 }
 
@@ -1878,7 +1946,7 @@ static int range_read(struct policydb *p
 	struct mls_range *r = NULL;
 	int rc;
 	__le32 buf[2];
-	u32 i, nel;
+	u32 i, nel, val;
 
 	if (p->policyvers < POLICYDB_VERSION_MLS)
 		return 0;
@@ -1909,7 +1977,11 @@ static int range_read(struct policydb *p
 			rc = next_entry(buf, fp, sizeof(u32));
 			if (rc)
 				goto out;
-			rt->target_class = le32_to_cpu(buf[0]);
+			rc = -EINVAL;
+			val = le32_to_cpu(buf[0]);
+			if (val > U16_MAX)
+				goto out;
+			rt->target_class = val;
 		} else
 			rt->target_class = p->process_class;
 
@@ -1946,6 +2018,8 @@ static int range_read(struct policydb *p
 out:
 	kfree(rt);
 	kfree(r);
+	if (rc)
+		pr_err("SELinux:  invalid range\n");
 	return rc;
 }
 
@@ -1954,7 +2028,7 @@ static int filename_trans_read_helper_co
 	struct filename_trans_key key, *ft = NULL;
 	struct filename_trans_datum *last, *datum = NULL;
 	char *name = NULL;
-	u32 len, stype, otype;
+	u32 len, stype, otype, val;
 	__le32 buf[4];
 	int rc;
 
@@ -1973,9 +2047,17 @@ static int filename_trans_read_helper_co
 	if (rc)
 		goto out;
 
+	rc = -EINVAL;
 	stype = le32_to_cpu(buf[0]);
+	if (!policydb_type_isvalid(p, stype))
+		goto out;
 	key.ttype = le32_to_cpu(buf[1]);
-	key.tclass = le32_to_cpu(buf[2]);
+	if (!policydb_type_isvalid(p, key.ttype))
+		goto out;
+	val = le32_to_cpu(buf[2]);
+	if (val > U16_MAX || !policydb_class_isvalid(p, val))
+		goto out;
+	key.tclass = val;
 	key.name = name;
 
 	otype = le32_to_cpu(buf[3]);
@@ -2031,6 +2113,9 @@ out:
 	kfree(ft);
 	kfree(name);
 	kfree(datum);
+
+	if (rc)
+		pr_err("SELinux:  invalid compat filename transition\n");
 	return rc;
 }
 
@@ -2039,7 +2124,7 @@ static int filename_trans_read_helper(st
 	struct filename_trans_key *ft = NULL;
 	struct filename_trans_datum **dst, *datum, *first = NULL;
 	char *name = NULL;
-	u32 len, ttype, ndatum, i;
+	u32 len, ttype, ndatum, i, val;
 	u16 tclass;
 	__le32 buf[3];
 	int rc;
@@ -2059,8 +2144,15 @@ static int filename_trans_read_helper(st
 	if (rc)
 		goto out;
 
+	rc = -EINVAL;
 	ttype = le32_to_cpu(buf[0]);
-	tclass = le32_to_cpu(buf[1]);
+	if (!policydb_type_isvalid(p, ttype))
+		goto out;
+	val = le32_to_cpu(buf[1]);
+	rc = -EINVAL;
+	if (val > U16_MAX || !policydb_class_isvalid(p, val))
+		goto out;
+	tclass = val;
 
 	ndatum = le32_to_cpu(buf[2]);
 	if (ndatum == 0) {
@@ -2090,6 +2182,10 @@ static int filename_trans_read_helper(st
 
 		datum->otype = le32_to_cpu(buf[0]);
 
+		rc = -EINVAL;
+		if (!policydb_type_isvalid(p, datum->otype))
+			goto out;
+
 		dst = &datum->next;
 	}
 
@@ -2121,6 +2217,9 @@ out:
 		ebitmap_destroy(&datum->stypes);
 		kfree(datum);
 	}
+
+	if (rc)
+		pr_err("SELinux:  invalid filename transition\n");
 	return rc;
 }
 
@@ -2168,7 +2267,7 @@ static int filename_trans_read(struct po
 static int genfs_read(struct policydb *p, struct policy_file *fp)
 {
 	int rc;
-	u32 i, j, nel, nel2, len, len2;
+	u32 i, j, nel, nel2, len, len2, val;
 	__le32 buf[1];
 	struct ocontext *l, *c;
 	struct ocontext *newc = NULL;
@@ -2238,7 +2337,11 @@ static int genfs_read(struct policydb *p
 			if (rc)
 				goto out;
 
-			newc->v.sclass = le32_to_cpu(buf[0]);
+			rc = -EINVAL;
+			val = le32_to_cpu(buf[0]);
+			if (val > U16_MAX || (val != 0 && !policydb_class_isvalid(p, val)))
+				goto out;
+			newc->v.sclass = val;
 			rc = context_read_and_validate(&newc->context[0], p,
 						       fp);
 			if (rc)
@@ -2275,6 +2378,9 @@ out:
 	}
 	ocontext_destroy(newc, OCON_FSUSE);
 
+	if (rc)
+		pr_err("SELinux:  invalid genfs\n");
+
 	return rc;
 }
 
@@ -2283,7 +2389,7 @@ static int ocontext_read(struct policydb
 {
 	int rc;
 	unsigned int i;
-	u32 j, nel, len;
+	u32 j, nel, len, val;
 	__be64 prefixbuf[1];
 	__le32 buf[3];
 	struct ocontext *l, *c;
@@ -2347,11 +2453,25 @@ static int ocontext_read(struct policydb
 				rc = next_entry(buf, fp, sizeof(u32) * 3);
 				if (rc)
 					goto out;
-				c->u.port.protocol = le32_to_cpu(buf[0]);
-				c->u.port.low_port = le32_to_cpu(buf[1]);
-				c->u.port.high_port = le32_to_cpu(buf[2]);
-				rc = context_read_and_validate(&c->context[0],
-							       p, fp);
+
+				rc = -EINVAL;
+				val = le32_to_cpu(buf[0]);
+				if (val > U8_MAX)
+					goto out;
+				c->u.port.protocol = val;
+				val = le32_to_cpu(buf[1]);
+				if (val > U16_MAX)
+					goto out;
+				c->u.port.low_port = val;
+				val = le32_to_cpu(buf[2]);
+				if (val > U16_MAX)
+					goto out;
+				c->u.port.high_port = val;
+				if (c->u.port.low_port == 0 ||
+				    c->u.port.low_port > c->u.port.high_port)
+					goto out;
+
+				rc = context_read_and_validate(&c->context[0], p, fp);
 				if (rc)
 					goto out;
 				break;
@@ -2469,6 +2589,8 @@ static int ocontext_read(struct policydb
 	}
 	rc = 0;
 out:
+	if (rc)
+		pr_err("SELinux:  invalid ocon\n");
 	return rc;
 }
 
@@ -2483,7 +2605,7 @@ int policydb_read(struct policydb *p, st
 	struct role_trans_datum *rtd = NULL;
 	int rc;
 	__le32 buf[4];
-	u32 i, j, len, nprim, nel, perm;
+	u32 i, j, len, nprim, nel, perm, val;
 
 	char *policydb_str;
 	const struct policydb_compat_info *info;
@@ -2675,7 +2797,11 @@ int policydb_read(struct policydb *p, st
 			rc = next_entry(buf, fp, sizeof(u32));
 			if (rc)
 				goto bad;
-			rtk->tclass = le32_to_cpu(buf[0]);
+			rc = -EINVAL;
+			val = le32_to_cpu(buf[0]);
+			if (val > U16_MAX)
+				goto bad;
+			rtk->tclass = val;
 		} else
 			rtk->tclass = p->process_class;
 
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -74,7 +74,7 @@ struct class_datum {
 /* Role attributes */
 struct role_datum {
 	u32 value; /* internal role value */
-	u32 bounds; /* boundary of role */
+	u32 bounds; /* boundary of role, 0 for none */
 	struct ebitmap dominates; /* set of roles dominated by this role */
 	struct ebitmap types; /* set of authorized types for role */
 };
@@ -110,7 +110,8 @@ struct role_allow {
 /* Type attributes */
 struct type_datum {
 	u32 value; /* internal type value */
-	u32 bounds; /* boundary of type */
+	u32 bounds; /* boundary of type, 0 for none */
+	/* internally unused, only forwarded via policydb_write() */
 	unsigned char primary; /* primary name? */
 	unsigned char attribute; /* attribute ?*/
 };
@@ -118,7 +119,7 @@ struct type_datum {
 /* User attributes */
 struct user_datum {
 	u32 value; /* internal user value */
-	u32 bounds; /* bounds of user */
+	u32 bounds; /* bounds of user, 0 for none */
 	struct ebitmap roles; /* set of authorized roles for user */
 	struct mls_range range; /* MLS range (min - max) for user */
 	struct mls_level dfltlevel; /* default login MLS level for user */
@@ -195,7 +196,7 @@ struct ocontext {
 		} ibendport;
 	} u;
 	union {
-		u16 sclass; /* security class for genfs */
+		u16 sclass; /* security class for genfs (can be 0 for wildcard) */
 		u32 behavior; /* labeling behavior for fs_use */
 	} v;
 	struct context context[2]; /* security context(s) */
@@ -388,9 +389,23 @@ static inline char *sym_name(struct poli
 	return p->sym_val_to_name[sym_num][element_nr];
 }
 
+static inline bool val_is_boolean(u32 value)
+{
+	return value == 0 || value == 1;
+}
+
 extern int str_read(char **strp, gfp_t flags, struct policy_file *fp, u32 len);
 
 extern u16 string_to_security_class(struct policydb *p, const char *name);
 extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
 
+#define pr_warn_once_policyload(policy, fmt, ...)    \
+	do {                                         \
+		static const void *prev_policy__;    \
+		if (prev_policy__ != policy) {       \
+			pr_warn(fmt, ##__VA_ARGS__); \
+			prev_policy__ = policy;      \
+		}                                    \
+	} while (0)
+
 #endif /* _SS_POLICYDB_H_ */
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -446,8 +446,6 @@ static int dump_masked_av_helper(void *k
 	struct perm_datum *pdatum = d;
 	char **permission_names = args;
 
-	BUG_ON(pdatum->value < 1 || pdatum->value > 32);
-
 	permission_names[pdatum->value - 1] = (char *)k;
 
 	return 0;
@@ -466,7 +464,7 @@ static void security_dump_masked_av(stru
 	char *tclass_name;
 	char *scontext_name = NULL;
 	char *tcontext_name = NULL;
-	char *permission_names[32];
+	char *permission_names[SEL_VEC_MAX];
 	int index;
 	u32 length;
 	bool need_comma = false;
@@ -507,7 +505,7 @@ static void security_dump_masked_av(stru
 			 "scontext=%s tcontext=%s tclass=%s perms=",
 			 reason, scontext_name, tcontext_name, tclass_name);
 
-	for (index = 0; index < 32; index++) {
+	for (index = 0; index < SEL_VEC_MAX; index++) {
 		u32 mask = (1 << index);
 
 		if ((mask & permissions) == 0)



  parent reply	other threads:[~2026-08-25 13:36 UTC|newest]

Thread overview: 115+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-25 13:24 [PATCH 7.1 000/101] 7.1.11-rc1 review Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 001/101] xfs: hoist per-bucket unlinked list check to helper Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 002/101] xfs: dont livelock in scrub on a circular unlinked list Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 003/101] xfs: add a xchk_ip_set_corrupt helper Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 004/101] xfs: rtsummary scrub should treat rtbitmap corruption errors as an xref error Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 005/101] PCI: host-generic: Fix NULL pointer dereference on 32-bit CAM systems Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 006/101] Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 007/101] iommu/tegra241-cmdqv: Fix CMD_SYNC use-after-free on teardown Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 008/101] iommu/iommufd: Fix NULL pointer deref in iommufd_ioas_change_process when racing with iopt_map_file_pages Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 009/101] ALSA: FCP: Use a private URB for the notification endpoint Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 010/101] ALSA: scarlett2: " Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 011/101] rndis_host: add overflow check in rndis_rx_fixup() Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 012/101] nvmet: fix NULL pointer dereference in nvmet_execute_identify_nslist() Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 013/101] io_uring/futex: dont mark futex wake requests as inflight Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 014/101] io_uring/futex: only mark private futex waits " Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 015/101] ALSA: dummy: Check card index validity at probe Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 016/101] io_uring/cmd: fix iovec leak when the async cmd is not recycled Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 017/101] io_uring/io-wq: fix worker accounting when canceling creation callbacks Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 018/101] io_uring/rsrc: fix folio size overflow in io_vec_fill_bvec() Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 019/101] io_uring/uring_cmd: dont skip completion for a synchronous multishot cmd Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 020/101] io_uring: defer eventfd signaling when queued from a wakeup handler Greg Kroah-Hartman
2026-08-25 13:24 ` [PATCH 7.1 021/101] ocfs2: fix missing metadata reservation for large xattrs Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 022/101] null_blk: fix UBSAN shift-out-of-bounds when zone_size is 0 or overflows Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 023/101] kcov: fix data corruption and race conditions on PREEMPT_RT Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 024/101] ext4: stop retrying saturated xattr cache entries Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 025/101] nilfs2: reject invalid block index in GC ioctl Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 026/101] ext4: clear error before retrying inode xattr space fallback Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 027/101] ext4: avoid tail write_begin walk for uptodate folios Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 028/101] ext4: propagate errors from fast commit range replay Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 029/101] ext4: dont enable DAX on new encrypted files Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 030/101] ext4: fix incorrect function call when initializing s_resgid Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 031/101] xfs: validate attr entry pointer before field access Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 032/101] xfs: restore nofs context unconditionally in xfs_trans_roll Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 033/101] drm/i915/pin: s/dev_priv/i915/ and drop struct drm_device usage Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 034/101] drm/i915: Track fence region ID in plane state Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 035/101] drm/i915: Introduce struct intel_fb_pin_params Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 036/101] drm/xe: Fix DPT allocation paths Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 037/101] nfc: digital: clamp SENSF_RES length to the destination buffer Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 038/101] nfc: fdp: bound the device-reported read length and fix an skb leak Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 039/101] nfc: microread: validate target discovery payload lengths Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 040/101] nfc: llcp: bound the connect_sn TLV walk to the skb Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 041/101] nfc: llcp: fix OOB read and u8 offset wrap in TLV parsers Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 042/101] nfc: llcp: reject PDUs shorter than the LLCP header Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 043/101] nfc: pn533: purge fragmented skbs during cleanup Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 044/101] nfc: st21nfca: validate ATR_REQ length against the received frame Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 045/101] nfc: nci: add data_len bound checks to activation parameter extractors Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 046/101] nfc: nci: fix out-of-bounds write in nci_target_auto_activated() Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 047/101] nfc: nci: fix uninit-value in the RF discover/activated NTF handlers Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 048/101] nfc: nci: free destination parameters when closing a connection Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 049/101] ipv4: reject undersized MTUs in ip_do_fragment() Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 050/101] ipv6: fix use-after-free in ip6_finish_output2() Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 051/101] mailbox: mchp-ipc-sbi: Add null check for devm_kasprintf() Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 052/101] dmaengine: fsl-edma: Add error handling for devm_kasprintf Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 053/101] nvmet-auth: zero the AUTH_RECEIVE response buffer Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 054/101] nvmet-fc: fix invalid free in LS IOD error path Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 055/101] nvmet-tcp: bound SGL data length before allocating command buffers Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 056/101] nvmet-tcp: Do not WARN on remotely-controlled oversized SGL allocations Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 057/101] nvmet: pci-epf: fix use-after-free in nvmet_pci_epf_exec_iod_work() Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 058/101] nvmet: pci-epf: put CQ ref on create_cq mapping failure Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 059/101] fbdev: Wrap user-invoked calls to fb_set_var() in helper Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 060/101] fbdev: serialize mode sysfs access with lock_fb_info() Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 061/101] drm/amdgpu: fix recursive ww_mutex acquire in amdgpu_devcoredump_format Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 062/101] drm/amdgpu: Allocate coredump ring buffers per ring Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 063/101] mptcp: pm: rename add_entry structure to add_addr Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 064/101] mptcp: pm: uniform announced addresses helpers Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 065/101] mptcp: pm: fix memory leak from alloc-during-teardown race Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 066/101] selinux: use u16 for security classes Greg Kroah-Hartman
2026-08-25 13:25 ` Greg Kroah-Hartman [this message]
2026-08-25 13:25 ` [PATCH 7.1 068/101] selinux: require a classs permission values to cover its permission count Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 069/101] HID: magicmouse: fix battery reporting for Bluetooth Magic Trackpad USB-C Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 070/101] HID: magicmouse: prevent unbounded recursion in magicmouse_raw_event() Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 071/101] HID: magicmouse: re-enable multitouch after reset-resume Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 072/101] HID: magicmouse: do not keep a stale msc->input if no input is claimed Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 073/101] HID: core: fix OOB read of field->usage in hid_set_field() Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 074/101] HID: pidff: fix OOB write when hid->inputs is empty Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 075/101] net/ionic: avoid OOB TX partner lookup for hwstamp RXQ Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 076/101] futex/pi: Reject cross-mm private futex owners Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 077/101] futex: Sanitize and document task_struct::futex::state transitions Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 078/101] futex/pi: Plug private futex exec() race Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 079/101] futex: Fix race in futex_pivot_pending() during private hash resize Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 080/101] futex: Fix race on the initial mm->futex.phash.ref allocation Greg Kroah-Hartman
2026-08-25 13:25 ` [PATCH 7.1 081/101] futex: Fix might_sleep() warning in futex_pivot_pending() Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 082/101] HID: asus: fix missing hid_is_usb() check Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 083/101] HID: huawei: " Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 084/101] HID: nintendo: fix out-of-bounds read in joycon_ctlr_read_handler() Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 085/101] HID: nintendo: register input device after capabilities are set Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 086/101] HID: nintendo: stop device IO before hid_hw_stop on probe failure Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 087/101] HID: rapoo: fix missing hid_is_usb() check Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 088/101] HID: core: fix number/pointer type confusion on long items Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 089/101] HID: ft260: fix stack-use-after-return write in I2C read race Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 090/101] HID: sensor: custom: Fix use-after-free in enable_sensor Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 091/101] HID: uclogic: fix use-after-free of inrange_timer on remove Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 092/101] HID: hyperv: validate initial device info bounds Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 093/101] HID: input: read battery capacity from its actual report offset Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 094/101] drm/xe: Dont hand out the flat CCS storage as usable VRAM Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 095/101] Bluetooth: hci_event: fix LE list UAF on reset Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 096/101] Bluetooth: hci_event: validate LE Set CIG Parameters response Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 097/101] Bluetooth: hci_sync: Fix accept list UAF during suspend Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 098/101] Bluetooth: ISO: do not force BT_LISTEN after a failed BIG sync Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 099/101] Bluetooth: ISO: zero the sockaddr before returning it in getname Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 100/101] Bluetooth: MGMT: reject HCI_CMD_SYNC params_len above 255 Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 7.1 101/101] Bluetooth: hci_aml: validate firmware segment lengths Greg Kroah-Hartman
2026-08-25 19:35 ` [PATCH 7.1 000/101] 7.1.11-rc1 review Pavel Machek
2026-08-25 21:38 ` Justin Forbes
2026-08-25 23:37 ` Florian Fainelli
2026-08-26  0:03 ` Shuah Khan
2026-08-26  6:03 ` Ron Economos
2026-08-26 10:32 ` Brett A C Sheffield
2026-08-26 12:02 ` Takeshi Ogasawara
2026-08-26 12:27 ` Miguel Ojeda
2026-08-26 15:55 ` Peter Schneider
2026-08-26 19:39 ` Benjamin Boortz
2026-08-26 23:09 ` Barry K. Nathan
2026-08-27 12:37 ` Mark Brown
2026-08-28  8:43 ` Dileep malepu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260825132544.627544007@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=cgzones@googlemail.com \
    --cc=patches@lists.linux.dev \
    --cc=paul@paul-moore.com \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=stephen.smalley.work@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox