diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-07-22 13:50:53 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-07-22 13:55:20 +0200 |
| commit | bb6bc13c53e211d9148ed2eab3e689c5cd5c75da (patch) | |
| tree | b1d8de2deb8001a3a10ab58d2db12ddd620a4fa9 | |
| parent | a8e72879cd0d8422c0b47d6d3c1802274fe73b98 (diff) | |
pidfs: preserve thread pidfds reopened by file handle
PIDFD_THREAD shares O_EXCL. do_dentry_open() clears O_EXCL after
pidfs_export_open() validates the flags, so open_by_handle_at()
silently turns a thread pidfd into a process pidfd.
Restore PIDFD_THREAD on the opened file, matching pidfs_alloc_file().
Signed-off-by: Li Chen <me@linux.beauty>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260716052726.1032092-1-me@linux.beauty
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
| -rw-r--r-- | fs/pidfs.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/pidfs.c b/fs/pidfs.c index aaa609ddab04..c20ffd747ff5 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -939,12 +939,18 @@ static int pidfs_export_permission(struct handle_to_path_ctx *ctx, static struct file *pidfs_export_open(const struct path *path, unsigned int oflags) { + struct file *file; + /* * Clear O_LARGEFILE as open_by_handle_at() forces it and raise * O_RDWR as pidfds always are. */ oflags &= ~O_LARGEFILE; - return dentry_open(path, oflags | O_RDWR, current_cred()); + file = dentry_open(path, oflags | O_RDWR, current_cred()); + /* do_dentry_open() strips O_EXCL, which encodes PIDFD_THREAD. */ + if (!IS_ERR(file)) + file->f_flags |= oflags & PIDFD_THREAD; + return file; } static const struct export_operations pidfs_export_operations = { |
