[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250506181413.8387-1-kuniyu@amazon.com>
Date: Tue, 6 May 2025 11:14:07 -0700
From: Kuniyuki Iwashima <kuniyu@...zon.com>
To: <memxor@...il.com>
CC: <andrii@...nel.org>, <ast@...nel.org>, <bpf@...r.kernel.org>,
<brauner@...nel.org>, <casey@...aufler-ca.com>, <daniel@...earbox.net>,
<eddyz87@...il.com>, <gnoack@...gle.com>, <haoluo@...gle.com>,
<jmorris@...ei.org>, <john.fastabend@...il.com>, <jolsa@...nel.org>,
<kpsingh@...nel.org>, <kuni1840@...il.com>, <kuniyu@...zon.com>,
<linux-security-module@...r.kernel.org>, <martin.lau@...ux.dev>,
<mic@...ikod.net>, <netdev@...r.kernel.org>, <omosnace@...hat.com>,
<paul@...l-moore.com>, <sdf@...ichev.me>, <selinux@...r.kernel.org>,
<serge@...lyn.com>, <song@...nel.org>, <stephen.smalley.work@...il.com>,
<yonghong.song@...ux.dev>
Subject: Re: [PATCH v1 bpf-next 0/5] af_unix: Allow BPF LSM to scrub SCM_RIGHTS at sendmsg().
From: Kumar Kartikeya Dwivedi <memxor@...il.com>
Date: Tue, 6 May 2025 18:08:23 +0200
> On Tue, 6 May 2025 at 11:15, Christian Brauner <brauner@...nel.org> wrote:
> >
> > On Tue, May 06, 2025 at 12:49:11AM +0200, Kumar Kartikeya Dwivedi wrote:
> > > On Mon, 5 May 2025 at 23:58, Kuniyuki Iwashima <kuniyu@...zon.com> wrote:
> > > >
> > > > As long as recvmsg() or recvmmsg() is used with cmsg, it is not
> > > > possible to avoid receiving file descriptors via SCM_RIGHTS.
> > > >
> > > > This behaviour has occasionally been flagged as problematic.
> > > >
> > > > For instance, as noted on the uAPI Group page [0], an untrusted peer
> > > > could send a file descriptor pointing to a hung NFS mount and then
> > > > close it. Once the receiver calls recvmsg() with msg_control, the
> > > > descriptor is automatically installed, and then the responsibility
> > > > for the final close() now falls on the receiver, which may result
> > > > in blocking the process for a long time.
> > > >
> > > > systemd calls cmsg_close_all() [1] after each recvmsg() to close()
> > > > unwanted file descriptors sent via SCM_RIGHTS.
> > > >
> > > > However, this cannot work around the issue because the last fput()
> > > > could occur on the receiver side once sendmsg() with SCM_RIGHTS
> > > > succeeds. Also, even filtering by LSM at recvmsg() does not work
> > > > for the same reason.
> > > >
> > > > Thus, we need a better way to filter SCM_RIGHTS on the sender side.
> > > >
> > > > This series allows BPF LSM to inspect skb at sendmsg() and scrub
> > > > SCM_RIGHTS fds by kfunc.
> > > >
> > > > Link: https://uapi-group.org/kernel-features/#disabling-reception-of-scm_rights-for-af_unix-sockets #[0]
> > > > Link: https://github.com/systemd/systemd/blob/v257.5/src/basic/fd-util.c#L612-L628 #[1]
> > > >
> > >
> > > This sounds pretty useful!
> > >
> > > I think you should mention the cases of possible DoS on close() or
> > > flooding, e.g. with FUSE controlled fd/NFS hangs in the commit log
> > > itself.
> > > I think it's been an open problem for a while now with no good solution.
> > > Currently systemd's FDSTORE=1 for PID 1 is susceptible to the same
> > > problem, even if the underlying service isn't root.
> > >
> > > I think it is also useful for restricting what individual file
> > > descriptors can be passed around by a process.
> > > Say restricting usage of an fd to a process and its children, but not
> > > allowing it to be shared with others.
> > > Send side hook is the right point to enforce it.
> > >
> > > Therefore exercising scm_fp_list would be a good idea.
> >
> > No, that's a terrible idea. If the receiver expects 10 file descriptors
> > and suddenly some magically disappear or the order gets messed up that's
> > terrible for security. It's either close all or nothing.
>
> I was talking about exercising/reading it in the selftest, not
> exposing anything new.
>
> Yes, the policy should be close all or nothing, but it can still be
> used to deny sendmsg when one of the descriptors being passed isn't in
> the allowed set.
> You just return 0 or an error. No need to scrub, no need to disappear
> some fds and let the message pass, which can be problematic.
>
> >
> > > We should provide some more examples of the filtering policy in the selftests.
> > > Maybe a simple example, e.g. only memfd or a pipe fd can be passed,
> > > and nothing else.
> > > It would require checking file->f_ops.
> >
> > There's not going to be poking around in file->f_ops for this.
>
> I don't think any poking is required. There's no need to expose anything extra.
>
> Really, all that is needed is for an LSM hook to exist and the program
> to say success or failure.
> Even the scrub fds stuff can be dropped.
>
> The program can simply inspect the scm_fp_list and if it doesn't look
> ok, deny the sendmsg.
> It's already there inside unix_skb_parms.
>
> It just means the program can look at the file (there's no helper
> needed to be exposed) and make a decision, just like in the rest of
> the BPF LSM hooks.
> I think a socket option makes sense too, but ideally we can have both
> the hook and the socket option.
>
> The socket option has the advantage that user space can set it itself
> conveniently, without having to load a BPF program.
> Meanwhile the hook can be more fine grained in decision making and be
> imposed by some central entity.
>
> Does this sound reasonable? I don't think it requires anything beyond
> simply defining the hook and letting a program run there.
> No poking into VFS internals etc. or silently dropping file
> descriptors and letting it succeed.
>
> So mostly patch 1-2 and then another to add a setsockopt flag.
Right, patch 1-2 is enough to let BPF LSM to filter each skb.
I'll also add the socket option too.
Thanks!
Powered by blists - more mailing lists