]> granicus.if.org Git - strace/commitdiff
bpf: implement decoding of BPF_TASK_FD_QUERY command
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 13 Mar 2019 18:38:51 +0000 (18:38 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 13 Mar 2019 18:38:51 +0000 (18:38 +0000)
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)) <bpf_cmd_decoders[]>: 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) <checks>: Add CHK(BPF_TASK_FD_QUERY).

bpf.c
bpf_attr.h
tests/bpf.c
xlat/bpf_task_fd_type.in [new file with mode: 0644]

diff --git a/bpf.c b/bpf.c
index 0bb0227974ed070dce8018e027e1a0eddbee9e28..5f944cf05b56db579c21f4f4c2fd121ec17eebad 100644 (file)
--- 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),
        };
 
index 37ddc41b4578bfad1d8a90b59393c779d551e4d5..f9ca310e362de4cd9c1273a3b9b08df19fa2ca14 100644 (file)
@@ -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;
index 5c04a8253b68150cf6c5e8c45ae0be1995039d6a..ba562b4afcc2d67350a7fe7b01e8e6296633f8eb 100644 (file)
@@ -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 (file)
index 0000000..33e89ad
--- /dev/null
@@ -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