Skip to content

Commit ac13a42

Browse files
liu-song-6Alexei Starovoitov
authored and
Alexei Starovoitov
committed
bpf: Add kfunc bpf_get_dentry_xattr() to read xattr from dentry
This kfunc can be used in LSM hooks with dentry, such as: security_inode_listxattr security_inode_permission and many more. Acked-by: Christian Brauner <[email protected]> Signed-off-by: Song Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent fa4e5af commit ac13a42

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

fs/bpf_fs_kfuncs.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,26 +94,29 @@ __bpf_kfunc int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz)
9494
}
9595

9696
/**
97-
* bpf_get_file_xattr - get xattr of a file
98-
* @file: file to get xattr from
97+
* bpf_get_dentry_xattr - get xattr of a dentry
98+
* @dentry: dentry to get xattr from
9999
* @name__str: name of the xattr
100100
* @value_p: output buffer of the xattr value
101101
*
102-
* Get xattr *name__str* of *file* and store the output in *value_ptr*.
102+
* Get xattr *name__str* of *dentry* and store the output in *value_ptr*.
103103
*
104104
* For security reasons, only *name__str* with prefix "user." is allowed.
105105
*
106106
* Return: 0 on success, a negative value on error.
107107
*/
108-
__bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str,
109-
struct bpf_dynptr *value_p)
108+
__bpf_kfunc int bpf_get_dentry_xattr(struct dentry *dentry, const char *name__str,
109+
struct bpf_dynptr *value_p)
110110
{
111111
struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
112-
struct dentry *dentry;
112+
struct inode *inode = d_inode(dentry);
113113
u32 value_len;
114114
void *value;
115115
int ret;
116116

117+
if (WARN_ON(!inode))
118+
return -EINVAL;
119+
117120
if (strncmp(name__str, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
118121
return -EPERM;
119122

@@ -122,11 +125,31 @@ __bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str,
122125
if (!value)
123126
return -EINVAL;
124127

125-
dentry = file_dentry(file);
126-
ret = inode_permission(&nop_mnt_idmap, dentry->d_inode, MAY_READ);
128+
ret = inode_permission(&nop_mnt_idmap, inode, MAY_READ);
127129
if (ret)
128130
return ret;
129-
return __vfs_getxattr(dentry, dentry->d_inode, name__str, value, value_len);
131+
return __vfs_getxattr(dentry, inode, name__str, value, value_len);
132+
}
133+
134+
/**
135+
* bpf_get_file_xattr - get xattr of a file
136+
* @file: file to get xattr from
137+
* @name__str: name of the xattr
138+
* @value_p: output buffer of the xattr value
139+
*
140+
* Get xattr *name__str* of *file* and store the output in *value_ptr*.
141+
*
142+
* For security reasons, only *name__str* with prefix "user." is allowed.
143+
*
144+
* Return: 0 on success, a negative value on error.
145+
*/
146+
__bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str,
147+
struct bpf_dynptr *value_p)
148+
{
149+
struct dentry *dentry;
150+
151+
dentry = file_dentry(file);
152+
return bpf_get_dentry_xattr(dentry, name__str, value_p);
130153
}
131154

132155
__bpf_kfunc_end_defs();
@@ -136,6 +159,7 @@ BTF_ID_FLAGS(func, bpf_get_task_exe_file,
136159
KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL)
137160
BTF_ID_FLAGS(func, bpf_put_file, KF_RELEASE)
138161
BTF_ID_FLAGS(func, bpf_path_d_path, KF_TRUSTED_ARGS)
162+
BTF_ID_FLAGS(func, bpf_get_dentry_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
139163
BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
140164
BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)
141165

0 commit comments

Comments
 (0)