From 7b15d6cf25e6c2aea77129179b75c191b20d79a9 Mon Sep 17 00:00:00 2001 From: Hengyu Liang Date: Sat, 22 Aug 2026 01:17:05 -0400 Subject: [PATCH] kernfs: preserve security xattrs without allocating iattrs Commit d5e81a5650b5 ("kernfs: avoid iattr allocation in listxattr") made kernfs_iop_listxattr() return an empty list when the kernfs node has no allocated kernfs_iattrs. However, this also skips security xattr names provided by simple_xattr_list(). As of now, applications can retrieve the SELinux label of a sysfs file with getxattr(), but cannot do it through listxattr(). A similar issue happened before in commit b09e0fa4b4ea ("tmpfs: implement generic xattr support"). It was fixed by commit 8b0ba61df5a1c ("fs/xattr.c: fix simple_xattr_list to always include security.* xattrs"). Perhaps this recent commit needs a fix as well. The issue can be reproduced with a simple python program: python3 - <<'PY' import os path = "/sys/kernel/warn_count" print("getxattr:", os.getxattr(path, "security.selinux")) print("listxattr:", os.listxattr(path)) PY Before commit d5e81a5650b5 ("kernfs: avoid iattr allocation in listxattr"), the result is: getxattr: b'system_u:object_r:sysfs_t:s0\x00' listxattr: ['security.selinux'] After that commit, the result is: getxattr: b'system_u:object_r:sysfs_t:s0\x00' listxattr: [] This patch will keep listxattr() consistent with getxattr() when security xattrs are available. Fixes: d5e81a5650b5 ("kernfs: avoid iattr allocation in listxattr") Signed-off-by: Hengyu Liang Acked-by: Tejun Heo Link: https://patch.msgid.link/20260822051705.1761850-1-hengyul@cs.unc.edu Signed-off-by: Danilo Krummrich --- fs/kernfs/inode.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 237dcdd73fc2..abb286bc3474 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -142,10 +142,8 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) struct kernfs_iattrs *attrs; attrs = kernfs_iattrs_noalloc(kn); - if (!attrs) - return 0; - return simple_xattr_list(d_inode(dentry), &attrs->xattrs, buf, size); + return simple_xattr_list(d_inode(dentry), attrs ? &attrs->xattrs : NULL, buf, size); } static inline void set_default_inode_attr(struct inode *inode, umode_t mode)