[PATCH] kernfs: preserve security xattrs without allocating iattrs

[email protected]
Newsgroups dev.linux.lists.driver-core,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: Hengyu Liang <[email protected]>

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 <[email protected]>
---
 fs/kernfs/inode.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 237dcdd73fc2..bc3c6b939b0e 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -142,10 +142,9 @@ 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)
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.