From: Matthew Bobrowski <repnop@google.com>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Jan Kara <jack@suse.cz>,
Christian Brauner <christian.brauner@ubuntu.com>,
linux-fsdevel <linux-fsdevel@vger.kernel.org>,
Linux API <linux-api@vger.kernel.org>
Subject: Re: [PATCH v2 5/5] fanotify: add pidfd support to the fanotify API
Date: Thu, 10 Jun 2021 16:35:24 +1000 [thread overview]
Message-ID: <YMGyrJMwpvqU2kcr@google.com> (raw)
In-Reply-To: <CAOQ4uxj2t+z1BWimWKKTae3saDbZQ=-h+6JSnr=Vyv1=rGT0Jw@mail.gmail.com>
On Thu, Jun 10, 2021 at 08:18:01AM +0300, Amir Goldstein wrote:
> On Thu, Jun 10, 2021 at 3:22 AM Matthew Bobrowski <repnop@google.com> wrote:
> > @@ -489,8 +525,9 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
> > struct path *path = fanotify_event_path(event);
> > struct fanotify_info *info = fanotify_event_info(event);
> > unsigned int info_mode = FAN_GROUP_FLAG(group, FANOTIFY_INFO_MODES);
> > + unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD;
> > struct file *f = NULL;
> > - int ret, fd = FAN_NOFD;
> > + int ret, pidfd = 0, fd = FAN_NOFD;
>
> It feels like this should be pidfd = FAN_NOPIDFD?
I had considered this, but in all honesty I wasn't sure what the behavior
is when put_unused_fd() is provided a negative value, nor whether it is
accepted. The way I saw it was that if fid info record copying had errored
out for whatever reason and we jumped to the out_close_fd label we'd also,
perhaps unnecessarily, take the pidfd clean up route, which IMO wouldn't be
required.
> >
> > pr_debug("%s: group=%p event=%p\n", __func__, group, event);
> >
> > @@ -524,6 +561,34 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
> > }
> > metadata.fd = fd;
> >
> > + /*
> > + * Currently, reporting a pidfd to an unprivileged listener is not
> > + * supported. The FANOTIFY_UNPRIV flag is to be kept here so that a
> > + * pidfd is not accidentally leaked to an unprivileged listener.
> > + */
> > + if (pidfd_mode && !FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV)) {
> > + /*
> > + * The PIDTYPE_TGID check for an event->pid is performed
> > + * preemptively in attempt to catch those rare instances
> > + * where the process responsible for generating the event has
> > + * terminated prior to calling into pidfd_create() and
> > + * acquiring a valid pidfd. Report FAN_NOPIDFD to the listener
> > + * in those cases.
> > + */
> > + if (metadata.pid == 0 ||
> > + !pid_has_task(event->pid, PIDTYPE_TGID)) {
> > + pidfd = FAN_NOPIDFD;
> > + } else {
> > + pidfd = pidfd_create(event->pid, 0);
> > + if (pidfd < 0)
> > + /*
> > + * All other pidfd creation errors are reported
> > + * as FAN_EPIDFD to the listener.
> > + */
> > + pidfd = FAN_EPIDFD;
>
> That's an anti pattern. a multi-line statement, even due to comment should
> be inside {}, but in this case, I think it is better to put this
> comment as another
> line in the big comment above which explains both the if and the else, because
> it is in fact a continuation of the comment above.
Ah, right, I didn't know that this was considered as an anti-pattern. But
then again, I can totally understand why it would be. No objections with
merging this comment with the one that precedes the parent if statement.
> > + }
> > + }
> > +
> > ret = -EFAULT;
> > /*
> > * Sanity check copy size in case get_one_event() and
> > @@ -545,10 +610,19 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
> > fd_install(fd, f);
> >
> > if (info_mode) {
> > - ret = copy_info_records_to_user(event, info, info_mode,
> > - buf, count);
> > + /*
> > + * Complain if the FAN_REPORT_PIDFD and FAN_REPORT_TID mutual
> > + * exclusion is ever lifted. At the time of incorporating pidfd
> > + * support within fanotify, the pidfd API only supported the
> > + * creation of pidfds for thread-group leaders.
> > + */
> > + WARN_ON_ONCE(pidfd_mode &&
> > + FAN_GROUP_FLAG(group, FAN_REPORT_TID));
> > +
>
> This WARN_ON, if needed at all, would be better places inside if (pidfd_mode &&
> code block above where you would only need to
> WARN_ON_ONCE(FAN_GROUP_FLAG(group, FAN_REPORT_TID));
> as close as possible to PIDTYPE_TGID line.
Agree, there's no reason why it can't be moved to the above pidfd_mode
check.
> > + ret = copy_info_records_to_user(event, info, info_mode, pidfd,
> > + buf, count);
> > if (ret < 0)
> > - return ret;
> > + goto out_close_fd;
>
> This looks like a bug in upstream.
Yes, I'm glad this was picked up and I was actually wondering why it was
acceptable to directly return without jumping to the out_close_fd label in
the case of an error. I felt like it may have been a burden to raise the
question in the first place because I thought that this got picked up in
the review already and there was a good reason for having it, despite not
really making much sense.
> It should have been goto out_close_fd to begin with.
> We did already copy metadata.fd to user, but the read() call
> returns an error.
> You should probably fix it before the refactoring patch, so it
> can be applied to stable kernels.
Sure, I will send through a patch fixing this before submitting the next
version of this series though. How do I tag the patch so that it's picked
up an back ported accordingly?
> > }
> >
> > return metadata.event_len;
> > @@ -558,6 +632,10 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
> > put_unused_fd(fd);
> > fput(f);
> > }
> > +
> > + if (pidfd < 0)
>
> That condition is reversed.
> We do not seem to have any test coverage for this error handling
> Not so surprising that upstream had a bug...
Sorry Amir, I don't quite understand what you mean by "That condition is
reversed". Presumably you're referring to the fd != FAN_NOFD check and not
pidfd < 0 here.
/M
next prev parent reply other threads:[~2021-06-10 6:35 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-10 0:19 [PATCH v2 0/5] Add pidfd support to the fanotify API Matthew Bobrowski
2021-06-10 0:20 ` [PATCH v2 1/5] kernel/pid.c: remove static qualifier from pidfd_create() Matthew Bobrowski
2021-06-15 11:34 ` Christian Brauner
2021-06-10 0:20 ` [PATCH v2 2/5] kernel/pid.c: implement additional checks upon pidfd_create() parameters Matthew Bobrowski
2021-06-15 11:35 ` Christian Brauner
2021-06-10 0:21 ` [PATCH v2 3/5] fanotify/fanotify_user.c: minor cosmetic adjustments to fid labels Matthew Bobrowski
2021-06-10 0:21 ` [PATCH v2 4/5] fanotify/fanotify_user.c: introduce a generic info record copying helper Matthew Bobrowski
2021-06-10 0:21 ` [PATCH v2 5/5] fanotify: add pidfd support to the fanotify API Matthew Bobrowski
2021-06-10 5:18 ` Amir Goldstein
2021-06-10 6:35 ` Matthew Bobrowski [this message]
2021-06-10 7:11 ` Amir Goldstein
2021-06-10 7:24 ` Matthew Bobrowski
2021-06-10 11:23 ` Jan Kara
2021-06-11 0:32 ` Matthew Bobrowski
2021-07-10 14:49 ` Amir Goldstein
2021-07-14 0:18 ` Matthew Bobrowski
2021-06-10 5:37 ` [PATCH v2 0/5] Add " Amir Goldstein
2021-06-10 6:55 ` Matthew Bobrowski
2021-06-10 11:32 ` Jan Kara
2021-06-11 0:35 ` Matthew Bobrowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YMGyrJMwpvqU2kcr@google.com \
--to=repnop@google.com \
--cc=amir73il@gmail.com \
--cc=christian.brauner@ubuntu.com \
--cc=jack@suse.cz \
--cc=linux-api@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).