Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs/xattr: bpf: Introduce security.bpf. xattr name prefix

Introduct new xattr name prefix security.bpf., and enable reading these
xattrs from bpf kfuncs bpf_get_[file|dentry]_xattr().

As we are on it, correct the comments for return value of
bpf_get_[file|dentry]_xattr(), i.e. return length the xattr value on
success.

Signed-off-by: Song Liu <song@kernel.org>
Acked-by: Christian Brauner <brauner@kernel.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Matt Bobrowski <mattbobrowski@google.com>
Link: https://lore.kernel.org/r/20250130213549.3353349-2-song@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Song Liu and committed by
Alexei Starovoitov
531118f1 b99f27e9

+29 -11
+25 -11
fs/bpf_fs_kfuncs.c
··· 93 93 return len; 94 94 } 95 95 96 + static bool match_security_bpf_prefix(const char *name__str) 97 + { 98 + return !strncmp(name__str, XATTR_NAME_BPF_LSM, XATTR_NAME_BPF_LSM_LEN); 99 + } 100 + 101 + static int bpf_xattr_read_permission(const char *name, struct inode *inode) 102 + { 103 + if (WARN_ON(!inode)) 104 + return -EINVAL; 105 + 106 + /* Allow reading xattr with user. and security.bpf. prefix */ 107 + if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && 108 + !match_security_bpf_prefix(name)) 109 + return -EPERM; 110 + 111 + return inode_permission(&nop_mnt_idmap, inode, MAY_READ); 112 + } 113 + 96 114 /** 97 115 * bpf_get_dentry_xattr - get xattr of a dentry 98 116 * @dentry: dentry to get xattr from ··· 119 101 * 120 102 * Get xattr *name__str* of *dentry* and store the output in *value_ptr*. 121 103 * 122 - * For security reasons, only *name__str* with prefix "user." is allowed. 104 + * For security reasons, only *name__str* with prefixes "user." or 105 + * "security.bpf." are allowed. 123 106 * 124 - * Return: 0 on success, a negative value on error. 107 + * Return: length of the xattr value on success, a negative value on error. 125 108 */ 126 109 __bpf_kfunc int bpf_get_dentry_xattr(struct dentry *dentry, const char *name__str, 127 110 struct bpf_dynptr *value_p) ··· 133 114 void *value; 134 115 int ret; 135 116 136 - if (WARN_ON(!inode)) 137 - return -EINVAL; 138 - 139 - if (strncmp(name__str, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) 140 - return -EPERM; 141 - 142 117 value_len = __bpf_dynptr_size(value_ptr); 143 118 value = __bpf_dynptr_data_rw(value_ptr, value_len); 144 119 if (!value) 145 120 return -EINVAL; 146 121 147 - ret = inode_permission(&nop_mnt_idmap, inode, MAY_READ); 122 + ret = bpf_xattr_read_permission(name__str, inode); 148 123 if (ret) 149 124 return ret; 150 125 return __vfs_getxattr(dentry, inode, name__str, value, value_len); ··· 152 139 * 153 140 * Get xattr *name__str* of *file* and store the output in *value_ptr*. 154 141 * 155 - * For security reasons, only *name__str* with prefix "user." is allowed. 142 + * For security reasons, only *name__str* with prefixes "user." or 143 + * "security.bpf." are allowed. 156 144 * 157 - * Return: 0 on success, a negative value on error. 145 + * Return: length of the xattr value on success, a negative value on error. 158 146 */ 159 147 __bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str, 160 148 struct bpf_dynptr *value_p)
+4
include/uapi/linux/xattr.h
··· 83 83 #define XATTR_CAPS_SUFFIX "capability" 84 84 #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX 85 85 86 + #define XATTR_BPF_LSM_SUFFIX "bpf." 87 + #define XATTR_NAME_BPF_LSM (XATTR_SECURITY_PREFIX XATTR_BPF_LSM_SUFFIX) 88 + #define XATTR_NAME_BPF_LSM_LEN (sizeof(XATTR_NAME_BPF_LSM) - 1) 89 + 86 90 #define XATTR_POSIX_ACL_ACCESS "posix_acl_access" 87 91 #define XATTR_NAME_POSIX_ACL_ACCESS XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_ACCESS 88 92 #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default"