Skip to content

Commit 4770584

Browse files
committed
pidfs: register pid in pidfs
Add simple helpers that allow a struct pid to be pinned via a pidfs dentry/inode. If no pidfs dentry exists a new one will be allocated for it. A reference is taken by pidfs on @pid. The reference must be released via pidfs_put_pid(). This will allow AF_UNIX sockets to allocate a dentry for the peer credentials pid at the time they are recorded where we know the task is still alive. When the task gets reaped its exit status is guaranteed to be recorded and a pidfd can be handed out for the reaped task. Link: https://lore.kernel.org/[email protected] Reviewed-by: Oleg Nesterov <[email protected]> Reviewed-by: David Rheinsberg <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent b590c92 commit 4770584

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

fs/pidfs.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,65 @@ struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags)
896896
return pidfd_file;
897897
}
898898

899+
/**
900+
* pidfs_register_pid - register a struct pid in pidfs
901+
* @pid: pid to pin
902+
*
903+
* Register a struct pid in pidfs. Needs to be paired with
904+
* pidfs_put_pid() to not risk leaking the pidfs dentry and inode.
905+
*
906+
* Return: On success zero, on error a negative error code is returned.
907+
*/
908+
int pidfs_register_pid(struct pid *pid)
909+
{
910+
struct path path __free(path_put) = {};
911+
int ret;
912+
913+
might_sleep();
914+
915+
if (!pid)
916+
return 0;
917+
918+
ret = path_from_stashed(&pid->stashed, pidfs_mnt, get_pid(pid), &path);
919+
if (unlikely(ret))
920+
return ret;
921+
/* Keep the dentry and only put the reference to the mount. */
922+
path.dentry = NULL;
923+
return 0;
924+
}
925+
926+
/**
927+
* pidfs_get_pid - pin a struct pid through pidfs
928+
* @pid: pid to pin
929+
*
930+
* Similar to pidfs_register_pid() but only valid if the caller knows
931+
* there's a reference to the @pid through a dentry already that can't
932+
* go away.
933+
*/
934+
void pidfs_get_pid(struct pid *pid)
935+
{
936+
if (!pid)
937+
return;
938+
WARN_ON_ONCE(!stashed_dentry_get(&pid->stashed));
939+
}
940+
941+
/**
942+
* pidfs_put_pid - drop a pidfs reference
943+
* @pid: pid to drop
944+
*
945+
* Drop a reference to @pid via pidfs. This is only safe if the
946+
* reference has been taken via pidfs_get_pid().
947+
*/
948+
void pidfs_put_pid(struct pid *pid)
949+
{
950+
might_sleep();
951+
952+
if (!pid)
953+
return;
954+
VFS_WARN_ON_ONCE(!pid->stashed);
955+
dput(pid->stashed);
956+
}
957+
899958
static void pidfs_inode_init_once(void *data)
900959
{
901960
struct pidfs_inode *pi = data;

include/linux/pidfs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@ void pidfs_add_pid(struct pid *pid);
88
void pidfs_remove_pid(struct pid *pid);
99
void pidfs_exit(struct task_struct *tsk);
1010
extern const struct dentry_operations pidfs_dentry_operations;
11+
int pidfs_register_pid(struct pid *pid);
12+
void pidfs_get_pid(struct pid *pid);
13+
void pidfs_put_pid(struct pid *pid);
1114

1215
#endif /* _LINUX_PID_FS_H */

0 commit comments

Comments
 (0)