diff mbox series

[v7,2/4] fanotify: introduce new event mask FAN_OPEN_EXEC

Message ID 05d2297ae76d5b7b00cc1d6af27b25e898e986c0.1541639254.git.mbobrowski@mbobrowski.org (mailing list archive)
State New, archived
Headers show
Series fanotify: introduce new event mask FAN_OPEN_EXEC and FAN_OPEN_EXEC_PERM | expand

Commit Message

Matthew Bobrowski Nov. 8, 2018, 3:07 a.m. UTC
A new event mask FAN_OPEN_EXEC has been defined so that users have the
ability to receive events specifically when a file has been opened with
the intent to be executed. Events of FAN_OPEN_EXEC type will be
generated when a file has been opened using either execve(), execveat()
or uselib() system calls.

The feature is implemented within fsnotify_open() by generating the
FAN_OPEN_EXEC event type if __FMODE_EXEC is set within file->f_flags.

Signed-off-by: Matthew Bobrowski <mbobrowski@mbobrowski.org>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify.c    | 3 ++-
 fs/notify/fsnotify.c             | 2 +-
 include/linux/fanotify.h         | 2 +-
 include/linux/fsnotify.h         | 2 ++
 include/linux/fsnotify_backend.h | 7 +++++--
 include/uapi/linux/fanotify.h    | 1 +
 6 files changed, 12 insertions(+), 5 deletions(-)

Comments

Andy Lutomirski Nov. 8, 2018, 6:22 p.m. UTC | #1
On Wed, Nov 7, 2018 at 7:07 PM Matthew Bobrowski
<mbobrowski@mbobrowski.org> wrote:
>
> A new event mask FAN_OPEN_EXEC has been defined so that users have the
> ability to receive events specifically when a file has been opened with
> the intent to be executed. Events of FAN_OPEN_EXEC type will be
> generated when a file has been opened using either execve(), execveat()
> or uselib() system calls.
>
> The feature is implemented within fsnotify_open() by generating the
> FAN_OPEN_EXEC event type if __FMODE_EXEC is set within file->f_flags.
>

I think this needs some clarification.  In particular:

Do current kernels generate some other fanotify on execve or do they
generate no event at all?

What is the intended use case?

What semantics do you provide for the opening of the ELF loader?  Are
those semantics useful?

How are users of this mechanism expected to handle DSOs?

--Andy
Matthew Bobrowski Nov. 9, 2018, 5:41 a.m. UTC | #2
On Thu, Nov 08, 2018 at 10:22:50AM -0800, Andy Lutomirski wrote:
> On Wed, Nov 7, 2018 at 7:07 PM Matthew Bobrowski
> <mbobrowski@mbobrowski.org> wrote:
> >
> > A new event mask FAN_OPEN_EXEC has been defined so that users have the
> > ability to receive events specifically when a file has been opened with
> > the intent to be executed. Events of FAN_OPEN_EXEC type will be
> > generated when a file has been opened using either execve(), execveat()
> > or uselib() system calls.
> >
> > The feature is implemented within fsnotify_open() by generating the
> > FAN_OPEN_EXEC event type if __FMODE_EXEC is set within file->f_flags.
> >
> 
> I think this needs some clarification.  In particular:

OK, sure.

> Do current kernels generate some other fanotify on execve or do they
> generate no event at all?

Yes, it does currently generate events on execve. Due to the nature of
how this particular system call works, the API, as is, will generate a
number of FAN_OPEN and FAN_ACCESS events.
 
> What is the intended use case?

For our particular use case, this is to greatly assist with an auditing
application that we're in the midst of developing. More specifically
though, it is to aid with providing additional context around why the
marked object(s) is being opened. We're interested to understand when
the direct execution of a file occurs via execve() or execveat(), for
example. This becomes exceptionally helpful on a busy filesystem when
you're trying to sift through and correlate FAN_OPEN and FAN_ACCESS
events while having marks placed on either a mount(s) or superblock(s).

> What semantics do you provide for the opening of the ELF loader?  Are
> those semantics useful?

I don't exactly understand what you mean by providing semantics around
the opening of the ELF loader. However, I'm going to work with the
assumption that you're referring to how this particular event mask works
with the implicit invocation of the ELF loader when an ELF program is
being prepared for execution? If that's the case, it's quite simple. If
the ELF loader has been marked to receive events of this type, then an
event will also be generated for the ELF loader when an ELF program is
invoked via execve. If the ELF loader has not been marked, then only the
event for the ELF program itself will be generated. 

If I've misunderstood what you're referring to, please kindly elaborate.
 
> How are users of this mechanism expected to handle DSOs?

Well, if they're concerned about the direct execution of a shared
library, then they'd just place a mark on it using this mask. Generally
speaking though, I can't see that being particularly useful seeing as
though DSOs in most cases are not actually directly executed per se, but
rather opened, read and then mapped into the process address space. So,
if they're concerned with handling DSOs, then it's the users discretion
about whether they mark it and what type of mark is to be placed on the
DSO object itself.
Andy Lutomirski Nov. 9, 2018, 6:04 a.m. UTC | #3
On Thu, Nov 8, 2018 at 9:41 PM Matthew Bobrowski
<mbobrowski@mbobrowski.org> wrote:
>
> On Thu, Nov 08, 2018 at 10:22:50AM -0800, Andy Lutomirski wrote:
> > On Wed, Nov 7, 2018 at 7:07 PM Matthew Bobrowski
> > <mbobrowski@mbobrowski.org> wrote:
> > >
> > > A new event mask FAN_OPEN_EXEC has been defined so that users have the
> > > ability to receive events specifically when a file has been opened with
> > > the intent to be executed. Events of FAN_OPEN_EXEC type will be
> > > generated when a file has been opened using either execve(), execveat()
> > > or uselib() system calls.
> > >
> > > The feature is implemented within fsnotify_open() by generating the
> > > FAN_OPEN_EXEC event type if __FMODE_EXEC is set within file->f_flags.
> > >
> >
> > I think this needs some clarification.  In particular:
>
> OK, sure.
>
> > Do current kernels generate some other fanotify on execve or do they
> > generate no event at all?
>
> Yes, it does currently generate events on execve. Due to the nature of
> how this particular system call works, the API, as is, will generate a
> number of FAN_OPEN and FAN_ACCESS events.
>
> > What is the intended use case?
>
> For our particular use case, this is to greatly assist with an auditing
> application that we're in the midst of developing. More specifically
> though, it is to aid with providing additional context around why the
> marked object(s) is being opened. We're interested to understand when
> the direct execution of a file occurs via execve() or execveat(), for
> example. This becomes exceptionally helpful on a busy filesystem when
> you're trying to sift through and correlate FAN_OPEN and FAN_ACCESS
> events while having marks placed on either a mount(s) or superblock(s).

Seems reasonable.

>
> > What semantics do you provide for the opening of the ELF loader?  Are
> > those semantics useful?
>
> I don't exactly understand what you mean by providing semantics around
> the opening of the ELF loader. However, I'm going to work with the
> assumption that you're referring to how this particular event mask works
> with the implicit invocation of the ELF loader when an ELF program is
> being prepared for execution? If that's the case, it's quite simple. If
> the ELF loader has been marked to receive events of this type, then an
> event will also be generated for the ELF loader when an ELF program is
> invoked via execve. If the ELF loader has not been marked, then only the
> event for the ELF program itself will be generated.

OK.  You should probably add to your documentation that interpreters
opened as a result of execve() and execveat() also set FAN_OPEN_EXEC.

>
> If I've misunderstood what you're referring to, please kindly elaborate.
>
> > How are users of this mechanism expected to handle DSOs?
>
> Well, if they're concerned about the direct execution of a shared
> library, then they'd just place a mark on it using this mask. Generally
> speaking though, I can't see that being particularly useful seeing as
> though DSOs in most cases are not actually directly executed per se, but
> rather opened, read and then mapped into the process address space. So,
> if they're concerned with handling DSOs, then it's the users discretion
> about whether they mark it and what type of mark is to be placed on the
> DSO object itself.

Are you sure?  Because I don't think that DSOs actually get
__FMODE_EXEC set.  So I expect that, if you do:

$ /bin/echo foo

then you'll get FAN_OPEN_EXEC.  If, on the other hand, you do:

$ /lib64/ld-linux-x86-64.so.2 /bin/echo foo

then I think you will *not* get FAN_OPEN_EXEC.
Matthew Bobrowski Nov. 9, 2018, 7:27 a.m. UTC | #4
On Thu, Nov 08, 2018 at 10:04:08PM -0800, Andy Lutomirski wrote:
> On Thu, Nov 8, 2018 at 9:41 PM Matthew Bobrowski
> <mbobrowski@mbobrowski.org> wrote:
> >
> > On Thu, Nov 08, 2018 at 10:22:50AM -0800, Andy Lutomirski wrote:
> > > On Wed, Nov 7, 2018 at 7:07 PM Matthew Bobrowski
> > > <mbobrowski@mbobrowski.org> wrote:
> > > >
> > > > A new event mask FAN_OPEN_EXEC has been defined so that users have the
> > > > ability to receive events specifically when a file has been opened with
> > > > the intent to be executed. Events of FAN_OPEN_EXEC type will be
> > > > generated when a file has been opened using either execve(), execveat()
> > > > or uselib() system calls.
> > > >
> > > > The feature is implemented within fsnotify_open() by generating the
> > > > FAN_OPEN_EXEC event type if __FMODE_EXEC is set within file->f_flags.
> > > >
> > >
> > > I think this needs some clarification.  In particular:
> >
> > OK, sure.
> >
> > > Do current kernels generate some other fanotify on execve or do they
> > > generate no event at all?
> >
> > Yes, it does currently generate events on execve. Due to the nature of
> > how this particular system call works, the API, as is, will generate a
> > number of FAN_OPEN and FAN_ACCESS events.
> >
> > > What is the intended use case?
> >
> > For our particular use case, this is to greatly assist with an auditing
> > application that we're in the midst of developing. More specifically
> > though, it is to aid with providing additional context around why the
> > marked object(s) is being opened. We're interested to understand when
> > the direct execution of a file occurs via execve() or execveat(), for
> > example. This becomes exceptionally helpful on a busy filesystem when
> > you're trying to sift through and correlate FAN_OPEN and FAN_ACCESS
> > events while having marks placed on either a mount(s) or superblock(s).
> 
> Seems reasonable.
> 
> >
> > > What semantics do you provide for the opening of the ELF loader?  Are
> > > those semantics useful?
> >
> > I don't exactly understand what you mean by providing semantics around
> > the opening of the ELF loader. However, I'm going to work with the
> > assumption that you're referring to how this particular event mask works
> > with the implicit invocation of the ELF loader when an ELF program is
> > being prepared for execution? If that's the case, it's quite simple. If
> > the ELF loader has been marked to receive events of this type, then an
> > event will also be generated for the ELF loader when an ELF program is
> > invoked via execve. If the ELF loader has not been marked, then only the
> > event for the ELF program itself will be generated.
> 
> OK.  You should probably add to your documentation that interpreters
> opened as a result of execve() and execveat() also set FAN_OPEN_EXEC.

Sure, I can add that as a clarifying point to the documentation. 

> 
> >
> > If I've misunderstood what you're referring to, please kindly elaborate.
> >
> > > How are users of this mechanism expected to handle DSOs?
> >
> > Well, if they're concerned about the direct execution of a shared
> > library, then they'd just place a mark on it using this mask. Generally
> > speaking though, I can't see that being particularly useful seeing as
> > though DSOs in most cases are not actually directly executed per se, but
> > rather opened, read and then mapped into the process address space. So,
> > if they're concerned with handling DSOs, then it's the users discretion
> > about whether they mark it and what type of mark is to be placed on the
> > DSO object itself.
> 
> Are you sure?  Because I don't think that DSOs actually get
> __FMODE_EXEC set.  So I expect that, if you do:
> 
> $ /bin/echo foo
> 
> then you'll get FAN_OPEN_EXEC.  

Correct. If the marked object here was /bin/echo, then yes, doing
exactly that would result in a FAN_OPEN_EXEC as you're passing it to
execve, so __FMODE_EXEC is set in the open_flag accordingly.

> If, on the other hand, you do:
> 
> $ /lib64/ld-linux-x86-64.so.2 /bin/echo foo
> 
> then I think you will *not* get FAN_OPEN_EXEC.

Here, you're also correct. 

Remember though, FAN_OPEN_EXEC is set purely for an object that is
opened and contains __FMODE_EXEC in the open_flag. Thus, anything opened
via syscalls execve, execveat or uselib. In the above example, direct
execution via execve is performed on /lib64/ld-linux-x86-64.so.2 and the
object /bin/echo in this instance is passed to it as an argument. This 
results in an open/read !(open_flag & __FMODE_EXEC), as oppose to
execve. So here, providing that you have a mark placed on the loader,
you'd only get a FAN_OPEN_EXEC for that object and consequently nothing
for the program that has been passed to it as an argument. 

Events of type FAN_OPEN_EXEC will *not* be raised in the situation where
an interpreter reads data as input and subsequently results in arbitrary
computation. I've also made this explicitly clear in my supporting
documentation (man-pages). Not sure, whether this should also be added
to the changelog. Thoughts?
Jan Kara Nov. 12, 2018, 4:14 p.m. UTC | #5
On Thu 08-11-18 22:04:08, Andy Lutomirski wrote:
> On Thu, Nov 8, 2018 at 9:41 PM Matthew Bobrowski
> <mbobrowski@mbobrowski.org> wrote:
> >
> > On Thu, Nov 08, 2018 at 10:22:50AM -0800, Andy Lutomirski wrote:
> > > On Wed, Nov 7, 2018 at 7:07 PM Matthew Bobrowski
> > > <mbobrowski@mbobrowski.org> wrote:
> > > >
> > > > A new event mask FAN_OPEN_EXEC has been defined so that users have the
> > > > ability to receive events specifically when a file has been opened with
> > > > the intent to be executed. Events of FAN_OPEN_EXEC type will be
> > > > generated when a file has been opened using either execve(), execveat()
> > > > or uselib() system calls.
> > > >
> > > > The feature is implemented within fsnotify_open() by generating the
> > > > FAN_OPEN_EXEC event type if __FMODE_EXEC is set within file->f_flags.
> > > >
> > >
> > > I think this needs some clarification.  In particular:
> >
> > OK, sure.
> >
> > > Do current kernels generate some other fanotify on execve or do they
> > > generate no event at all?
> >
> > Yes, it does currently generate events on execve. Due to the nature of
> > how this particular system call works, the API, as is, will generate a
> > number of FAN_OPEN and FAN_ACCESS events.
> >
> > > What is the intended use case?
> >
> > For our particular use case, this is to greatly assist with an auditing
> > application that we're in the midst of developing. More specifically
> > though, it is to aid with providing additional context around why the
> > marked object(s) is being opened. We're interested to understand when
> > the direct execution of a file occurs via execve() or execveat(), for
> > example. This becomes exceptionally helpful on a busy filesystem when
> > you're trying to sift through and correlate FAN_OPEN and FAN_ACCESS
> > events while having marks placed on either a mount(s) or superblock(s).
> 
> Seems reasonable.
> 
> >
> > > What semantics do you provide for the opening of the ELF loader?  Are
> > > those semantics useful?
> >
> > I don't exactly understand what you mean by providing semantics around
> > the opening of the ELF loader. However, I'm going to work with the
> > assumption that you're referring to how this particular event mask works
> > with the implicit invocation of the ELF loader when an ELF program is
> > being prepared for execution? If that's the case, it's quite simple. If
> > the ELF loader has been marked to receive events of this type, then an
> > event will also be generated for the ELF loader when an ELF program is
> > invoked via execve. If the ELF loader has not been marked, then only the
> > event for the ELF program itself will be generated.
> 
> OK.  You should probably add to your documentation that interpreters
> opened as a result of execve() and execveat() also set FAN_OPEN_EXEC.

I'm not sure I understand your concern (and thus need for documentation).
In the following I assume you watch the whole system for fanotify events
(you can restrict them to specific files / mount points / superblocks
but that's besides the point of this discussion).
If you do:

~> /bin/echo

Then you get FAN_OPEN_EXEC event for '/bin/echo' file and nothing more.
Similarly if you do:
~> cat /tmp/test.sh
#!/bin/bash
/bin/echo
~> /tmp/test.sh

You will get FAN_OPEN_EXEC events for /tmp/test.sh and /bin/echo and
nothing more.

If you do:

~> /bin/sh /tmp/test.sh

You will get FAN_OPEN_EXEC events for /bin/sh and /bin/echo and
nothing more.

I other words generated FAN_OPEN_EXEC events 1:1 correspond to the first
argument of the execve(2) syscall. Nothing less and nothing more.

> > If I've misunderstood what you're referring to, please kindly elaborate.
> >
> > > How are users of this mechanism expected to handle DSOs?
> >
> > Well, if they're concerned about the direct execution of a shared
> > library, then they'd just place a mark on it using this mask. Generally
> > speaking though, I can't see that being particularly useful seeing as
> > though DSOs in most cases are not actually directly executed per se, but
> > rather opened, read and then mapped into the process address space. So,
> > if they're concerned with handling DSOs, then it's the users discretion
> > about whether they mark it and what type of mark is to be placed on the
> > DSO object itself.
> 
> Are you sure?  Because I don't think that DSOs actually get
> __FMODE_EXEC set.  So I expect that, if you do:
> 
> $ /bin/echo foo
> 
> then you'll get FAN_OPEN_EXEC.  If, on the other hand, you do:
> 
> $ /lib64/ld-linux-x86-64.so.2 /bin/echo foo
> 
> then I think you will *not* get FAN_OPEN_EXEC.

Exactly and I think that was what Matthew was trying to tell. Generally
there are no FAN_OPEN_EXEC events for DSOs. Is it clearer now?

								Honza
Andy Lutomirski Nov. 12, 2018, 4:37 p.m. UTC | #6
> On Nov 12, 2018, at 8:14 AM, Jan Kara <jack@suse.cz> wrote:
> 
>> On Thu 08-11-18 22:04:08, Andy Lutomirski wrote:
>> On Thu, Nov 8, 2018 at 9:41 PM Matthew Bobrowski
>> <mbobrowski@mbobrowski.org> wrote:
>>> 
>>>> On Thu, Nov 08, 2018 at 10:22:50AM -0800, Andy Lutomirski wrote:
>>>> On Wed, Nov 7, 2018 at 7:07 PM Matthew Bobrowski
>>>> <mbobrowski@mbobrowski.org> wrote:
>>>>> 
>>>>> A new event mask FAN_OPEN_EXEC has been defined so that users have the
>>>>> ability to receive events specifically when a file has been opened with
>>>>> the intent to be executed. Events of FAN_OPEN_EXEC type will be
>>>>> generated when a file has been opened using either execve(), execveat()
>>>>> or uselib() system calls.
>>>>> 
>>>>> The feature is implemented within fsnotify_open() by generating the
>>>>> FAN_OPEN_EXEC event type if __FMODE_EXEC is set within file->f_flags.
>>>>> 
>>>> 
>>>> I think this needs some clarification.  In particular:
>>> 
>>> OK, sure.
>>> 
>>>> Do current kernels generate some other fanotify on execve or do they
>>>> generate no event at all?
>>> 
>>> Yes, it does currently generate events on execve. Due to the nature of
>>> how this particular system call works, the API, as is, will generate a
>>> number of FAN_OPEN and FAN_ACCESS events.
>>> 
>>>> What is the intended use case?
>>> 
>>> For our particular use case, this is to greatly assist with an auditing
>>> application that we're in the midst of developing. More specifically
>>> though, it is to aid with providing additional context around why the
>>> marked object(s) is being opened. We're interested to understand when
>>> the direct execution of a file occurs via execve() or execveat(), for
>>> example. This becomes exceptionally helpful on a busy filesystem when
>>> you're trying to sift through and correlate FAN_OPEN and FAN_ACCESS
>>> events while having marks placed on either a mount(s) or superblock(s).
>> 
>> Seems reasonable.
>> 
>>> 
>>>> What semantics do you provide for the opening of the ELF loader?  Are
>>>> those semantics useful?
>>> 
>>> I don't exactly understand what you mean by providing semantics around
>>> the opening of the ELF loader. However, I'm going to work with the
>>> assumption that you're referring to how this particular event mask works
>>> with the implicit invocation of the ELF loader when an ELF program is
>>> being prepared for execution? If that's the case, it's quite simple. If
>>> the ELF loader has been marked to receive events of this type, then an
>>> event will also be generated for the ELF loader when an ELF program is
>>> invoked via execve. If the ELF loader has not been marked, then only the
>>> event for the ELF program itself will be generated.
>> 
>> OK.  You should probably add to your documentation that interpreters
>> opened as a result of execve() and execveat() also set FAN_OPEN_EXEC.
> 
> I'm not sure I understand your concern (and thus need for documentation).
> In the following I assume you watch the whole system for fanotify events
> (you can restrict them to specific files / mount points / superblocks
> but that's besides the point of this discussion).
> If you do:
> 
> ~> /bin/echo
> 
> Then you get FAN_OPEN_EXEC event for '/bin/echo' file and nothing more.

If indeed that’s what the code does, then documenting it as such seems fine. But, by inspection, ELF interpreters are opened with open_exec(), so they should fire the event too. Am I wrong?
Matthew Bobrowski Nov. 13, 2018, 11:45 a.m. UTC | #7
On Mon, Nov 12, 2018 at 08:37:25AM -0800, Andy Lutomirski wrote:
> >> OK.  You should probably add to your documentation that interpreters
> >> opened as a result of execve() and execveat() also set FAN_OPEN_EXEC.
> > 
> > I'm not sure I understand your concern (and thus need for documentation).
> > In the following I assume you watch the whole system for fanotify events
> > (you can restrict them to specific files / mount points / superblocks
> > but that's besides the point of this discussion).
> > If you do:
> > 
> > ~> /bin/echo
> > 
> > Then you get FAN_OPEN_EXEC event for '/bin/echo' file and nothing more.
> 
> If indeed that’s what the code does, then documenting it as such seems fine.
> But, by inspection, ELF interpreters are opened with open_exec(), so they
> should fire the event too. Am I wrong?

No, you're not wrong.

I do believe that there is no need to add a specific statement about
interpreters within the documentation.
Jan Kara Nov. 13, 2018, 5:35 p.m. UTC | #8
On Tue 13-11-18 22:45:28, Matthew Bobrowski wrote:
> On Mon, Nov 12, 2018 at 08:37:25AM -0800, Andy Lutomirski wrote:
> > >> OK.  You should probably add to your documentation that interpreters
> > >> opened as a result of execve() and execveat() also set FAN_OPEN_EXEC.
> > > 
> > > I'm not sure I understand your concern (and thus need for documentation).
> > > In the following I assume you watch the whole system for fanotify events
> > > (you can restrict them to specific files / mount points / superblocks
> > > but that's besides the point of this discussion).
> > > If you do:
> > > 
> > > ~> /bin/echo
> > > 
> > > Then you get FAN_OPEN_EXEC event for '/bin/echo' file and nothing more.
> > 
> > If indeed that’s what the code does, then documenting it as such seems fine.
> > But, by inspection, ELF interpreters are opened with open_exec(), so they
> > should fire the event too. Am I wrong?
> 
> No, you're not wrong.
> 
> I do believe that there is no need to add a specific statement about
> interpreters within the documentation.

So I think what Andy means is that if I watch / for FAN_OPEN_EXEC, then
people may not immediately realize that if they do /bin/echo, they'll
actually get events for

/bin/echo
/lib64/ld-2.22.so

At least I didn't immediately realize that (and just compiled test kernel
with your patches to verify). So I think this clarification would be worth
it as a note in the manpage. Changelog can IMO stay as is.

								Honza
Matthew Bobrowski Nov. 13, 2018, 11:26 p.m. UTC | #9
On Tue, Nov 13, 2018 at 06:35:03PM +0100, Jan Kara wrote:
> > > >> OK.  You should probably add to your documentation that interpreters
> > > >> opened as a result of execve() and execveat() also set FAN_OPEN_EXEC.
> > > > 
> > > > I'm not sure I understand your concern (and thus need for documentation).
> > > > In the following I assume you watch the whole system for fanotify events
> > > > (you can restrict them to specific files / mount points / superblocks
> > > > but that's besides the point of this discussion).
> > > > If you do:
> > > > 
> > > > ~> /bin/echo
> > > > 
> > > > Then you get FAN_OPEN_EXEC event for '/bin/echo' file and nothing more.
> > > 
> > > If indeed that’s what the code does, then documenting it as such seems fine.
> > > But, by inspection, ELF interpreters are opened with open_exec(), so they
> > > should fire the event too. Am I wrong?
> > 
> > No, you're not wrong.
> > 
> > I do believe that there is no need to add a specific statement about
> > interpreters within the documentation.
> 
> So I think what Andy means is that if I watch / for FAN_OPEN_EXEC, then
> people may not immediately realize that if they do /bin/echo, they'll
> actually get events for
> 
> /bin/echo
> /lib64/ld-2.22.so
> 
> At least I didn't immediately realize that (and just compiled test kernel
> with your patches to verify). So I think this clarification would be worth
> it as a note in the manpage. Changelog can IMO stay as is.

OK, sure, I will add it.
diff mbox series

Patch

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 0a09950317dd..e30f3a1d9699 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -209,8 +209,9 @@  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_OPEN_EXEC != FS_OPEN_EXEC);
 
-	BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 10);
+	BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 11);
 
 	mask = fanotify_group_event_mask(iter_info, mask, data, data_type);
 	if (!mask)
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index d2c34900ae05..b3f58f36a0ab 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -401,7 +401,7 @@  static __init int fsnotify_init(void)
 {
 	int ret;
 
-	BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 23);
+	BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 24);
 
 	ret = init_srcu_struct(&fsnotify_mark_srcu);
 	if (ret)
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index a5a60691e48b..c521e4264f2b 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -37,7 +37,7 @@ 
 
 /* Events that user can request to be notified on */
 #define FANOTIFY_EVENTS		(FAN_ACCESS | FAN_MODIFY | \
-				 FAN_CLOSE | FAN_OPEN)
+				 FAN_CLOSE | FAN_OPEN | FAN_OPEN_EXEC)
 
 /* Events that require a permission response from user */
 #define FANOTIFY_PERM_EVENTS	(FAN_OPEN_PERM | FAN_ACCESS_PERM)
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index fd1ce10553bf..1fe5ac93b252 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -215,6 +215,8 @@  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_OPEN_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 135b973e44d1..39d94e62a836 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_OPEN_EXEC		0x00001000	/* File was opened for exec */
 
 #define FS_UNMOUNT		0x00002000	/* inode on umount fs */
 #define FS_Q_OVERFLOW		0x00004000	/* Event queued overflowed */
@@ -62,7 +63,8 @@ 
 #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_OPEN_EXEC)
 
 #define FS_MOVE			(FS_MOVED_FROM | FS_MOVED_TO)
 
@@ -74,7 +76,8 @@ 
 			     FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
 			     FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
 			     FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
-			     FS_OPEN_PERM | FS_ACCESS_PERM | FS_DN_RENAME)
+			     FS_OPEN_PERM | FS_ACCESS_PERM | FS_DN_RENAME | \
+			     FS_OPEN_EXEC)
 
 /* Extra flags that may be reported with event or control handling of events */
 #define ALL_FSNOTIFY_FLAGS  (FS_EXCL_UNLINK | FS_ISDIR | FS_IN_ONESHOT | \
diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
index b86740d1c50a..d9664fbc905b 100644
--- a/include/uapi/linux/fanotify.h
+++ b/include/uapi/linux/fanotify.h
@@ -10,6 +10,7 @@ 
 #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_OPEN_EXEC		0x00001000	/* File was opened for exec */
 
 #define FAN_Q_OVERFLOW		0x00004000	/* Event queued overflowed */