From: Greg Kroah-Hartman Date: Wed, 21 Feb 2024 10:45:13 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.19.307~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0de5fd1373cdd43ea368842a3a78f28aad696564;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: lsm-new-security_file_ioctl_compat-hook.patch --- diff --git a/queue-4.19/lsm-new-security_file_ioctl_compat-hook.patch b/queue-4.19/lsm-new-security_file_ioctl_compat-hook.patch new file mode 100644 index 00000000000..d7b07bac4ae --- /dev/null +++ b/queue-4.19/lsm-new-security_file_ioctl_compat-hook.patch @@ -0,0 +1,208 @@ +From f1bb47a31dff6d4b34fb14e99850860ee74bb003 Mon Sep 17 00:00:00 2001 +From: Alfred Piccioni +Date: Tue, 19 Dec 2023 10:09:09 +0100 +Subject: lsm: new security_file_ioctl_compat() hook + +From: Alfred Piccioni + +commit f1bb47a31dff6d4b34fb14e99850860ee74bb003 upstream. + +Some ioctl commands do not require ioctl permission, but are routed to +other permissions such as FILE_GETATTR or FILE_SETATTR. This routing is +done by comparing the ioctl cmd to a set of 64-bit flags (FS_IOC_*). + +However, if a 32-bit process is running on a 64-bit kernel, it emits +32-bit flags (FS_IOC32_*) for certain ioctl operations. These flags are +being checked erroneously, which leads to these ioctl operations being +routed to the ioctl permission, rather than the correct file +permissions. + +This was also noted in a RED-PEN finding from a while back - +"/* RED-PEN how should LSM module know it's handling 32bit? */". + +This patch introduces a new hook, security_file_ioctl_compat(), that is +called from the compat ioctl syscall. All current LSMs have been changed +to support this hook. + +Reviewing the three places where we are currently using +security_file_ioctl(), it appears that only SELinux needs a dedicated +compat change; TOMOYO and SMACK appear to be functional without any +change. + +Cc: stable@vger.kernel.org +Fixes: 0b24dcb7f2f7 ("Revert "selinux: simplify ioctl checking"") +Signed-off-by: Alfred Piccioni +Reviewed-by: Stephen Smalley +[PM: subject tweak, line length fixes, and alignment corrections] +Signed-off-by: Paul Moore +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + fs/compat_ioctl.c | 3 +-- + include/linux/lsm_hooks.h | 9 +++++++++ + include/linux/security.h | 9 +++++++++ + security/security.c | 17 +++++++++++++++++ + security/selinux/hooks.c | 28 ++++++++++++++++++++++++++++ + security/smack/smack_lsm.c | 1 + + security/tomoyo/tomoyo.c | 1 + + 7 files changed, 66 insertions(+), 2 deletions(-) + +--- a/fs/compat_ioctl.c ++++ b/fs/compat_ioctl.c +@@ -1370,8 +1370,7 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned i + if (!f.file) + goto out; + +- /* RED-PEN how should LSM module know it's handling 32bit? */ +- error = security_file_ioctl(f.file, cmd, arg); ++ error = security_file_ioctl_compat(f.file, cmd, arg); + if (error) + goto out_fput; + +--- a/include/linux/lsm_hooks.h ++++ b/include/linux/lsm_hooks.h +@@ -466,6 +466,12 @@ + * simple integer value. When @arg represents a user space pointer, it + * should never be used by the security module. + * Return 0 if permission is granted. ++ * @file_ioctl_compat: ++ * @file contains the file structure. ++ * @cmd contains the operation to perform. ++ * @arg contains the operational arguments. ++ * Check permission for a compat ioctl operation on @file. ++ * Return 0 if permission is granted. + * @mmap_addr : + * Check permissions for a mmap operation at @addr. + * @addr contains virtual address that will be used for the operation. +@@ -1563,6 +1569,8 @@ union security_list_options { + void (*file_free_security)(struct file *file); + int (*file_ioctl)(struct file *file, unsigned int cmd, + unsigned long arg); ++ int (*file_ioctl_compat)(struct file *file, unsigned int cmd, ++ unsigned long arg); + int (*mmap_addr)(unsigned long addr); + int (*mmap_file)(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags); +@@ -1861,6 +1869,7 @@ struct security_hook_heads { + struct hlist_head file_alloc_security; + struct hlist_head file_free_security; + struct hlist_head file_ioctl; ++ struct hlist_head file_ioctl_compat; + struct hlist_head mmap_addr; + struct hlist_head mmap_file; + struct hlist_head file_mprotect; +--- a/include/linux/security.h ++++ b/include/linux/security.h +@@ -322,6 +322,8 @@ int security_file_permission(struct file + int security_file_alloc(struct file *file); + void security_file_free(struct file *file); + int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ++int security_file_ioctl_compat(struct file *file, unsigned int cmd, ++ unsigned long arg); + int security_mmap_file(struct file *file, unsigned long prot, + unsigned long flags); + int security_mmap_addr(unsigned long addr); +@@ -833,6 +835,13 @@ static inline int security_file_ioctl(st + { + return 0; + } ++ ++static inline int security_file_ioctl_compat(struct file *file, ++ unsigned int cmd, ++ unsigned long arg) ++{ ++ return 0; ++} + + static inline int security_mmap_file(struct file *file, unsigned long prot, + unsigned long flags) +--- a/security/security.c ++++ b/security/security.c +@@ -890,6 +890,23 @@ int security_file_ioctl(struct file *fil + return call_int_hook(file_ioctl, 0, file, cmd, arg); + } + ++/** ++ * security_file_ioctl_compat() - Check if an ioctl is allowed in compat mode ++ * @file: associated file ++ * @cmd: ioctl cmd ++ * @arg: ioctl arguments ++ * ++ * Compat version of security_file_ioctl() that correctly handles 32-bit ++ * processes running on 64-bit kernels. ++ * ++ * Return: Returns 0 if permission is granted. ++ */ ++int security_file_ioctl_compat(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ return call_int_hook(file_ioctl_compat, 0, file, cmd, arg); ++} ++ + static inline unsigned long mmap_prot(struct file *file, unsigned long prot) + { + /* +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -3709,6 +3709,33 @@ static int selinux_file_ioctl(struct fil + return error; + } + ++static int selinux_file_ioctl_compat(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ /* ++ * If we are in a 64-bit kernel running 32-bit userspace, we need to ++ * make sure we don't compare 32-bit flags to 64-bit flags. ++ */ ++ switch (cmd) { ++ case FS_IOC32_GETFLAGS: ++ cmd = FS_IOC_GETFLAGS; ++ break; ++ case FS_IOC32_SETFLAGS: ++ cmd = FS_IOC_SETFLAGS; ++ break; ++ case FS_IOC32_GETVERSION: ++ cmd = FS_IOC_GETVERSION; ++ break; ++ case FS_IOC32_SETVERSION: ++ cmd = FS_IOC_SETVERSION; ++ break; ++ default: ++ break; ++ } ++ ++ return selinux_file_ioctl(file, cmd, arg); ++} ++ + static int default_noexec; + + static int file_map_prot_check(struct file *file, unsigned long prot, int shared) +@@ -7054,6 +7081,7 @@ static struct security_hook_list selinux + LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), + LSM_HOOK_INIT(file_free_security, selinux_file_free_security), + LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), ++ LSM_HOOK_INIT(file_ioctl_compat, selinux_file_ioctl_compat), + LSM_HOOK_INIT(mmap_file, selinux_mmap_file), + LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), + LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect), +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -4737,6 +4737,7 @@ static struct security_hook_list smack_h + LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security), + LSM_HOOK_INIT(file_free_security, smack_file_free_security), + LSM_HOOK_INIT(file_ioctl, smack_file_ioctl), ++ LSM_HOOK_INIT(file_ioctl_compat, smack_file_ioctl), + LSM_HOOK_INIT(file_lock, smack_file_lock), + LSM_HOOK_INIT(file_fcntl, smack_file_fcntl), + LSM_HOOK_INIT(mmap_file, smack_mmap_file), +--- a/security/tomoyo/tomoyo.c ++++ b/security/tomoyo/tomoyo.c +@@ -516,6 +516,7 @@ static struct security_hook_list tomoyo_ + LSM_HOOK_INIT(path_rename, tomoyo_path_rename), + LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr), + LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl), ++ LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl), + LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod), + LSM_HOOK_INIT(path_chown, tomoyo_path_chown), + LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot), diff --git a/queue-4.19/series b/queue-4.19/series index a4db0196fc7..d935fc45c41 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -196,6 +196,6 @@ irqchip-irq-brcmstb-l2-add-write-memory-barrier-before-exit.patch pmdomain-core-move-the-unused-cleanup-to-a-_sync-initcall.patch revert-md-raid5-wait-for-md_sb_change_pending-in-rai.patch sched-membarrier-reduce-the-ability-to-hammer-on-sys_membarrier.patch -mm-memcontrol-decouple-reference-counting-from-page-accounting.patch nilfs2-fix-potential-bug-in-end_buffer_async_write.patch nilfs2-replace-warn_ons-for-invalid-dat-metadata-block-requests.patch +lsm-new-security_file_ioctl_compat-hook.patch