summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMickaël Salaün <mic@digikod.net>2026-09-10 16:48:33 +0200
committerPaul Moore <paul@paul-moore.com>2026-09-14 16:41:53 -0400
commiteb221044db2d687be7253cd203df4ee648232c3b (patch)
tree25fd3ff839b210ad47c4350c1c57cc2adcc97d8b
parent7dfacee94c9cac9e62149791f91ce7777d6d870e (diff)
downloadlinux-next-eb221044db2d687be7253cd203df4ee648232c3b.tar.gz
linux-next-eb221044db2d687be7253cd203df4ee648232c3b.zip
lsm: Preserve full ioctl commands in audit records
Ioctl commands are unsigned int values, with their encoded direction and size in the upper 16 bits. However, struct lsm_ioctlop_audit keeps only a u16, and the common audit formatter uses %hx. This logs 0xc00ffeee as 0xfeee and makes distinct commands with matching low 16 bits indistinguishable. Change cmd to unsigned int and use %x. Pass the full command through ioctl_has_perm() as well. Its driver and xperm values remain u8 values derived from the same low 16 bits, so SELinux enforcement does not change. Commands that fit in 16 bits keep the same audit text. Cc: Jeff Vander Stoep <jeffv@google.com> Cc: Paul Moore <paul@paul-moore.com> Fixes: 671a2781ff01 ("security: add ioctl specific auditing to lsm_audit") Signed-off-by: Mickaël Salaün <mic@digikod.net> Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r--include/linux/lsm_audit.h2
-rw-r--r--security/lsm_audit.c2
-rw-r--r--security/selinux/hooks.c6
3 files changed, 5 insertions, 5 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 526a8e7471c8..5cf0b4795065 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -44,7 +44,7 @@ struct lsm_network_audit {
struct lsm_ioctlop_audit {
struct path path;
- u16 cmd;
+ unsigned int cmd;
};
struct lsm_ibpkey_audit {
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 29116ef2986b..955b2e7b2c8e 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -231,7 +231,7 @@ void audit_log_lsm_data(struct audit_buffer *ab,
audit_log_format(ab, " ino=%llu", inode->i_ino);
}
- audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
+ audit_log_format(ab, " ioctlcmd=0x%x", a->u.op->cmd);
break;
}
case LSM_AUDIT_DATA_DENTRY: {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 967984d0af30..368f9dacdcef 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3866,7 +3866,7 @@ static int selinux_backing_file_alloc(struct file *backing_file,
* operation to an inode.
*/
static int ioctl_has_perm(const struct cred *cred, struct file *file,
- u32 requested, u16 cmd)
+ u32 requested, unsigned int cmd)
{
struct common_audit_data ad;
struct file_security_struct *fsec = selinux_file(file);
@@ -3937,14 +3937,14 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
case FIOCLEX:
case FIONCLEX:
if (!selinux_policycap_ioctl_skip_cloexec())
- error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
+ error = ioctl_has_perm(cred, file, FILE__IOCTL, cmd);
break;
/* default case assumes that the command will go
* to the file's ioctl() function.
*/
default:
- error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
+ error = ioctl_has_perm(cred, file, FILE__IOCTL, cmd);
}
return error;
}