Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fanotify: introduce new event mask FAN_OPEN_EXEC_PERM

A new event mask FAN_OPEN_EXEC_PERM has been defined. This allows users
to receive events and grant access to files that are intending to be
opened for execution. Events of FAN_OPEN_EXEC_PERM type will be
generated when a file has been opened by using either execve(),
execveat() or uselib() system calls.

This acts in the same manner as previous permission event mask, meaning
that an access response is required from the user application in order
to permit any further operations on the file.

Signed-off-by: Matthew Bobrowski <mbobrowski@mbobrowski.org>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>

authored by

Matthew Bobrowski and committed by
Jan Kara
66917a31 a704bba5

+23 -11
+2 -1
fs/notify/fanotify/fanotify.c
··· 211 211 BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM); 212 212 BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR); 213 213 BUILD_BUG_ON(FAN_OPEN_EXEC != FS_OPEN_EXEC); 214 + BUILD_BUG_ON(FAN_OPEN_EXEC_PERM != FS_OPEN_EXEC_PERM); 214 215 215 - BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 11); 216 + BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 12); 216 217 217 218 mask = fanotify_group_event_mask(iter_info, mask, data, data_type); 218 219 if (!mask)
+1 -1
fs/notify/fsnotify.c
··· 401 401 { 402 402 int ret; 403 403 404 - BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 24); 404 + BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 25); 405 405 406 406 ret = init_srcu_struct(&fsnotify_mark_srcu); 407 407 if (ret)
+2 -1
include/linux/fanotify.h
··· 40 40 FAN_CLOSE | FAN_OPEN | FAN_OPEN_EXEC) 41 41 42 42 /* Events that require a permission response from user */ 43 - #define FANOTIFY_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM) 43 + #define FANOTIFY_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM | \ 44 + FAN_OPEN_EXEC_PERM) 44 45 45 46 /* Extra flags that may be reported with event or control handling of events */ 46 47 #define FANOTIFY_EVENT_FLAGS (FAN_EVENT_ON_CHILD | FAN_ONDIR)
+12 -5
include/linux/fsnotify.h
··· 40 40 return fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); 41 41 } 42 42 43 - /* simple call site for access decisions */ 43 + /* Simple call site for access decisions */ 44 44 static inline int fsnotify_perm(struct file *file, int mask) 45 45 { 46 + int ret; 46 47 const struct path *path = &file->f_path; 47 48 struct inode *inode = file_inode(file); 48 49 __u32 fsnotify_mask = 0; ··· 52 51 return 0; 53 52 if (!(mask & (MAY_READ | MAY_OPEN))) 54 53 return 0; 55 - if (mask & MAY_OPEN) 54 + if (mask & MAY_OPEN) { 56 55 fsnotify_mask = FS_OPEN_PERM; 57 - else if (mask & MAY_READ) 56 + 57 + if (file->f_flags & __FMODE_EXEC) { 58 + ret = fsnotify_path(inode, path, FS_OPEN_EXEC_PERM); 59 + 60 + if (ret) 61 + return ret; 62 + } 63 + } else if (mask & MAY_READ) { 58 64 fsnotify_mask = FS_ACCESS_PERM; 59 - else 60 - BUG(); 65 + } 61 66 62 67 return fsnotify_path(inode, path, fsnotify_mask); 63 68 }
+5 -3
include/linux/fsnotify_backend.h
··· 46 46 47 47 #define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */ 48 48 #define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */ 49 + #define FS_OPEN_EXEC_PERM 0x00040000 /* open/exec event in a permission hook */ 49 50 50 51 #define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */ 51 52 #define FS_ISDIR 0x40000000 /* event occurred against dir */ ··· 65 64 FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN |\ 66 65 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\ 67 66 FS_DELETE | FS_OPEN_PERM | FS_ACCESS_PERM | \ 68 - FS_OPEN_EXEC) 67 + FS_OPEN_EXEC | FS_OPEN_EXEC_PERM) 69 68 70 69 #define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO) 71 70 72 - #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM) 71 + #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | \ 72 + FS_OPEN_EXEC_PERM) 73 73 74 74 /* Events that can be reported to backends */ 75 75 #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ ··· 79 77 FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \ 80 78 FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \ 81 79 FS_OPEN_PERM | FS_ACCESS_PERM | FS_DN_RENAME | \ 82 - FS_OPEN_EXEC) 80 + FS_OPEN_EXEC | FS_OPEN_EXEC_PERM) 83 81 84 82 /* Extra flags that may be reported with event or control handling of events */ 85 83 #define ALL_FSNOTIFY_FLAGS (FS_EXCL_UNLINK | FS_ISDIR | FS_IN_ONESHOT | \
+1
include/uapi/linux/fanotify.h
··· 16 16 17 17 #define FAN_OPEN_PERM 0x00010000 /* File open in perm check */ 18 18 #define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ 19 + #define FAN_OPEN_EXEC_PERM 0x00040000 /* File open/exec in perm check */ 19 20 20 21 #define FAN_ONDIR 0x40000000 /* event occurred against dir */ 21 22