Skip to content

Commit

Permalink
bpf: Add d_path helper
Browse files Browse the repository at this point in the history
Adding d_path helper function that returns full path for
given 'struct path' object, which needs to be the kernel
BTF 'path' object. The path is returned in buffer provided
'buf' of size 'sz' and is zero terminated.

  bpf_d_path(&file->f_path, buf, size);

The helper calls directly d_path function, so there's only
limited set of function it can be called from. Adding just
very modest set for the start.

Updating also bpf.h tools uapi header and adding 'path' to
bpf_helpers_doc.py script.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: KP Singh <kpsingh@google.com>
Link: https://lore.kernel.org/bpf/20200825192124.710397-11-jolsa@kernel.org
  • Loading branch information
olsajiri authored and Alexei Starovoitov committed Aug 25, 2020
1 parent eae2e83 commit 6e22ab9
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
14 changes: 14 additions & 0 deletions include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -3513,6 +3513,7 @@ union bpf_attr {
*
* **-EPERM** This helper cannot be used under the
* current sock_ops->op.
*
* void *bpf_inode_storage_get(struct bpf_map *map, void *inode, void *value, u64 flags)
* Description
* Get a bpf_local_storage from an *inode*.
Expand Down Expand Up @@ -3548,6 +3549,18 @@ union bpf_attr {
* 0 on success.
*
* **-ENOENT** if the bpf_local_storage cannot be found.
*
* long bpf_d_path(struct path *path, char *buf, u32 sz)
* Description
* Return full path for given 'struct path' object, which
* needs to be the kernel BTF 'path' object. The path is
* returned in the provided buffer 'buf' of size 'sz' and
* is zero terminated.
*
* Return
* On success, the strictly positive length of the string,
* including the trailing NUL character. On error, a negative
* value.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
Expand Down Expand Up @@ -3697,6 +3710,7 @@ union bpf_attr {
FN(reserve_hdr_opt), \
FN(inode_storage_get), \
FN(inode_storage_delete), \
FN(d_path), \
/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
Expand Down
48 changes: 48 additions & 0 deletions kernel/trace/bpf_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,52 @@ static const struct bpf_func_proto bpf_send_signal_thread_proto = {
.arg1_type = ARG_ANYTHING,
};

BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz)
{
long len;
char *p;

if (!sz)
return 0;

p = d_path(path, buf, sz);
if (IS_ERR(p)) {
len = PTR_ERR(p);
} else {
len = buf + sz - p;
memmove(buf, p, len);
}

return len;
}

BTF_SET_START(btf_allowlist_d_path)
BTF_ID(func, vfs_truncate)
BTF_ID(func, vfs_fallocate)
BTF_ID(func, dentry_open)
BTF_ID(func, vfs_getattr)
BTF_ID(func, filp_close)
BTF_SET_END(btf_allowlist_d_path)

static bool bpf_d_path_allowed(const struct bpf_prog *prog)
{
return btf_id_set_contains(&btf_allowlist_d_path, prog->aux->attach_btf_id);
}

BTF_ID_LIST(bpf_d_path_btf_ids)
BTF_ID(struct, path)

static const struct bpf_func_proto bpf_d_path_proto = {
.func = bpf_d_path,
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_BTF_ID,
.arg2_type = ARG_PTR_TO_MEM,
.arg3_type = ARG_CONST_SIZE_OR_ZERO,
.btf_id = bpf_d_path_btf_ids,
.allowed = bpf_d_path_allowed,
};

const struct bpf_func_proto *
bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
Expand Down Expand Up @@ -1579,6 +1625,8 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return prog->expected_attach_type == BPF_TRACE_ITER ?
&bpf_seq_write_proto :
NULL;
case BPF_FUNC_d_path:
return &bpf_d_path_proto;
default:
return raw_tp_prog_func_proto(func_id, prog);
}
Expand Down
2 changes: 2 additions & 0 deletions scripts/bpf_helpers_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ class PrinterHelpers(Printer):
'struct __sk_buff',
'struct sk_msg_md',
'struct xdp_md',
'struct path',
]
known_types = {
'...',
Expand Down Expand Up @@ -472,6 +473,7 @@ class PrinterHelpers(Printer):
'struct tcp_request_sock',
'struct udp6_sock',
'struct task_struct',
'struct path',
}
mapped_types = {
'u8': '__u8',
Expand Down
14 changes: 14 additions & 0 deletions tools/include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -3513,6 +3513,7 @@ union bpf_attr {
*
* **-EPERM** This helper cannot be used under the
* current sock_ops->op.
*
* void *bpf_inode_storage_get(struct bpf_map *map, void *inode, void *value, u64 flags)
* Description
* Get a bpf_local_storage from an *inode*.
Expand Down Expand Up @@ -3548,6 +3549,18 @@ union bpf_attr {
* 0 on success.
*
* **-ENOENT** if the bpf_local_storage cannot be found.
*
* long bpf_d_path(struct path *path, char *buf, u32 sz)
* Description
* Return full path for given 'struct path' object, which
* needs to be the kernel BTF 'path' object. The path is
* returned in the provided buffer 'buf' of size 'sz' and
* is zero terminated.
*
* Return
* On success, the strictly positive length of the string,
* including the trailing NUL character. On error, a negative
* value.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
Expand Down Expand Up @@ -3697,6 +3710,7 @@ union bpf_attr {
FN(reserve_hdr_opt), \
FN(inode_storage_get), \
FN(inode_storage_delete), \
FN(d_path), \
/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
Expand Down

0 comments on commit 6e22ab9

Please sign in to comment.