selinux: always fill AVC decision in avc_has_perm_noaudit()

avc_has_perm_noaudit() is documented to return a copy of the access
decision in @avd, but its early return for an empty requested permission
set leaves the buffer untouched.  All callers pass an uninitialized
stack variable and afterwards feed it to avc_audit(), and the inode hook
even stores it in the per-task decision cache.

Fill in a deny-all, audit-all decision, similar to avd_init(), so every
caller receives a defined value at no cost on the hot path.

Cc: stable@vger.kernel.org
Fixes: e6f2f381e4 ("selinux: replace BUG_ONs with WARN_ONs in avc.c")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
Christian Göttsche 2026-09-03 13:43:38 +02:00 committed by Paul Moore
parent df2908090c
commit 8861db3051

View File

@ -1149,8 +1149,11 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
u32 denied;
struct avc_node *node;
if (WARN_ON(!requested))
if (WARN_ON(!requested)) {
/* Provide a deny-all, audit-all decision to the caller. */
*avd = (struct av_decision){ .auditdeny = 0xffffffff };
return -EACCES;
}
rcu_read_lock();
node = avc_lookup(ssid, tsid, tclass);