Commit ff7ec8dc authored by wangzijie's avatar wangzijie Committed by Andrew Morton
Browse files

proc: use the same treatment to check proc_lseek as ones for proc_read_iter et.al

Check pde->proc_ops->proc_lseek directly may cause UAF in rmmod scenario. 
It's a gap in proc_reg_open() after commit 654b33ad("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: 3f61631d ("take care to handle NULL ->proc_lseek()")
Signed-off-by: default avatarwangzijie <wangzijie1@honor.com>
Reviewed-by: default avatarAlexey 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: default avatarAndrew Morton <akpm@linux-foundation.org>
parent a6fde7ad
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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,
+1 −1
Original line number Diff line number Diff line
@@ -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)) {
+5 −0
Original line number Diff line number Diff line
@@ -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);

+1 −0
Original line number Diff line number Diff line
@@ -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 {