]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
proc: use the same treatment to check proc_lseek as ones for proc_read_iter et.al
authorwangzijie <wangzijie1@honor.com>
Sat, 7 Jun 2025 02:13:53 +0000 (10:13 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Thu, 10 Jul 2025 05:42:01 +0000 (22:42 -0700)
Check pde->proc_ops->proc_lseek directly may cause UAF in rmmod scenario.
It's a gap in proc_reg_open() after commit 654b33ada4ab("proc: fix UAF in
proc_get_inode()").  Followed by AI Viro's suggestion, fix it in same
manner.

Link: https://lkml.kernel.org/r/20250607021353.1127963-1-wangzijie1@honor.com
Fixes: 3f61631d47f1 ("take care to handle NULL ->proc_lseek()")
Signed-off-by: wangzijie <wangzijie1@honor.com>
Reviewed-by: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
Cc: Kirill A. Shuemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/proc/generic.c
fs/proc/inode.c
fs/proc/internal.h
include/linux/proc_fs.h

index a3e22803cddf2daab36a3e2dcc9e10c67282b9b4..e0e50914ab25f208b5a8fb2ea426a7501bc13368 100644 (file)
@@ -569,6 +569,8 @@ static void pde_set_flags(struct proc_dir_entry *pde)
        if (pde->proc_ops->proc_compat_ioctl)
                pde->flags |= PROC_ENTRY_proc_compat_ioctl;
 #endif
+       if (pde->proc_ops->proc_lseek)
+               pde->flags |= PROC_ENTRY_proc_lseek;
 }
 
 struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
index 3604b616311c27a0ed1d91d05f1569cc2523cdc0..129490151be147dbdd3667d10fb8b85b62380264 100644 (file)
@@ -473,7 +473,7 @@ static int proc_reg_open(struct inode *inode, struct file *file)
        typeof_member(struct proc_ops, proc_open) open;
        struct pde_opener *pdeo;
 
-       if (!pde->proc_ops->proc_lseek)
+       if (!pde_has_proc_lseek(pde))
                file->f_mode &= ~FMODE_LSEEK;
 
        if (pde_is_permanent(pde)) {
index 96122e91c64597b01b9ab0a8f76c7fc7f9efe0ca..3d48ffe72583a1a2ed812684d40a0d1a7287ba8d 100644 (file)
@@ -99,6 +99,11 @@ static inline bool pde_has_proc_compat_ioctl(const struct proc_dir_entry *pde)
 #endif
 }
 
+static inline bool pde_has_proc_lseek(const struct proc_dir_entry *pde)
+{
+       return pde->flags & PROC_ENTRY_proc_lseek;
+}
+
 extern struct kmem_cache *proc_dir_entry_cache;
 void pde_free(struct proc_dir_entry *pde);
 
index ea62201c74c4020121225f4ec341341b7a025bbc..703d0c76cc9a0aa90da723b09d267d063768d529 100644 (file)
@@ -27,6 +27,7 @@ enum {
 
        PROC_ENTRY_proc_read_iter       = 1U << 1,
        PROC_ENTRY_proc_compat_ioctl    = 1U << 2,
+       PROC_ENTRY_proc_lseek           = 1U << 3,
 };
 
 struct proc_ops {