@@ -2777,6 +2777,18 @@ union bpf_attr {
* restricted to raw_tracepoint bpf programs.
* Return
* 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_get_file_path(char *path, u32 size, int fd)
+ * Description
+ * Get **file** atrribute from the current task by *fd*, then call
+ * **d_path** to get it's absolute path and copy it as string into
+ * *path* of *size*. The **path** also support pseudo filesystems
+ * (whether or not it can be mounted). The *size* must be strictly
+ * positive. On success, the helper makes sure that the *path* is
+ * NUL-terminated. On failure, it is filled with zeroes.
+ * Return
+ * On success, returns the length of the copied string INCLUDING
+ * the trailing NUL, or a negative error in case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -2890,7 +2902,8 @@ union bpf_attr {
FN(sk_storage_delete), \
FN(send_signal), \
FN(tcp_gen_syncookie), \
- FN(skb_output),
+ FN(skb_output), \
+ FN(get_file_path),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
@@ -683,6 +683,52 @@ static const struct bpf_func_proto bpf_send_signal_proto = {
.arg1_type = ARG_ANYTHING,
};
+BPF_CALL_3(bpf_get_file_path, char *, dst, u32, size, int, fd)
+{
+ struct fd f;
+ char *p;
+ int ret = -EBADF;
+
+ /* Use fdget_raw instead of fdget to support O_PATH, and
+ * fdget_raw doesn't have any sleepable code, so it's ok
+ * to be here.
+ */
+ f = fdget_raw(fd);
+ if (!f.file)
+ goto error;
+
+ /* d_path doesn't have any sleepable code, so it's ok to
+ * be here. But it uses the current macro to get fs_struct
+ * (current->fs). So this helper shouldn't be called in
+ * interrupt context.
+ */
+ p = d_path(&f.file->f_path, dst, size);
+ if (IS_ERR(p)) {
+ ret = PTR_ERR(p);
+ fdput(f);
+ goto error;
+ }
+
+ ret = strlen(p);
+ memmove(dst, p, ret);
+ dst[ret++] = '\0';
+ fdput(f);
+ return ret;
+
+error:
+ memset(dst, '0', size);
+ return ret;
+}
+
+static const struct bpf_func_proto bpf_get_file_path_proto = {
+ .func = bpf_get_file_path,
+ .gpl_only = true,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_UNINIT_MEM,
+ .arg2_type = ARG_CONST_SIZE,
+ .arg3_type = ARG_ANYTHING,
+};
+
static const struct bpf_func_proto *
tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
@@ -735,6 +781,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
#endif
case BPF_FUNC_send_signal:
return &bpf_send_signal_proto;
+ case BPF_FUNC_get_file_path:
+ return &bpf_get_file_path_proto;
default:
return NULL;
}
@@ -2777,6 +2777,18 @@ union bpf_attr {
* restricted to raw_tracepoint bpf programs.
* Return
* 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_get_file_path(char *path, u32 size, int fd)
+ * Description
+ * Get **file** atrribute from the current task by *fd*, then call
+ * **d_path** to get it's absolute path and copy it as string into
+ * *path* of *size*. The **path** also support pseudo filesystems
+ * (whether or not it can be mounted). The *size* must be strictly
+ * positive. On success, the helper makes sure that the *path* is
+ * NUL-terminated. On failure, it is filled with zeroes.
+ * Return
+ * On success, returns the length of the copied string INCLUDING
+ * the trailing NUL, or a negative error in case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -2890,7 +2902,8 @@ union bpf_attr {
FN(sk_storage_delete), \
FN(send_signal), \
FN(tcp_gen_syncookie), \
- FN(skb_output),
+ FN(skb_output), \
+ FN(get_file_path),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call