1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2024 Google LLC. */
6 #include <linux/btf_ids.h>
7 #include <linux/dcache.h>
9 #include <linux/file.h>
11 #include <linux/xattr.h>
13 __bpf_kfunc_start_defs();
16 * bpf_get_task_exe_file - get a reference on the exe_file struct file member of
17 * the mm_struct that is nested within the supplied
19 * @task: task_struct of which the nested mm_struct exe_file member to get a
22 * Get a reference on the exe_file struct file member field of the mm_struct
23 * nested within the supplied *task*. The referenced file pointer acquired by
24 * this BPF kfunc must be released using bpf_put_file(). Failing to call
25 * bpf_put_file() on the returned referenced struct file pointer that has been
26 * acquired by this BPF kfunc will result in the BPF program being rejected by
29 * This BPF kfunc may only be called from BPF LSM programs.
31 * Internally, this BPF kfunc leans on get_task_exe_file(), such that calling
32 * bpf_get_task_exe_file() would be analogous to calling get_task_exe_file()
33 * directly in kernel context.
35 * Return: A referenced struct file pointer to the exe_file member of the
36 * mm_struct that is nested within the supplied *task*. On error, NULL is
39 __bpf_kfunc
struct file
*bpf_get_task_exe_file(struct task_struct
*task
)
41 return get_task_exe_file(task
);
45 * bpf_put_file - put a reference on the supplied file
46 * @file: file to put a reference on
48 * Put a reference on the supplied *file*. Only referenced file pointers may be
49 * passed to this BPF kfunc. Attempting to pass an unreferenced file pointer, or
50 * any other arbitrary pointer for that matter, will result in the BPF program
51 * being rejected by the BPF verifier.
53 * This BPF kfunc may only be called from BPF LSM programs.
55 __bpf_kfunc
void bpf_put_file(struct file
*file
)
61 * bpf_path_d_path - resolve the pathname for the supplied path
62 * @path: path to resolve the pathname for
63 * @buf: buffer to return the resolved pathname in
64 * @buf__sz: length of the supplied buffer
66 * Resolve the pathname for the supplied *path* and store it in *buf*. This BPF
67 * kfunc is the safer variant of the legacy bpf_d_path() helper and should be
68 * used in place of bpf_d_path() whenever possible. It enforces KF_TRUSTED_ARGS
69 * semantics, meaning that the supplied *path* must itself hold a valid
70 * reference, or else the BPF program will be outright rejected by the BPF
73 * This BPF kfunc may only be called from BPF LSM programs.
75 * Return: A positive integer corresponding to the length of the resolved
76 * pathname in *buf*, including the NUL termination character. On error, a
77 * negative integer is returned.
79 __bpf_kfunc
int bpf_path_d_path(struct path
*path
, char *buf
, size_t buf__sz
)
87 ret
= d_path(path
, buf
, buf__sz
);
91 len
= buf
+ buf__sz
- ret
;
92 memmove(buf
, ret
, len
);
97 * bpf_get_dentry_xattr - get xattr of a dentry
98 * @dentry: dentry to get xattr from
99 * @name__str: name of the xattr
100 * @value_p: output buffer of the xattr value
102 * Get xattr *name__str* of *dentry* and store the output in *value_ptr*.
104 * For security reasons, only *name__str* with prefix "user." is allowed.
106 * Return: 0 on success, a negative value on error.
108 __bpf_kfunc
int bpf_get_dentry_xattr(struct dentry
*dentry
, const char *name__str
,
109 struct bpf_dynptr
*value_p
)
111 struct bpf_dynptr_kern
*value_ptr
= (struct bpf_dynptr_kern
*)value_p
;
112 struct inode
*inode
= d_inode(dentry
);
120 if (strncmp(name__str
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
))
123 value_len
= __bpf_dynptr_size(value_ptr
);
124 value
= __bpf_dynptr_data_rw(value_ptr
, value_len
);
128 ret
= inode_permission(&nop_mnt_idmap
, inode
, MAY_READ
);
131 return __vfs_getxattr(dentry
, inode
, name__str
, value
, value_len
);
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
140 * Get xattr *name__str* of *file* and store the output in *value_ptr*.
142 * For security reasons, only *name__str* with prefix "user." is allowed.
144 * Return: 0 on success, a negative value on error.
146 __bpf_kfunc
int bpf_get_file_xattr(struct file
*file
, const char *name__str
,
147 struct bpf_dynptr
*value_p
)
149 struct dentry
*dentry
;
151 dentry
= file_dentry(file
);
152 return bpf_get_dentry_xattr(dentry
, name__str
, value_p
);
155 __bpf_kfunc_end_defs();
157 BTF_KFUNCS_START(bpf_fs_kfunc_set_ids
)
158 BTF_ID_FLAGS(func
, bpf_get_task_exe_file
,
159 KF_ACQUIRE
| KF_TRUSTED_ARGS
| KF_RET_NULL
)
160 BTF_ID_FLAGS(func
, bpf_put_file
, KF_RELEASE
)
161 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
)
163 BTF_ID_FLAGS(func
, bpf_get_file_xattr
, KF_SLEEPABLE
| KF_TRUSTED_ARGS
)
164 BTF_KFUNCS_END(bpf_fs_kfunc_set_ids
)
166 static int bpf_fs_kfuncs_filter(const struct bpf_prog
*prog
, u32 kfunc_id
)
168 if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids
, kfunc_id
) ||
169 prog
->type
== BPF_PROG_TYPE_LSM
)
174 static const struct btf_kfunc_id_set bpf_fs_kfunc_set
= {
175 .owner
= THIS_MODULE
,
176 .set
= &bpf_fs_kfunc_set_ids
,
177 .filter
= bpf_fs_kfuncs_filter
,
180 static int __init
bpf_fs_kfuncs_init(void)
182 return register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM
, &bpf_fs_kfunc_set
);
185 late_initcall(bpf_fs_kfuncs_init
);