From nobody Fri Oct 2 12:22:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4653416125; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785519850; cv=none; b=giuN9t8t3UWh075lP09AIhqcHjh63uhG1l2GGbFquDo/nywSgMKozhyqSx0ayIejhKoSfFkRsP+iAtYCgEqMb1yK/0r0OrL5xZkjz8Oh9ghxALhP3aJQkGG7xLqcUvlgdpaFEexcKDLojfclc+GSpRnInHdyHd7OAnxk8ybHgWo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785519850; c=relaxed/simple; bh=PLkkmGRA1MvUV3Aj1xQ20xyb2Y/W9NXMEoXlMvEX9cw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HvAuLn+th7jSWXZ/aVJvVcZMrNgavMiYAGLX/w0YE4bifk+4ZHJV4sDg16qYWKWokSa7vjTa4WLpHtqHs69JLYRiQVwn5vrzUt7iXpKjTpWHqWGWgiUB/cUJw/Ko/nhjs53a3GhHDJMIb5KDYK9KH9lIROYAsWGK9gQdyDpOwrc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CfuMPBT+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CfuMPBT+" Received: by smtp.kernel.org (Postfix) with ESMTPS id 0305FC2BCF4; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785519850; bh=PLkkmGRA1MvUV3Aj1xQ20xyb2Y/W9NXMEoXlMvEX9cw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=CfuMPBT+RB6JrztQEnBIBLel5Jc5ViipV9D7BvG7xPu+wddbh5UVXnWRimZj0dLQL dropNh731s3ciEIw5rRThxDd79nP+G26sEm9y7rj0vWEn2jE1MKxpY/nEtyTQnam6N fF2KDyYqCQceFWAcA4YMF0MfsBqzKmdmq06Cr3oHH9ID3FwYzki+p2aLJaV10125b2 uk6NgjVa0eBoJ7ixpjpgu5zIFfzzwNZscdgcq+6lde4jRE/F2ahYRVDXc8UFtiJw3L nX0I8mtBemEclNfoQO+O2UHCivupZDDQgFoJi40Y75GU8eG3eTIEX7VOdpDv6y4Irk 2T1OWMIVzW7tw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D996CC5516F; Fri, 31 Jul 2026 17:44:09 +0000 (UTC) From: Bryam Vargas via B4 Relay Date: Fri, 31 Jul 2026 12:44:09 -0500 Subject: [PATCH 1/4] selinux: do not cancel a policy conversion that never started Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-b4-disp-d32e997b-v1-1-0341d038ee47@proton.me> References: <20260731-b4-disp-d32e997b-v1-0-0341d038ee47@proton.me> In-Reply-To: <20260731-b4-disp-d32e997b-v1-0-0341d038ee47@proton.me> To: Paul Moore , Stephen Smalley Cc: linux-kernel@vger.kernel.org, Ondrej Mosnacek , Kees Cook , selinux@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1785519848; l=1563; i=hexlabsecurity@proton.me; s=default; h=from:subject:message-id; bh=9Qq8XJedLiodysrUmiyu10hH6TBgjvkDd7Iu7+OmmI4=; b=NUCyDDPzA4NIDI3YaWpAh9+dO4rxlHCk0xPk72BtxXUpO72Odon7DAmg7Z7bg1req4rRK7fHx gQPQrKcumabCK6mMKbFuwvFY1n1AgvcLuY1JBX/FOLjXmjDEpf1gQH5 X-Developer-Key: i=hexlabsecurity@proton.me; a=ed25519; pk=xw1AhCtQdvuoQc+bOQIYy9o8G++cp4/VniI2G/tc3G8= X-Endpoint-Received: by B4 Relay for hexlabsecurity@proton.me/default with auth_id=893 X-Original-From: Bryam Vargas Reply-To: hexlabsecurity@proton.me From: Bryam Vargas sel_write_load() calls selinux_policy_cancel() when sel_make_policy_nodes() fails, and that helper dereferences the outgoing policy to cancel its sidtab conversion. On the first policy load there is no outgoing policy: security_load_policy() returns early for that case, before it converts anything, and state->policy is still NULL. A first load that fails while building the selinuxfs tree therefore takes a NULL dereference in selinux_policy_cancel(), reached from a write(2) to /sys/fs/selinux/load. Skip the cancel when there is no old policy, mirroring the check security_load_policy() already makes before it converts. Fixes: 02a52c5c8c3b ("selinux: move policy commit after updating selinuxfs") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas Acked-by: Stephen Smalley --- security/selinux/ss/services.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 2d828548f3db..90e81186cb2e 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2221,7 +2221,9 @@ void selinux_policy_cancel(struct selinux_load_state = *load_state) oldpolicy =3D rcu_dereference_protected(state->policy, lockdep_is_held(&state->policy_mutex)); =20 - sidtab_cancel_convert(oldpolicy->sidtab); + /* a first load has no outgoing policy and converted nothing */ + if (oldpolicy) + sidtab_cancel_convert(oldpolicy->sidtab); selinux_policy_free(load_state->policy); kfree(load_state->convert_data); } --=20 2.55.0 From nobody Fri Oct 2 12:22:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF5AD449B3C; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785519850; cv=none; b=MRRRj3a4v21/WPb5FgaXfDEdqUdfnsfZyQn+zt1YpQBOKFtv0d2zB9fmQm4vR2qKG5rGUssQjm9fuV3Og1lPLvpvdPQp+RoWsZzNrokxoSMfZZ4Li83qTnOGECJtgIU8ImnZSEC8WUGkY9GhuXz742E1jEWELmXQcQQNvQDfr90= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785519850; c=relaxed/simple; bh=ImwqTOGTJQJMsLawFHNrKEQOeVF1OAhdccY27ZoGqns=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ERDi3fKGjjWXnbmS33m3aphvGoQQiWvTnJgTE3P9YoPOLhBLnD8BORt4rgErWcJs0GjrPRnOHpB61ko/DpJqupiRHqwca3QYQ/ETizzGuWFFaGqSMweww2oorHuQ9ovG6MHlHTGRYG5ZmaD3iy9M/zRZWr6/4rMBPntirGytYpQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Dox+y90x; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Dox+y90x" Received: by smtp.kernel.org (Postfix) with ESMTPS id 137BDC2BCFA; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785519850; bh=ImwqTOGTJQJMsLawFHNrKEQOeVF1OAhdccY27ZoGqns=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Dox+y90xeuGTtUl0UPL1Kh6fnMahYG0i+i0RuocQPqzm58jfk57rAhqDHEhiSdkKo Lx3F/vF7qfdOZrJ/hnNlc0j5Vsu4vD4v+pk0/3IEJNwRH4yVsPrZbSGjZHccBEaBdQ H5vE5yjDeG0X+9sprB6E+jmsgDQBgqn4hP9NrqYI8pwcpaz2ZrPgQU8lgnsnsrsSUX f+bimCdhjCeEdvy8T9TGI505ojh4bC/B3tE+PKCTTqRLgfLfNBssMIZJt1BTLBbT3N /UOi5/dYsNuBUrZWdFAK/l2B+wLIvFKBBScDBVmD3E2F+uGnJVJ0Zna5J/lzCEc3TQ nyoXcwPnimovg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7A21C5516D; Fri, 31 Jul 2026 17:44:09 +0000 (UTC) From: Bryam Vargas via B4 Relay Date: Fri, 31 Jul 2026 12:44:10 -0500 Subject: [PATCH 2/4] selinux: require a class's permission values to cover its permission count Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-b4-disp-d32e997b-v1-2-0341d038ee47@proton.me> References: <20260731-b4-disp-d32e997b-v1-0-0341d038ee47@proton.me> In-Reply-To: <20260731-b4-disp-d32e997b-v1-0-0341d038ee47@proton.me> To: Paul Moore , Stephen Smalley Cc: linux-kernel@vger.kernel.org, Ondrej Mosnacek , Kees Cook , selinux@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1785519848; l=5224; i=hexlabsecurity@proton.me; s=default; h=from:subject:message-id; bh=sQJ2gqN49C5jQUs9/rBGsVRQJs8Us0KlqrG3XBJiK64=; b=DTEfkF+Wqf4CV60SwDLmyG1JP4QEkvoncAf2i4m9jvfHWyzAVP/lJ8I5ii93ou5beevfp9xSv EtCLbS5VKbMBAH6+aleT0Qh3g7vpqdzMWc32rCmyPg1DK5ZVReV5iF6 X-Developer-Key: i=hexlabsecurity@proton.me; a=ed25519; pk=xw1AhCtQdvuoQc+bOQIYy9o8G++cp4/VniI2G/tc3G8= X-Endpoint-Received: by B4 Relay for hexlabsecurity@proton.me/default with auth_id=893 X-Original-From: Bryam Vargas Reply-To: hexlabsecurity@proton.me From: Bryam Vargas security_get_permissions() sizes an array by the class's permissions.nprim and fills it at value - 1, from the inherited common's permission table and then the class's own. A value no permission defines leaves a NULL that sel_make_perm_files() passes to d_alloc_name(), an oops inside sel_write_load() that strands selinux_state.policy_mutex and leaves every later load in uninterruptible sleep; two permissions sharing a value overwrite the first kstrdup(). Bounding each value by nprim catches neither, and neither would a count: the symbol table is keyed on the permission name, so duplicates pass. Track the values each permission table claims and require them to cover exactly what its count declares, rejecting a count no value can reach. Conforming policies are unaffected. Fixes: 55fcf09b3fe4 ("selinux: add support for querying object classes and = permissions from the running policy") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas Acked-by: Stephen Smalley --- security/selinux/ss/policydb.c | 51 +++++++++++++++++++++++++++++++++++++-= ---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 69777e885ae7..d358200817bd 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -1154,7 +1154,18 @@ int str_read(char **strp, gfp_t flags, struct policy= _file *fp, u32 len) return 0; } =20 -static int perm_read(struct policydb *p, struct symtab *s, struct policy_f= ile *fp) +/* + * Bitmap of the permission values a symtab has claimed. Values are 1-bas= ed + * and bounded by SEL_VEC_MAX, the width of an access vector, so the whole= set + * fits in a u32 and the callers reject an nprim past that width. + */ +static u32 perm_claimed_mask(u32 nprim) +{ + return nprim ? U32_MAX >> (SEL_VEC_MAX - nprim) : 0; +} + +static int perm_read(struct policydb *p, struct symtab *s, + struct policy_file *fp, u32 *claimed) { char *key =3D NULL; struct perm_datum *perdatum; @@ -1178,6 +1189,10 @@ static int perm_read(struct policydb *p, struct symt= ab *s, struct policy_file *f /* indexes an nprim-sized array in security_get_permissions() */ if (perdatum->value > s->nprim) goto bad; + /* two permissions cannot share one slot of that array */ + if (*claimed & (1U << (perdatum->value - 1))) + goto bad; + *claimed |=3D 1U << (perdatum->value - 1); =20 rc =3D str_read(&key, GFP_KERNEL, fp, len); if (rc) @@ -1198,7 +1213,7 @@ static int common_read(struct policydb *p, struct sym= tab *s, struct policy_file char *key =3D NULL; struct common_datum *comdatum; __le32 buf[4]; - u32 i, len, nel; + u32 i, len, nel, claimed =3D 0; int rc; =20 comdatum =3D kzalloc_obj(*comdatum); @@ -1225,17 +1240,28 @@ static int common_read(struct policydb *p, struct s= ymtab *s, struct policy_file if (rc) goto bad; comdatum->permissions.nprim =3D le32_to_cpu(buf[2]); + /* no permission value can reach a slot past SEL_VEC_MAX */ + rc =3D -EINVAL; + if (comdatum->permissions.nprim > SEL_VEC_MAX) + goto bad; =20 rc =3D str_read(&key, GFP_KERNEL, fp, len); if (rc) goto bad; =20 for (i =3D 0; i < nel; i++) { - rc =3D perm_read(p, &comdatum->permissions, fp); + rc =3D perm_read(p, &comdatum->permissions, fp, &claimed); if (rc) goto bad; } =20 + rc =3D -EINVAL; + if (claimed !=3D perm_claimed_mask(comdatum->permissions.nprim)) { + pr_err("SELinux: common %s does not define every permission it declares= \n", + key); + goto bad; + } + hash_eval(&comdatum->permissions.table, "common_permissions", key); =20 rc =3D symtab_insert(s, key, comdatum); @@ -1369,7 +1395,7 @@ static int class_read(struct policydb *p, struct symt= ab *s, struct policy_file * char *key =3D NULL; struct class_datum *cladatum; __le32 buf[6]; - u32 i, len, len2, ncons, nel, val; + u32 i, len, len2, ncons, nel, val, claimed =3D 0, inherited =3D 0; int rc; =20 cladatum =3D kzalloc_obj(*cladatum); @@ -1402,6 +1428,10 @@ static int class_read(struct policydb *p, struct sym= tab *s, struct policy_file * if (rc) goto bad; cladatum->permissions.nprim =3D le32_to_cpu(buf[3]); + /* no permission value can reach a slot past SEL_VEC_MAX */ + rc =3D -EINVAL; + if (cladatum->permissions.nprim > SEL_VEC_MAX) + goto bad; =20 ncons =3D le32_to_cpu(buf[5]); =20 @@ -1436,11 +1466,22 @@ static int class_read(struct policydb *p, struct sy= mtab *s, struct policy_file * } } for (i =3D 0; i < nel; i++) { - rc =3D perm_read(p, &cladatum->permissions, fp); + rc =3D perm_read(p, &cladatum->permissions, fp, &claimed); if (rc) goto bad; } =20 + /* the class's own permissions must claim the slots the common leaves */ + if (cladatum->comdatum) + inherited =3D cladatum->comdatum->permissions.nprim; + rc =3D -EINVAL; + if (claimed !=3D (perm_claimed_mask(cladatum->permissions.nprim) & + ~perm_claimed_mask(inherited))) { + pr_err("SELinux: class %s does not define every permission it declares\= n", + key); + goto bad; + } + hash_eval(&cladatum->permissions.table, "class_permissions", key); =20 rc =3D read_cons_helper(p, &cladatum->constraints, ncons, 0, fp); --=20 2.55.0 From nobody Fri Oct 2 12:22:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0AA244AB92; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785519851; cv=none; b=mSRHNBLA9QnHrSiazbaIl/MQ0X5mw3q6J9QVpVluqDgGX5x2ACzQQ1Ep4/Cj7z7/eDbUwYcQXB+SflmSxeT7WiQPxUPZMRRdCnmeKfsgHIkwqZYv3FRBAksBz4blAOyAU41CHE839yhaZiYJAJ1H8HHN2VRDuZyu34lu6M5/ynU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785519851; c=relaxed/simple; bh=jdHeH42NJK+sRNHUhRFHxkP9qChVfte4gNDC1Rcw0i4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BDx5w/MsAeY/NEynSdXvKWZJG6TOFc/jiMVxIUCxpoSxF4kSnaN5n+TbdVYzFeuwJfPBtX4YdWmrSA3JS8WIeS+lubb9gE0cIL3Blhanv2COKBmrkuDmgQviCzrY3+epJFutaA0YqdnF9mk5Q5bxbi1mFaBhLx2FPJ/a5O5RoWI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BdTcBwGC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BdTcBwGC" Received: by smtp.kernel.org (Postfix) with ESMTPS id 1D6FCC2BCFB; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785519850; bh=jdHeH42NJK+sRNHUhRFHxkP9qChVfte4gNDC1Rcw0i4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=BdTcBwGClXbwYxtNZmkECny1/nRGdATKk/AMMjvKGzQW/9ANHw1mqjpz71Y0fNpVh QzT26XXQ9yA6nbzTzNotDse31KuULwjyPB6+N8o8IiYoFi5Xi0QRtgzfnF+GWI/saH CJiv1CqGn9O8WgkAufRkWVTHNIFqiJHEMJhx6QkOUchpfArwlF8ubY7Y6jGMpIOGJI kwGj3dRkTRE1jzSqHFBpX7VavT8wap00XF8ubYTRJqJrCeZr5+PMXlqjUWNW7Z+5i0 uCYtI1B5/FViYCnusTOFa6S8xeU52lWqtDSKDR8jQq4vtRpjv3ZtFvha6QHm29Xdi4 ZIEKBErQI711A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 009F5C55175; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) From: Bryam Vargas via B4 Relay Date: Fri, 31 Jul 2026 12:44:11 -0500 Subject: [PATCH 3/4] selinux: reject an unclaimed class value in security_get_classes() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-b4-disp-d32e997b-v1-3-0341d038ee47@proton.me> References: <20260731-b4-disp-d32e997b-v1-0-0341d038ee47@proton.me> In-Reply-To: <20260731-b4-disp-d32e997b-v1-0-0341d038ee47@proton.me> To: Paul Moore , Stephen Smalley Cc: linux-kernel@vger.kernel.org, Ondrej Mosnacek , Kees Cook , selinux@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1785519848; l=2212; i=hexlabsecurity@proton.me; s=default; h=from:subject:message-id; bh=146rmnAfLEvFW4uw+zlgvifpJzRkQBhtNeevcrvrVxY=; b=75DlDjNX2pjUbExZ1Kf+vXP0AyfZVSOzdMKlZr7wbTah/wLkZaJIMQ5BcA7uc31mfFZ5/h4zP W17KLxQSHlHCGW3Cb3d6NgzU0UimsXtm8tWZQH6NZ8rdP9d4vfS44UI X-Developer-Key: i=hexlabsecurity@proton.me; a=ed25519; pk=xw1AhCtQdvuoQc+bOQIYy9o8G++cp4/VniI2G/tc3G8= X-Endpoint-Received: by B4 Relay for hexlabsecurity@proton.me/default with auth_id=893 X-Original-From: Bryam Vargas Reply-To: hexlabsecurity@proton.me From: Bryam Vargas security_get_classes() sizes an array by p_classes.nprim and fills it at value - 1, so a class value the policy never defines leaves a NULL. sel_make_classes() passes every entry to sel_make_dir(), reaching the same d_alloc_name() dereference as the permission array. The class symbol table is allowed to be sparse (policydb_class_isvalid() exists to absorb that), but this getter builds its own array straight from the hash table and has no such predicate. Fail the lookup when a value went unclaimed instead of handing out the NULL. Conforming policies define every class they declare and are unaffected. Fixes: 55fcf09b3fe4 ("selinux: add support for querying object classes and = permissions from the running policy") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas Acked-by: Stephen Smalley --- security/selinux/ss/services.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 90e81186cb2e..7afce975436e 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3304,6 +3304,7 @@ int security_get_classes(struct selinux_policy *polic= y, char ***classes, u32 *nclasses) { struct policydb *policydb; + u32 i; int rc; =20 policydb =3D &policy->policydb; @@ -3316,16 +3317,29 @@ int security_get_classes(struct selinux_policy *pol= icy, =20 rc =3D hashtab_map(&policydb->p_classes.table, get_classes_callback, *classes); - if (rc) { - u32 i; + if (rc) + goto err; =20 - for (i =3D 0; i < *nclasses; i++) - kfree((*classes)[i]); - kfree(*classes); + /* + * The class symtab may be sparse, which policydb_class_isvalid() exists + * to absorb; the callback fills this array by value, so an unclaimed + * one leaves a NULL that sel_make_classes() hands to sel_make_dir(). + */ + for (i =3D 0; i < *nclasses; i++) { + if (!(*classes)[i]) { + rc =3D -EINVAL; + goto err; + } } =20 out: return rc; + +err: + for (i =3D 0; i < *nclasses; i++) + kfree((*classes)[i]); + kfree(*classes); + return rc; } =20 static int get_permissions_callback(void *k, void *d, void *args) --=20 2.55.0 From nobody Fri Oct 2 12:22:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA51441A50A; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785519850; cv=none; b=cX/DGH1Fa2eojIHw7jIkstil602kHU0haxcCg6wOdh/YlcwEQ/uYEq/gc4zI7SGgqpOxCX1ssaAZGP6JlKX+yS3meBOdoW9UgXvyfYBK9M78VgWsjAsmnztbz1HJaQRgwkypjwWh0zGw42Bhvs9sLBU1Yn4V2RAiiE7zjElq3bE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785519850; c=relaxed/simple; bh=bFweYXHzDsjnKqwBBx2UMemvlHC1eJ4kYwCV3M57T3w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GNf+ULEFHX9h4pBY29RnHeO89ijxQYFTTqkkzRcmlDgvStcsbSV4Sr5ZqUEhTD+MmsNpQWEwipBDGcAGMpuYGW3ompX5ugbJXUqSHpqUN4Kfh5hyjViKxohNT9g5D6VKPKQki2/VYbW13fZwpiro/2YMXW4HQHrFCt0FaFLjboc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Wyi6G5Sw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Wyi6G5Sw" Received: by smtp.kernel.org (Postfix) with ESMTPS id 260DFC2BCFD; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785519850; bh=bFweYXHzDsjnKqwBBx2UMemvlHC1eJ4kYwCV3M57T3w=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Wyi6G5SwUsmpmRr50UURgk4a3EzEgzxb9AdHb/2Rw69H/b3nDoP6NIPAJaSwJD5ZZ rS/B3FPSv057DLN2v1c2ggCvMB5n/5au7RFtYHlKcKnNngXkTP15xMPeV9lzNzzxNV WMmto3sCdKtXnyvF8Jk1nAsLTCL3dd/1nGlyFlIBI5OCpHqauJJlWojjv+qeOSUcE3 80DV2ZyrzqYEYrotGs/K2vrVE7dirFDSb2fZYB+7kyCtkNdQCPrjbaex7X+v3bj1l9 Hl6cBCLkGldgWtW7mQ9ubC7iUS28MzXFzDjk/DNPtUZakmAbX9Lldanurtmnr7S16m iZbhwrwsoSf7g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E575C55174; Fri, 31 Jul 2026 17:44:10 +0000 (UTC) From: Bryam Vargas via B4 Relay Date: Fri, 31 Jul 2026 12:44:12 -0500 Subject: [PATCH 4/4] selinux: require every boolean value to be defined Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-b4-disp-d32e997b-v1-4-0341d038ee47@proton.me> References: <20260731-b4-disp-d32e997b-v1-0-0341d038ee47@proton.me> In-Reply-To: <20260731-b4-disp-d32e997b-v1-0-0341d038ee47@proton.me> To: Paul Moore , Stephen Smalley Cc: linux-kernel@vger.kernel.org, Ondrej Mosnacek , Kees Cook , selinux@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1785519848; l=2108; i=hexlabsecurity@proton.me; s=default; h=from:subject:message-id; bh=I7aNEIxlzRwFx8VoQh04N3ZU/iwunm3TR1TrNlfSSMw=; b=xlN1scXScpwCr94ODTYukby6eRZzCnJ4J8SLTAx69Wrc1Z/ByhoW6GiXq2lXmxnnxj/aTJpCM Huj0PC2hY5qA8pV25NA1wYbbzCA/Pv8ZfYRxXH7yKK9ErBS7rtk/qQb X-Developer-Key: i=hexlabsecurity@proton.me; a=ed25519; pk=xw1AhCtQdvuoQc+bOQIYy9o8G++cp4/VniI2G/tc3G8= X-Endpoint-Received: by B4 Relay for hexlabsecurity@proton.me/default with auth_id=893 X-Original-From: Bryam Vargas Reply-To: hexlabsecurity@proton.me From: Bryam Vargas p_bools.nprim comes from the policy image independently of how many booleans follow it, and cond_index_bool() fills bool_val_to_struct[] at value - 1, so a count larger than the values present leaves NULL entries. Every user of that array then walks it by index and dereferences each entry: cond_evaluate_expr() on the access-vector path, security_get_bools() and security_get_bool_value() behind selinuxfs, and security_set_bools(). A sparse class value is absorbed by policydb_class_isvalid() and its siblings; booleans have no such predicate, and no consumer that could use one. Reject a boolean value that no boolean defines, once, where the array is built. Conforming policies define every boolean they declare and are unaffected. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas Acked-by: Stephen Smalley --- security/selinux/ss/policydb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index d358200817bd..d88713201be9 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -719,6 +719,7 @@ static inline void symtab_hash_eval(struct symtab *s) static int policydb_index(struct policydb *p) { int i, rc; + u32 v; =20 if (p->mls_enabled) pr_debug( @@ -769,6 +770,24 @@ static int policydb_index(struct policydb *p) if (rc) goto out; } + + /* + * A sparse class value is absorbed by policydb_class_isvalid() and + * its siblings, but no such predicate exists for booleans: every + * user of bool_val_to_struct[] walks it by index and dereferences + * each entry -- cond_evaluate_expr(), the two getters and + * security_set_bools() -- so an unclaimed one has no consumer that + * can tolerate it. + */ + for (v =3D 0; v < p->p_bools.nprim; v++) { + if (!p->bool_val_to_struct[v]) { + pr_err("SELinux: boolean %u is declared but not defined\n", + v + 1); + rc =3D -EINVAL; + goto out; + } + } + rc =3D 0; out: return rc; --=20 2.55.0