fanotify: if set by user unset FMODE_NONOTIFY before fsnotify_perm() is called
authorLino Sanfilippo <LinoSanfilippo@gmx.de>
Fri, 5 Nov 2010 16:05:27 +0000 (17:05 +0100)
committerEric Paris <eparis@redhat.com>
Tue, 7 Dec 2010 21:14:21 +0000 (16:14 -0500)
Unsetting FMODE_NONOTIFY in fsnotify_open() is too late, since fsnotify_perm()
is called before. If FMODE_NONOTIFY is set fsnotify_perm() will skip permission
checks, so a user can still disable permission checks by setting this flag
in an open() call.
This patch corrects this by unsetting the flag before fsnotify_perm is called.

Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Signed-off-by: Eric Paris <eparis@redhat.com>
fs/namei.c
include/linux/fsnotify.h

index 5362af9b73729905817a76b5c24a5b33c48d5ce7..4ff7ca530533b121763dbe3b415ad79b162a85fb 100644 (file)
@@ -1748,6 +1748,9 @@ struct file *do_filp_open(int dfd, const char *pathname,
        if (!(open_flag & O_CREAT))
                mode = 0;
 
+       /* Must never be set by userspace */
+       open_flag &= ~FMODE_NONOTIFY;
+
        /*
         * O_SYNC is implemented as __O_SYNC|O_DSYNC.  As many places only
         * check for O_DSYNC if the need any syncing at all we enforce it's
index 5c185fa27089f03b4e9194445ee7bfd842f125c6..b10bcdeaef768b2b0b123c4a6c862b3f5f6c0694 100644 (file)
@@ -235,9 +235,6 @@ static inline void fsnotify_open(struct file *file)
        if (S_ISDIR(inode->i_mode))
                mask |= FS_ISDIR;
 
-       /* FMODE_NONOTIFY must never be set from user */
-       file->f_mode &= ~FMODE_NONOTIFY;
-
        fsnotify_parent(path, NULL, mask);
        fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
 }