[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAOQ4uxg96V3FBpnn0JvPFvqjK8_R=4gHbJjTPVTxDPzyns52hw@mail.gmail.com>
Date: Wed, 13 Nov 2024 09:01:23 +0100
From: Amir Goldstein <amir73il@...il.com>
To: Jeff Layton <jlayton@...nel.org>, Erin Shepherd <erin.shepherd@....eu>
Cc: linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org,
christian@...uner.io, paul@...l-moore.com, bluca@...ian.org
Subject: Re: [PATCH 4/4] pidfs: implement fh_to_dentry
On Wed, Nov 13, 2024 at 1:34 AM Jeff Layton <jlayton@...nel.org> wrote:
>
> On Fri, 2024-11-01 at 13:54 +0000, Erin Shepherd wrote:
> > This enables userspace to use name_to_handle_at to recover a pidfd
> > to a process.
> >
> > We stash the process' PID in the root pid namespace inside the handle,
> > and use that to recover the pid (validating that pid->ino matches the
> > value in the handle, i.e. that the pid has not been reused).
> >
> > We use the root namespace in order to ensure that file handles can be
> > moved across namespaces; however, we validate that the PID exists in
> > the current namespace before returning the inode.
> >
> > Signed-off-by: Erin Shepherd <erin.shepherd@....eu>
> > ---
> > fs/pidfs.c | 50 +++++++++++++++++++++++++++++++++++++++++++-------
> > 1 file changed, 43 insertions(+), 7 deletions(-)
> >
> > diff --git a/fs/pidfs.c b/fs/pidfs.c
> > index c8e7e9011550..2d66610ef385 100644
> > --- a/fs/pidfs.c
> > +++ b/fs/pidfs.c
> > @@ -348,23 +348,59 @@ static const struct dentry_operations pidfs_dentry_operations = {
> > .d_prune = stashed_dentry_prune,
> > };
> >
> > -static int pidfs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
> > +#define PIDFD_FID_LEN 3
> > +
> > +struct pidfd_fid {
> > + u64 ino;
> > + s32 pid;
> > +} __packed;
> > +
> > +static int pidfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
> > struct inode *parent)
> > {
> > struct pid *pid = inode->i_private;
> > -
> > - if (*max_len < 2) {
> > - *max_len = 2;
> > + struct pidfd_fid *fid = (struct pidfd_fid *)fh;
> > +
> > + if (*max_len < PIDFD_FID_LEN) {
> > + *max_len = PIDFD_FID_LEN;
> > return FILEID_INVALID;
> > }
> >
> > - *max_len = 2;
> > - *(u64 *)fh = pid->ino;
> > - return FILEID_KERNFS;
> > + fid->ino = pid->ino;
> > + fid->pid = pid_nr(pid);
>
> I worry a little here. A container being able to discover its pid in
> the root namespace seems a little sketchy. This makes that fairly
> simple to figure out.
>
> Maybe generate a random 32 bit value at boot time, and then xor that
> into this? Then you could just reverse that and look up the pid.
>
I don't like playing pseudo cryptographic games, we are not
crypto experts so we are bound to lose in this game.
My thinking is the other way around -
- encode FILEID_INO32_GEN with pid_nr + i_generation
- pid_nr is obviously not unique across pidns and reusable
but that makes it just like i_ino across filesystems
- the resulting file handle is thus usable only in the pidns where
it was encoded - is that a bad thing?
Erin,
You write that "To ensure file handles are invariant and can move
between pid namespaces, we stash a pid from the initial namespace
inside the file handle."
Why is it a requirement for userspace that pidfs file handles are
invariant to pidns?
Thanks,
Amir.
Powered by blists - more mailing lists