From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org
Cc: "Jann Horn" <jannh@google.com>,
"Josef Bacik" <josef@toxicpanda.com>,
"Jeff Layton" <jlayton@kernel.org>,
"Daan De Meyer" <daan.j.demeyer@gmail.com>,
"Lennart Poettering" <lennart@poettering.net>,
"Mike Yuan" <me@yhndnzj.com>,
"Zbigniew Jędrzejewski-Szmek" <zbyszek@in.waw.pl>,
"Christian Brauner" <brauner@kernel.org>,
"Alexander Mikhalitsyn" <alexander@mihalicyn.com>
Subject: [PATCH RFC 4/7] pidfs: support xattrs on pidfds
Date: Tue, 17 Jun 2025 17:45:14 +0200 [thread overview]
Message-ID: <20250617-work-pidfs-xattr-v1-4-d9466a20da2e@kernel.org> (raw)
In-Reply-To: <20250617-work-pidfs-xattr-v1-0-d9466a20da2e@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
fs/pidfs.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 92 insertions(+), 2 deletions(-)
diff --git a/fs/pidfs.c b/fs/pidfs.c
index 1343bfc60e3f..b1968f628417 100644
--- a/fs/pidfs.c
+++ b/fs/pidfs.c
@@ -21,6 +21,7 @@
#include <linux/utsname.h>
#include <net/net_namespace.h>
#include <linux/coredump.h>
+#include <linux/xattr.h>
#include "internal.h"
#include "mount.h"
@@ -40,6 +41,7 @@
#define PIDFS_PID_DEAD ERR_PTR(-ESRCH)
static struct kmem_cache *pidfs_cachep __ro_after_init;
+static struct kmem_cache *pidfs_attrs_cachep __ro_after_init;
/*
* Stashes information that userspace needs to access even after the
@@ -51,9 +53,14 @@ struct pidfs_exit_info {
__u32 coredump_mask;
};
+struct pidfs_attrs {
+ struct simple_xattrs xattrs;
+};
+
struct pidfs_inode {
struct pidfs_exit_info __pei;
struct pidfs_exit_info *exit_info;
+ struct pidfs_attrs *attrs;
struct inode vfs_inode;
};
@@ -672,15 +679,34 @@ static int pidfs_getattr(struct mnt_idmap *idmap, const struct path *path,
return anon_inode_getattr(idmap, path, stat, request_mask, query_flags);
}
+static ssize_t pidfs_listxattr(struct dentry *dentry, char *buf, size_t size)
+{
+ struct inode *inode = d_inode(dentry);
+ struct pidfs_attrs *attrs;
+
+ attrs = READ_ONCE(pidfs_i(inode)->attrs);
+ if (!attrs)
+ return -ENODATA;
+
+ return simple_xattr_list(inode, &attrs->xattrs, buf, size);
+}
+
static const struct inode_operations pidfs_inode_operations = {
- .getattr = pidfs_getattr,
- .setattr = pidfs_setattr,
+ .getattr = pidfs_getattr,
+ .setattr = pidfs_setattr,
+ .listxattr = pidfs_listxattr,
};
static void pidfs_evict_inode(struct inode *inode)
{
struct pid *pid = inode->i_private;
+ struct pidfs_attrs *attrs;
+ attrs = READ_ONCE(pidfs_i(inode)->attrs);
+ if (attrs) {
+ simple_xattrs_free(&attrs->xattrs, NULL);
+ kmem_cache_free(pidfs_attrs_cachep, attrs);
+ }
clear_inode(inode);
put_pid(pid);
}
@@ -695,6 +721,7 @@ static struct inode *pidfs_alloc_inode(struct super_block *sb)
memset(&pi->__pei, 0, sizeof(pi->__pei));
pi->exit_info = NULL;
+ pi->attrs = NULL;
return &pi->vfs_inode;
}
@@ -951,6 +978,63 @@ static const struct stashed_operations pidfs_stashed_ops = {
.put_data = pidfs_put_data,
};
+static int pidfs_xattr_get(const struct xattr_handler *handler,
+ struct dentry *unused, struct inode *inode,
+ const char *suffix, void *value, size_t size)
+{
+ const char *name;
+ struct pidfs_attrs *attrs;
+
+ attrs = READ_ONCE(pidfs_i(inode)->attrs);
+ if (!attrs)
+ return -ENODATA;
+
+ name = xattr_full_name(handler, suffix);
+ return simple_xattr_get(&attrs->xattrs, name, value, size);
+}
+
+static int pidfs_xattr_set(const struct xattr_handler *handler,
+ struct mnt_idmap *idmap, struct dentry *unused,
+ struct inode *inode, const char *suffix,
+ const void *value, size_t size, int flags)
+{
+ const char *name;
+ struct pidfs_attrs *attrs;
+ struct simple_xattr *old_xattr;
+
+ /* Make sure we're the only one here. */
+ WARN_ON_ONCE(!inode_is_locked(inode));
+
+ attrs = READ_ONCE(pidfs_i(inode)->attrs);
+ if (!attrs) {
+ attrs = kmem_cache_zalloc(pidfs_attrs_cachep, GFP_KERNEL);
+ if (!attrs)
+ return -ENOMEM;
+
+ simple_xattrs_init(&attrs->xattrs);
+ smp_store_release(&pidfs_i(inode)->attrs, attrs);
+ }
+
+ name = xattr_full_name(handler, suffix);
+ old_xattr = simple_xattr_set(&attrs->xattrs, name, value, size, flags);
+ if (IS_ERR(old_xattr))
+ return PTR_ERR(old_xattr);
+
+ simple_xattr_free(old_xattr);
+ return 0;
+}
+
+static const struct xattr_handler pidfs_trusted_xattr_handler = {
+ .prefix = XATTR_TRUSTED_PREFIX,
+ .get = pidfs_xattr_get,
+ .set = pidfs_xattr_set,
+};
+
+static const struct xattr_handler *const pidfs_xattr_handlers[] = {
+ &pidfs_trusted_xattr_handler,
+ NULL
+};
+
static int pidfs_init_fs_context(struct fs_context *fc)
{
struct pseudo_fs_context *ctx;
@@ -964,6 +1048,7 @@ static int pidfs_init_fs_context(struct fs_context *fc)
ctx->ops = &pidfs_sops;
ctx->eops = &pidfs_export_operations;
ctx->dops = &pidfs_dentry_operations;
+ ctx->xattr = pidfs_xattr_handlers;
fc->s_fs_info = (void *)&pidfs_stashed_ops;
return 0;
}
@@ -1073,6 +1158,11 @@ void __init pidfs_init(void)
(SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT |
SLAB_ACCOUNT | SLAB_PANIC),
pidfs_inode_init_once);
+
+ pidfs_attrs_cachep = kmem_cache_create("pidfs_attrs_cache",
+ sizeof(struct pidfs_attrs), 0,
+ SLAB_PANIC, NULL);
+
pidfs_mnt = kern_mount(&pidfs_type);
if (IS_ERR(pidfs_mnt))
panic("Failed to mount pidfs pseudo filesystem");
--
2.47.2
next prev parent reply other threads:[~2025-06-17 15:45 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-17 15:45 [PATCH RFC 0/7] pidfs: support extended attributes Christian Brauner
2025-06-17 15:45 ` [PATCH RFC 1/7] libfs: prepare to allow for non-immutable pidfd inodes Christian Brauner
2025-06-18 19:44 ` Alexander Mikhalitsyn
2025-06-17 15:45 ` [PATCH RFC 2/7] pidfs: make inodes mutable Christian Brauner
2025-06-18 19:43 ` Alexander Mikhalitsyn
2025-06-17 15:45 ` [PATCH RFC 3/7] pidfs: raise SB_I_NODEV and SB_I_NOEXEC Christian Brauner
2025-06-18 19:46 ` Alexander Mikhalitsyn
2025-06-17 15:45 ` Christian Brauner [this message]
2025-06-18 19:54 ` [PATCH RFC 4/7] pidfs: support xattrs on pidfds Alexander Mikhalitsyn
2025-06-17 15:45 ` [PATCH RFC 5/7] selftests/pidfd: test extended attribute support Christian Brauner
2025-06-17 15:45 ` [PATCH RFC 6/7] " Christian Brauner
2025-06-17 15:45 ` [PATCH RFC 7/7] selftests/pidfd: test setattr support Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250617-work-pidfs-xattr-v1-4-d9466a20da2e@kernel.org \
--to=brauner@kernel.org \
--cc=alexander@mihalicyn.com \
--cc=daan.j.demeyer@gmail.com \
--cc=jannh@google.com \
--cc=jlayton@kernel.org \
--cc=josef@toxicpanda.com \
--cc=lennart@poettering.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=me@yhndnzj.com \
--cc=zbyszek@in.waw.pl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).