Without this patch fanotify_init does not validate the value passed in event_f_flags.
When a fanotify event is read from the fanotify file descriptor a new file descriptor is created where file.f_flags = event_f_flags. Internal and external open flags are stored together in field f_flags of struct file. Hence, an application might create file descriptors with internal flags like FMODE_EXEC, FMODE_NOCMTIME set. With the patch the value of event_f_flags is checked. Only external open flags are allowed. When specifying an invalid value error EINVAL is returned. Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de> --- fs/notify/fanotify/fanotify_user.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 4e565c8..3e456d7 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -25,6 +25,21 @@ #define FANOTIFY_DEFAULT_MAX_MARKS 8192 #define FANOTIFY_DEFAULT_MAX_LISTENERS 128 +/* + * All flags that may be specified in parameter event_f_flags of fanotify_init. + * + * Internal and external open flags are stored together in field f_flags of + * struct file. Only external open flags shall be allowed in event_f_flags. + * Internal flags like FMODE_EXEC shall be excluded. + */ +#define FANOTIFY_INIT_ALL_EVENT_F_FLAGS ( \ + O_RDONLY | O_WRONLY | O_RDWR | \ + O_CREAT | O_EXCL | O_NOCTTY | \ + O_TRUNC | O_APPEND | O_NONBLOCK | \ + __O_SYNC | O_DSYNC | FASYNC | \ + O_DIRECT | O_LARGEFILE | O_DIRECTORY | \ + O_NOFOLLOW | O_NOATIME | O_CLOEXEC | \ + O_PATH | __O_TMPFILE | O_NDELAY ) extern const struct fsnotify_ops fanotify_fsnotify_ops; static struct kmem_cache *fanotify_mark_cache __read_mostly; @@ -669,6 +684,9 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) if (flags & ~FAN_ALL_INIT_FLAGS) return -EINVAL; + if (event_f_flags & ~FANOTIFY_INIT_ALL_EVENT_F_FLAGS) + return -EINVAL; + user = get_current_user(); if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) { free_uid(user); -- 1.9.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/