Merge patch series "Fix for huge faults regression"
Amir Goldstein <amir73il@gmail.com> says: The two Fix patches have been tested by Alex together and each one independently. I also verified that they pass the LTP inoityf/fanotify tests. * patches from https://lore.kernel.org/r/20250203223205.861346-1-amir73il@gmail.com: fsnotify: disable pre-content and permission events by default fsnotify: disable notification by default for all pseudo files fsnotify: use accessor to set FMODE_NONOTIFY_* Link: https://lore.kernel.org/r/20250203223205.861346-1-amir73il@gmail.com Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
commit
ec6164adc7
8 changed files with 54 additions and 15 deletions
|
@ -798,7 +798,7 @@ static int ptmx_open(struct inode *inode, struct file *filp)
|
|||
nonseekable_open(inode, filp);
|
||||
|
||||
/* We refuse fsnotify events on ptmx, since it's a shared resource */
|
||||
filp->f_mode |= FMODE_NONOTIFY;
|
||||
file_set_fsnotify_mode(filp, FMODE_NONOTIFY);
|
||||
|
||||
retval = tty_alloc_file(filp);
|
||||
if (retval)
|
||||
|
|
|
@ -194,6 +194,11 @@ static int init_file(struct file *f, int flags, const struct cred *cred)
|
|||
* refcount bumps we should reinitialize the reused file first.
|
||||
*/
|
||||
file_ref_init(&f->f_ref, 1);
|
||||
/*
|
||||
* Disable permission and pre-content events for all files by default.
|
||||
* They may be enabled later by file_set_fsnotify_mode_from_watchers().
|
||||
*/
|
||||
file_set_fsnotify_mode(f, FMODE_NONOTIFY_PERM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -375,7 +380,13 @@ struct file *alloc_file_pseudo(struct inode *inode, struct vfsmount *mnt,
|
|||
if (IS_ERR(file)) {
|
||||
ihold(inode);
|
||||
path_put(&path);
|
||||
return file;
|
||||
}
|
||||
/*
|
||||
* Disable all fsnotify events for pseudo files by default.
|
||||
* They may be enabled by caller with file_set_fsnotify_mode().
|
||||
*/
|
||||
file_set_fsnotify_mode(file, FMODE_NONOTIFY);
|
||||
return file;
|
||||
}
|
||||
EXPORT_SYMBOL(alloc_file_pseudo);
|
||||
|
@ -400,6 +411,11 @@ struct file *alloc_file_pseudo_noaccount(struct inode *inode,
|
|||
return file;
|
||||
}
|
||||
file_init_path(file, &path, fops);
|
||||
/*
|
||||
* Disable all fsnotify events for pseudo files by default.
|
||||
* They may be enabled by caller with file_set_fsnotify_mode().
|
||||
*/
|
||||
file_set_fsnotify_mode(file, FMODE_NONOTIFY);
|
||||
return file;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alloc_file_pseudo_noaccount);
|
||||
|
|
|
@ -648,7 +648,7 @@ EXPORT_SYMBOL_GPL(fsnotify);
|
|||
* Later, fsnotify permission hooks do not check if there are permission event
|
||||
* watches, but that there were permission event watches at open time.
|
||||
*/
|
||||
void file_set_fsnotify_mode(struct file *file)
|
||||
void file_set_fsnotify_mode_from_watchers(struct file *file)
|
||||
{
|
||||
struct dentry *dentry = file->f_path.dentry, *parent;
|
||||
struct super_block *sb = dentry->d_sb;
|
||||
|
@ -665,7 +665,7 @@ void file_set_fsnotify_mode(struct file *file)
|
|||
*/
|
||||
if (likely(!fsnotify_sb_has_priority_watchers(sb,
|
||||
FSNOTIFY_PRIO_CONTENT))) {
|
||||
file->f_mode |= FMODE_NONOTIFY_PERM;
|
||||
file_set_fsnotify_mode(file, FMODE_NONOTIFY_PERM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -676,7 +676,7 @@ void file_set_fsnotify_mode(struct file *file)
|
|||
if ((!d_is_dir(dentry) && !d_is_reg(dentry)) ||
|
||||
likely(!fsnotify_sb_has_priority_watchers(sb,
|
||||
FSNOTIFY_PRIO_PRE_CONTENT))) {
|
||||
file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
|
||||
file_set_fsnotify_mode(file, FMODE_NONOTIFY | FMODE_NONOTIFY_PERM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -686,19 +686,25 @@ void file_set_fsnotify_mode(struct file *file)
|
|||
*/
|
||||
mnt_mask = READ_ONCE(real_mount(file->f_path.mnt)->mnt_fsnotify_mask);
|
||||
if (unlikely(fsnotify_object_watched(d_inode(dentry), mnt_mask,
|
||||
FSNOTIFY_PRE_CONTENT_EVENTS)))
|
||||
FSNOTIFY_PRE_CONTENT_EVENTS))) {
|
||||
/* Enable pre-content events */
|
||||
file_set_fsnotify_mode(file, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Is parent watching for pre-content events on this file? */
|
||||
if (dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED) {
|
||||
parent = dget_parent(dentry);
|
||||
p_mask = fsnotify_inode_watches_children(d_inode(parent));
|
||||
dput(parent);
|
||||
if (p_mask & FSNOTIFY_PRE_CONTENT_EVENTS)
|
||||
if (p_mask & FSNOTIFY_PRE_CONTENT_EVENTS) {
|
||||
/* Enable pre-content events */
|
||||
file_set_fsnotify_mode(file, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Nobody watching for pre-content events from this file */
|
||||
file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
|
||||
file_set_fsnotify_mode(file, FMODE_NONOTIFY | FMODE_NONOTIFY_PERM);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
11
fs/open.c
11
fs/open.c
|
@ -905,7 +905,8 @@ static int do_dentry_open(struct file *f,
|
|||
f->f_sb_err = file_sample_sb_err(f);
|
||||
|
||||
if (unlikely(f->f_flags & O_PATH)) {
|
||||
f->f_mode = FMODE_PATH | FMODE_OPENED | FMODE_NONOTIFY;
|
||||
f->f_mode = FMODE_PATH | FMODE_OPENED;
|
||||
file_set_fsnotify_mode(f, FMODE_NONOTIFY);
|
||||
f->f_op = &empty_fops;
|
||||
return 0;
|
||||
}
|
||||
|
@ -935,10 +936,10 @@ static int do_dentry_open(struct file *f,
|
|||
|
||||
/*
|
||||
* Set FMODE_NONOTIFY_* bits according to existing permission watches.
|
||||
* If FMODE_NONOTIFY was already set for an fanotify fd, this doesn't
|
||||
* change anything.
|
||||
* If FMODE_NONOTIFY mode was already set for an fanotify fd or for a
|
||||
* pseudo file, this call will not change the mode.
|
||||
*/
|
||||
file_set_fsnotify_mode(f);
|
||||
file_set_fsnotify_mode_from_watchers(f);
|
||||
error = fsnotify_open_perm(f);
|
||||
if (error)
|
||||
goto cleanup_all;
|
||||
|
@ -1122,7 +1123,7 @@ struct file *dentry_open_nonotify(const struct path *path, int flags,
|
|||
if (!IS_ERR(f)) {
|
||||
int error;
|
||||
|
||||
f->f_mode |= FMODE_NONOTIFY;
|
||||
file_set_fsnotify_mode(f, FMODE_NONOTIFY);
|
||||
error = vfs_open(path, f);
|
||||
if (error) {
|
||||
fput(f);
|
||||
|
|
|
@ -960,6 +960,12 @@ int create_pipe_files(struct file **res, int flags)
|
|||
res[1] = f;
|
||||
stream_open(inode, res[0]);
|
||||
stream_open(inode, res[1]);
|
||||
/*
|
||||
* Disable permission and pre-content events, but enable legacy
|
||||
* inotify events for legacy users.
|
||||
*/
|
||||
file_set_fsnotify_mode(res[0], FMODE_NONOTIFY_PERM);
|
||||
file_set_fsnotify_mode(res[1], FMODE_NONOTIFY_PERM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,6 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
|
|||
#define FMODE_FSNOTIFY_HSM(mode) 0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Attribute flags. These should be or-ed together to figure out what
|
||||
* has been changed!
|
||||
|
@ -3140,6 +3139,12 @@ static inline void exe_file_allow_write_access(struct file *exe_file)
|
|||
allow_write_access(exe_file);
|
||||
}
|
||||
|
||||
static inline void file_set_fsnotify_mode(struct file *file, fmode_t mode)
|
||||
{
|
||||
file->f_mode &= ~FMODE_FSNOTIFY_MASK;
|
||||
file->f_mode |= mode;
|
||||
}
|
||||
|
||||
static inline bool inode_is_open_for_write(const struct inode *inode)
|
||||
{
|
||||
return atomic_read(&inode->i_writecount) > 0;
|
||||
|
|
|
@ -129,7 +129,7 @@ static inline int fsnotify_file(struct file *file, __u32 mask)
|
|||
|
||||
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
|
||||
|
||||
void file_set_fsnotify_mode(struct file *file);
|
||||
void file_set_fsnotify_mode_from_watchers(struct file *file);
|
||||
|
||||
/*
|
||||
* fsnotify_file_area_perm - permission hook before access to file range
|
||||
|
@ -213,7 +213,7 @@ static inline int fsnotify_open_perm(struct file *file)
|
|||
}
|
||||
|
||||
#else
|
||||
static inline void file_set_fsnotify_mode(struct file *file)
|
||||
static inline void file_set_fsnotify_mode_from_watchers(struct file *file)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -479,6 +479,11 @@ struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
|
|||
sock->file = file;
|
||||
file->private_data = sock;
|
||||
stream_open(SOCK_INODE(sock), file);
|
||||
/*
|
||||
* Disable permission and pre-content events, but enable legacy
|
||||
* inotify events for legacy users.
|
||||
*/
|
||||
file_set_fsnotify_mode(file, FMODE_NONOTIFY_PERM);
|
||||
return file;
|
||||
}
|
||||
EXPORT_SYMBOL(sock_alloc_file);
|
||||
|
|
Loading…
Add table
Reference in a new issue