From 4207c1115d11f40a9cb045bb61128fe49ad760e7 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Wed, 13 Mar 2019 18:38:51 +0000 Subject: [PATCH] bpf: implement decoding of BPF_TASK_FD_QUERY command BPF_TASK_FD_QUERY command was introduced by Linux commit v4.18-rc1~114^2~148^2~1^2~5. * bpf_attr.h (struct BPF_TASK_FD_QUERY_struct): New type. (BPF_TASK_FD_QUERY_struct_size, expected_BPF_TASK_FD_QUERY_struct_size): New macros. * bpf.c: Include "xlat/bpf_task_fd_type.h". (BEGIN_BPF_CMD_DECODER(BPF_TASK_FD_QUERY)): New bpf command decoder. (SYS_FUNC(bpf)) : Add BPF_CMD_ENTRY(BPF_TASK_FD_QUERY). * xlat/bpf_task_fd_type.in: New file. * tests/bpf.c (union bpf_attr_data): Add BPF_ATTR_DATA_FIELD(BPF_TASK_FD_QUERY). (BPF_TASK_FD_QUERY_checks): New checks array. (main) : Add CHK(BPF_TASK_FD_QUERY). --- bpf.c | 34 ++++++++++++++++++++++++++++++++++ bpf_attr.h | 16 ++++++++++++++++ tests/bpf.c | 36 ++++++++++++++++++++++++++++++++++++ xlat/bpf_task_fd_type.in | 7 +++++++ 4 files changed, 93 insertions(+) create mode 100644 xlat/bpf_task_fd_type.in diff --git a/bpf.c b/bpf.c index 0bb02279..5f944cf0 100644 --- a/bpf.c +++ b/bpf.c @@ -27,6 +27,7 @@ #include "xlat/bpf_attach_type.h" #include "xlat/bpf_attach_flags.h" #include "xlat/bpf_query_flags.h" +#include "xlat/bpf_task_fd_type.h" #include "xlat/ebpf_regs.h" #include "xlat/numa_node.h" @@ -845,6 +846,38 @@ BEGIN_BPF_CMD_DECODER(BPF_BTF_GET_FD_BY_ID) } END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD) +BEGIN_BPF_CMD_DECODER(BPF_TASK_FD_QUERY) +{ + if (entering(tcp)) { + set_tcb_priv_ulong(tcp, attr.buf_len); + + PRINT_FIELD_U("{task_fd_query={", attr, pid); + PRINT_FIELD_FD(", ", attr, fd, tcp); + PRINT_FIELD_U(", ", attr, flags); + PRINT_FIELD_U(", ", attr, buf_len); + + return 0; + } + + unsigned int saved_buf_len = get_tcb_priv_ulong(tcp); + + if (saved_buf_len != attr.buf_len) + tprintf(" => %u", attr.buf_len); + + const unsigned int buf_len = MIN(saved_buf_len, attr.buf_len); + tprintf(", buf="); + print_big_u64_addr(attr.buf); + printstr_ex(tcp, attr.buf, buf_len, QUOTE_0_TERMINATED); + PRINT_FIELD_U(", ", attr, prog_id); + PRINT_FIELD_XVAL_INDEX(", ", attr, fd_type, bpf_task_fd_type, + "BPF_FD_TYPE_???"); + PRINT_FIELD_X(", ", attr, probe_offset); + PRINT_FIELD_X(", ", attr, probe_addr); + + tprints("}"); +} +END_BPF_CMD_DECODER(RVAL_DECODED) + SYS_FUNC(bpf) { static const bpf_cmd_decoder_t bpf_cmd_decoders[] = { @@ -868,6 +901,7 @@ SYS_FUNC(bpf) BPF_CMD_ENTRY(BPF_RAW_TRACEPOINT_OPEN), BPF_CMD_ENTRY(BPF_BTF_LOAD), BPF_CMD_ENTRY(BPF_BTF_GET_FD_BY_ID), + BPF_CMD_ENTRY(BPF_TASK_FD_QUERY), BPF_CMD_ENTRY(BPF_MAP_LOOKUP_AND_DELETE_ELEM), }; diff --git a/bpf_attr.h b/bpf_attr.h index 37ddc41b..f9ca310e 100644 --- a/bpf_attr.h +++ b/bpf_attr.h @@ -247,6 +247,22 @@ struct BPF_BTF_GET_FD_BY_ID_struct { sizeof(struct BPF_BTF_GET_FD_BY_ID_struct) # define expected_BPF_BTF_GET_FD_BY_ID_struct_size 4 +struct BPF_TASK_FD_QUERY_struct /* task_fd_query */ { + uint32_t pid; + uint32_t fd; + uint32_t flags; + uint32_t buf_len; + uint64_t ATTRIBUTE_ALIGNED(8) buf; + uint32_t prog_id; + uint32_t fd_type; + uint64_t ATTRIBUTE_ALIGNED(8) probe_offset; + uint64_t ATTRIBUTE_ALIGNED(8) probe_addr; +}; + +# define BPF_TASK_FD_QUERY_struct_size \ + sizeof(struct BPF_TASK_FD_QUERY_struct) +# define expected_BPF_TASK_FD_QUERY_struct_size 48 + struct bpf_map_info_struct { uint32_t type; uint32_t id; diff --git a/tests/bpf.c b/tests/bpf.c index 5c04a825..ba562b4a 100644 --- a/tests/bpf.c +++ b/tests/bpf.c @@ -73,6 +73,7 @@ union bpf_attr_data { BPF_ATTR_DATA_FIELD(BPF_RAW_TRACEPOINT_OPEN); BPF_ATTR_DATA_FIELD(BPF_BTF_LOAD); BPF_ATTR_DATA_FIELD(BPF_BTF_GET_FD_BY_ID); + BPF_ATTR_DATA_FIELD(BPF_TASK_FD_QUERY); char char_data[256]; }; @@ -1128,6 +1129,40 @@ static const struct bpf_attr_check BPF_BTF_GET_FD_BY_ID_checks[] = { } }; +static const struct bpf_attr_check BPF_TASK_FD_QUERY_checks[] = { + { + .data = { .BPF_TASK_FD_QUERY_data = { .pid = 0xdeadbeef } }, + .size = offsetofend(struct BPF_TASK_FD_QUERY_struct, pid), + .str = "task_fd_query={pid=3735928559, fd=0, flags=0" + ", buf_len=0, buf=NULL, prog_id=0" + ", fd_type=BPF_FD_TYPE_RAW_TRACEPOINT" + ", probe_offset=0, probe_addr=0}" + }, + { /* 1 */ + .data = { .BPF_TASK_FD_QUERY_data = { + .pid = 0xcafef00d, + .fd = 0xdeadbeef, + .flags = 0xfacefeed, + .buf_len = 0xdefaced, + .buf = 0xfffffffffffffffe, + .prog_id = 0xbadc0ded, + .fd_type = 5, + .probe_offset = 0xfac1fed2fac3fed4, + .probe_addr = 0xfac5fed5fac7fed8 + } }, + .size = offsetofend(struct BPF_TASK_FD_QUERY_struct, probe_addr), + .str = "task_fd_query={pid=3405705229" + ", fd=-559038737" + ", flags=4207869677" + ", buf_len=233811181" + ", buf=" BIG_ADDR("0xfffffffffffffffe", "0xfffffffe") + ", prog_id=3134983661" + ", fd_type=BPF_FD_TYPE_URETPROBE" + ", probe_offset=0xfac1fed2fac3fed4" + ", probe_addr=0xfac5fed5fac7fed8}" + } +}; + #define CHK(cmd_) \ { \ @@ -1160,6 +1195,7 @@ main(void) CHK(BPF_RAW_TRACEPOINT_OPEN), CHK(BPF_BTF_LOAD), CHK(BPF_BTF_GET_FD_BY_ID), + CHK(BPF_TASK_FD_QUERY), CHK(BPF_MAP_LOOKUP_AND_DELETE_ELEM), }; diff --git a/xlat/bpf_task_fd_type.in b/xlat/bpf_task_fd_type.in new file mode 100644 index 00000000..33e89ada --- /dev/null +++ b/xlat/bpf_task_fd_type.in @@ -0,0 +1,7 @@ +#value_indexed +BPF_FD_TYPE_RAW_TRACEPOINT 0 +BPF_FD_TYPE_TRACEPOINT 1 +BPF_FD_TYPE_KPROBE 2 +BPF_FD_TYPE_KRETPROBE 3 +BPF_FD_TYPE_UPROBE 4 +BPF_FD_TYPE_URETPROBE 5 -- 2.50.1