fsnotify: call fsnotify_parent in perm events
fsnotify perm events do not call fsnotify parent. That means you cannot register a perm event on a directory and enforce permissions on all inodes in that directory. This patch fixes that situation. Signed-off-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
Родитель
ff8bcbd03d
Коммит
52420392c8
|
@ -84,16 +84,17 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
|
|||
}
|
||||
|
||||
/* Notify this dentry's parent about a child's events. */
|
||||
void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||
int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||
{
|
||||
struct dentry *parent;
|
||||
struct inode *p_inode;
|
||||
int ret = 0;
|
||||
|
||||
if (!dentry)
|
||||
dentry = path->dentry;
|
||||
|
||||
if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
parent = dget_parent(dentry);
|
||||
p_inode = parent->d_inode;
|
||||
|
@ -106,14 +107,16 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
|||
mask |= FS_EVENT_ON_CHILD;
|
||||
|
||||
if (path)
|
||||
fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
|
||||
dentry->d_name.name, 0);
|
||||
ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
|
||||
dentry->d_name.name, 0);
|
||||
else
|
||||
fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
|
||||
dentry->d_name.name, 0);
|
||||
ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
|
||||
dentry->d_name.name, 0);
|
||||
}
|
||||
|
||||
dput(parent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__fsnotify_parent);
|
||||
|
||||
|
|
|
@ -26,12 +26,12 @@ static inline void fsnotify_d_instantiate(struct dentry *dentry,
|
|||
}
|
||||
|
||||
/* Notify this dentry's parent about a child's events. */
|
||||
static inline void fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||
static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||
{
|
||||
if (!dentry)
|
||||
dentry = path->dentry;
|
||||
|
||||
__fsnotify_parent(path, dentry, mask);
|
||||
return __fsnotify_parent(path, dentry, mask);
|
||||
}
|
||||
|
||||
/* simple call site for access decisions */
|
||||
|
@ -40,6 +40,7 @@ static inline int fsnotify_perm(struct file *file, int mask)
|
|||
struct path *path = &file->f_path;
|
||||
struct inode *inode = path->dentry->d_inode;
|
||||
__u32 fsnotify_mask = 0;
|
||||
int ret;
|
||||
|
||||
if (file->f_mode & FMODE_NONOTIFY)
|
||||
return 0;
|
||||
|
@ -52,6 +53,10 @@ static inline int fsnotify_perm(struct file *file, int mask)
|
|||
else
|
||||
BUG();
|
||||
|
||||
ret = fsnotify_parent(path, NULL, fsnotify_mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ struct fsnotify_mark {
|
|||
/* main fsnotify call to send events */
|
||||
extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
|
||||
const unsigned char *name, u32 cookie);
|
||||
extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
|
||||
extern int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
|
||||
extern void __fsnotify_inode_delete(struct inode *inode);
|
||||
extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
|
||||
extern u32 fsnotify_get_cookie(void);
|
||||
|
@ -433,8 +433,10 @@ static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int da
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||
{}
|
||||
static inline int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __fsnotify_inode_delete(struct inode *inode)
|
||||
{}
|
||||
|
|
Загрузка…
Ссылка в новой задаче