On Wed, Nov 13, 2024 at 1:34 AM Jeff Layton <jlayton@xxxxxxxxxx> 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@xxxxxx> > > --- > > 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.