summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-17 11:02:10 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-17 11:02:10 -0700
commitde03b17ec046d81c4713bc54306579b9024fc513 (patch)
tree1a15783aa1f0662c6563719f2394eecf2ff6a688 /net
parent9ea8d6197d9f43a15ccb9c0dce601ec535d5da7e (diff)
parent8abc1c8badc11c859bb4ba43211611347e59c55c (diff)
downloadlinux-next-de03b17ec046d81c4713bc54306579b9024fc513.tar.gz
linux-next-de03b17ec046d81c4713bc54306579b9024fc513.zip
Merge tag 'vfs-7.3-rc1.kfunc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs bpf access updates from Christian Brauner: "This adds a bpf_sock_read_xattr() kfunc so a BPF LSM program can read a user.* extended attribute from a socket's sockfs inode locklessly. userspace already uses user.* xattrs on sockets to implement socket rate limiting and to tag sockets for other purposes such as a varlink registry. There has been no efficient way for a BPF program to read those labels back. With this a listening socket marked from userspace with fsetxattr() can be read back during bind or connect and acted upon on the connecting socket. That lets userspace mark sockets and later rediscover them or implement policy on them" * tag 'vfs-7.3-rc1.kfunc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: selftests/bpf: Add test for bpf_sock_read_xattr() kfunc fs: Add bpf_sock_read_xattr() kfunc to read socket xattrs
Diffstat (limited to 'net')
-rw-r--r--net/socket.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/net/socket.c b/net/socket.c
index 63c69a0fa74e..b0256cd222f8 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -465,6 +465,31 @@ static const struct xattr_handler sockfs_user_xattr_handler = {
.set = sockfs_user_xattr_set,
};
+/**
+ * sock_read_xattr - read a user.* xattr from a socket's sockfs inode
+ * @sock: socket whose inode holds the xattr
+ * @name: full xattr name, e.g. "user.bpf_test"
+ * @value: output buffer
+ * @size: size of @value in bytes
+ *
+ * SOCK_INODE() is valid only for sockfs sockets; sock_from_file() rejects
+ * anything else (e.g. tun, tap).
+ * Lockless: simple_xattr_get() looks up the value under RCU, no inode lock.
+ *
+ * Return: length of the value on success, a negative errno on error.
+ */
+int sock_read_xattr(struct socket *sock, const char *name, void *value, size_t size)
+{
+ struct file *file = sock->file;
+ struct sockfs_inode *si;
+
+ if (!file || sock_from_file(file) != sock)
+ return -EOPNOTSUPP;
+
+ si = SOCKFS_I(SOCK_INODE(sock));
+ return simple_xattr_get(&sockfs_xa_cache, &si->xattrs, name, value, size);
+}
+
static const struct xattr_handler * const sockfs_xattr_handlers[] = {
&sockfs_xattr_handler,
&sockfs_security_xattr_handler,