Hello, On Monday, July 16, 2018 11:26:53 AM EDT Jan Kara wrote: > On Mon 16-07-18 18:50:11, Matthew Bobrowski wrote: > > Currently, the fanotify API does not provide a means for user space > > programs to register and receive events specifically when a file has been > > opened with the intent to be executed. Two new event flags FAN_EXEC and > > FAN_EXEC_PERM have been introduced to the fanotify API along with updates > > to the generic filesystem notification hooks fsnotify_open and > > fsnotify_perm in order to support this capability. > > > > Signed-off-by: Matthew Bobrowski <mbobrowski@xxxxxxxxxxxxxx> > > I miss one important part in this changelog: Why do you need this feature? > Monitoring for read would be enough after all... There are several reasons that I can think of. There are lots of file accesses. It is possible to guess which one is the beginning of an execve, but you really don't know. Apps can be started in so many ways. They can be run from the runtime linker, they have LD_PRELOAD, they can have an unexpected interpreter, they can be statically linked, they can be a script which may present a new pattern of file accesses. With all the variations in how programs can start up, it would be nice to have one anchor that unambiguously says we are overlaying this pid with a whole new app and forget everything you knew about the pid. And the access pattern can be accurately watched because we always have a marker to start the sequence. Hope this helps... -Steve > > The proposed changes have been tested against Linus' mainline source tree > > along with testing them against stable kernel releases 4.17.4, 4.17.5 and > > 4.17.6. > > > > --- > > > > diff --git a/fs/notify/fanotify/fanotify.c > > b/fs/notify/fanotify/fanotify.c > > index f90842efea13..4882706e2188 100644 > > --- a/fs/notify/fanotify/fanotify.c > > +++ b/fs/notify/fanotify/fanotify.c > > @@ -197,6 +197,8 @@ static int fanotify_handle_event(struct > > fsnotify_group > > *group, > > BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM); > > BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM); > > BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR); > > + BUILD_BUG_ON(FAN_EXEC != FS_EXEC); > > + BUILD_BUG_ON(FAN_EXEC_PERM != FS_EXEC_PERM); > > > > if (!fanotify_should_send_event(iter_info, mask, data, data_type)) > > return 0; > > diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c > > index f174397b63a0..ef5d3eca2e62 100644 > > --- a/fs/notify/fsnotify.c > > +++ b/fs/notify/fsnotify.c > > @@ -393,7 +393,7 @@ static __init int fsnotify_init(void) > > { > > int ret; > > > > - BUG_ON(hweight32(ALL_FSNOTIFY_EVENTS) != 23); > > + BUG_ON(hweight32(ALL_FSNOTIFY_EVENTS) != 25); > > > > ret = init_srcu_struct(&fsnotify_mark_srcu); > > if (ret) > > diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h > > index bdaf22582f6e..db3ee74a7903 100644 > > --- a/include/linux/fsnotify.h > > +++ b/include/linux/fsnotify.h > > @@ -42,9 +42,12 @@ static inline int fsnotify_perm(struct file *file, int > > mask) > > return 0; > > if (!(mask & (MAY_READ | MAY_OPEN))) > > return 0; > > - if (mask & MAY_OPEN) > > + if (mask & MAY_OPEN) { > > fsnotify_mask = FS_OPEN_PERM; > > - else if (mask & MAY_READ) > > + > > + if (file->f_flags & FMODE_EXEC) > > + fsnotify_mask |= FS_EXEC_PERM; > > + } else if (mask & MAY_READ) > > fsnotify_mask = FS_ACCESS_PERM; > > else > > BUG(); > > @@ -220,6 +223,9 @@ static inline void fsnotify_open(struct file *file) > > if (S_ISDIR(inode->i_mode)) > > mask |= FS_ISDIR; > > > > + if (file->f_flags & FMODE_EXEC) > > + mask |= FS_EXEC; > > + > > fsnotify_parent(path, NULL, mask); > > fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); > > } > > diff --git a/include/linux/fsnotify_backend.h > > b/include/linux/fsnotify_backend.h > > index b38964a7a521..7179a82d60d4 100644 > > --- a/include/linux/fsnotify_backend.h > > +++ b/include/linux/fsnotify_backend.h > > @@ -38,6 +38,7 @@ > > #define FS_DELETE 0x00000200 /* Subfile was deleted > > */ > > #define FS_DELETE_SELF 0x00000400 /* Self was > > deleted */ > > #define FS_MOVE_SELF 0x00000800 /* Self was moved */ > > +#define FS_EXEC 0x00001000 /* File was > > executed */ > > > > #define FS_UNMOUNT 0x00002000 /* inode on umount fs > > */ > > #define FS_Q_OVERFLOW 0x00004000 /* Event queued > > overflowed */ > > @@ -45,6 +46,7 @@ > > > > #define FS_OPEN_PERM 0x00010000 /* open event in an > > permission hook */ > > #define FS_ACCESS_PERM 0x00020000 /* access event in > > a permissions hook */ > > +#define FS_EXEC_PERM 0x00040000 /* exec event in > > permission hook */ > > > > #define FS_EXCL_UNLINK 0x04000000 /* do not send > > events if object is unlinked */ > > #define FS_ISDIR 0x40000000 /* event occurred > > against dir */ > > @@ -62,11 +64,12 @@ > > #define FS_EVENTS_POSS_ON_CHILD (FS_ACCESS | FS_MODIFY | FS_ATTRIB |\ > > FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | > > FS_OPEN |\ > > FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE > > > > |\ > > > > - FS_DELETE | FS_OPEN_PERM | > > FS_ACCESS_PERM) > > + FS_DELETE | FS_OPEN_PERM | > > FS_ACCESS_PERM |\ > > + FS_EXEC | FS_EXEC_PERM) > > > > #define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO) > > > > -#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM) > > +#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | > > FS_EXEC_PERM) > > > > #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ > > FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | > > \ > > @@ -75,7 +78,8 @@ > > FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | > > \ > > FS_OPEN_PERM | FS_ACCESS_PERM | > > FS_EXCL_UNLINK | \ > > FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \ > > - FS_DN_MULTISHOT | FS_EVENT_ON_CHILD) > > + FS_DN_MULTISHOT | FS_EVENT_ON_CHILD |\ > > + FS_EXEC | FS_EXEC_PERM) > > > > struct fsnotify_group; > > struct fsnotify_event; > > diff --git a/include/uapi/linux/fanotify.h > > b/include/uapi/linux/fanotify.h > > index 74247917de04..80822af0eeac 100644 > > --- a/include/uapi/linux/fanotify.h > > +++ b/include/uapi/linux/fanotify.h > > @@ -10,11 +10,13 @@ > > #define FAN_CLOSE_WRITE 0x00000008 /* Writtable file > > closed */ > > #define FAN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file > > closed */ > > #define FAN_OPEN 0x00000020 /* File was opened */ > > +#define FAN_EXEC 0x00001000 /* File was executed */ > > > > #define FAN_Q_OVERFLOW 0x00004000 /* Event queued > > overflowed */ > > > > #define FAN_OPEN_PERM 0x00010000 /* File open in > > perm check */ > > #define FAN_ACCESS_PERM 0x00020000 /* File accessed > > in perm check */ > > +#define FAN_EXEC_PERM 0x00040000 /* File executed in > > perm check */ > > > > #define FAN_ONDIR 0x40000000 /* event occurred > > against dir */ > > > > @@ -69,13 +71,15 @@ > > #define FAN_ALL_EVENTS (FAN_ACCESS |\ > > FAN_MODIFY |\ > > FAN_CLOSE |\ > > - FAN_OPEN) > > + FAN_OPEN |\ > > + FAN_EXEC) > > > > /* > > * All events which require a permission response from userspace > > */ > > #define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM |\ > > - FAN_ACCESS_PERM) > > + FAN_ACCESS_PERM |\ > > + FAN_EXEC_PERM) > > > > #define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS |\ > > FAN_ALL_PERM_EVENTS |\