From 805d6ea5700cfc5fe09d2e5a2792b63c859916dc Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Thu, 27 Jul 2017 20:11:33 +0000 Subject: [PATCH] bpf: enhance decoding of BPF_MAP_LOOKUP_ELEM and BPF_MAP_GET_NEXT_KEY Print union bpf_attr.value field of BPF_MAP_LOOKUP_ELEM command and union bpf_attr.next_key field of BPF_MAP_GET_NEXT_KEY command on entering syscall. These fields are addresses specified to the kernel from userspace. The amount of data written by the kernel to these addresses is specified at the map creation time by BPF_MAP_CREATE command and is not available at this point. * bpf.c (decode_BPF_MAP_LOOKUP_ELEM): Print union bpf_attr.value on entering syscall. (decode_BPF_MAP_GET_NEXT_KEY): Print union bpf_attr.next_key on entering syscall. (bpf_map_io): Remove. * tests/bpf.c (print_BPF_MAP_DELETE_ELEM_first, print_BPF_MAP_DELETE_ELEM_attr, print_BPF_MAP_GET_NEXT_KEY_first, print_BPF_MAP_GET_NEXT_KEY_attr): Replace macro redirects with new functions. (print_BPF_MAP_LOOKUP_ELEM_first, print_BPF_MAP_LOOKUP_ELEM_attr, --- bpf.c | 62 ++++++++++++++++++++++------------------------------- tests/bpf.c | 30 ++++++++++++++++++++------ 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/bpf.c b/bpf.c index c4f5074e..7734b07a 100644 --- a/bpf.c +++ b/bpf.c @@ -109,6 +109,26 @@ DEF_BPF_CMD_DECODER(BPF_MAP_CREATE) return RVAL_DECODED | RVAL_FD; } +DEF_BPF_CMD_DECODER(BPF_MAP_LOOKUP_ELEM) +{ + struct bpf_io_elem_struct { + uint32_t map_fd; + uint64_t ATTRIBUTE_ALIGNED(8) key, value; + } attr = {}; + + const unsigned int len = size < sizeof(attr) ? size : sizeof(attr); + + memcpy(&attr, data, len); + + PRINT_FIELD_FD("{", attr, map_fd, tcp); + PRINT_FIELD_X(", ", attr, key); + PRINT_FIELD_X(", ", attr, value); + decode_attr_extra_data(tcp, data, size, sizeof(attr)); + tprints("}"); + + return RVAL_DECODED; +} + DEF_BPF_CMD_DECODER(BPF_MAP_UPDATE_ELEM) { struct { @@ -150,31 +170,12 @@ DEF_BPF_CMD_DECODER(BPF_MAP_DELETE_ELEM) return RVAL_DECODED; } -static int -bpf_map_io(struct tcb *const tcp, - const kernel_ulong_t addr, - const unsigned int size, - void *const data, - const char *const text) +DEF_BPF_CMD_DECODER(BPF_MAP_GET_NEXT_KEY) { struct bpf_io_elem_struct { uint32_t map_fd; - uint64_t ATTRIBUTE_ALIGNED(8) key; - uint64_t ATTRIBUTE_ALIGNED(8) value; + uint64_t ATTRIBUTE_ALIGNED(8) key, next_key; } attr = {}; - const size_t value_offset = offsetof(struct bpf_io_elem_struct, value); - - if (exiting(tcp)) { - if (!syserror(tcp)) { - tprints(", "); - if (!umove_or_printaddr(tcp, addr + value_offset, - &attr.value)) - tprintf("%s=%#" PRIx64, text, attr.value); - } - tprints("}"); - - return RVAL_DECODED; - } const unsigned int len = size < sizeof(attr) ? size : sizeof(attr); @@ -182,22 +183,11 @@ bpf_map_io(struct tcb *const tcp, PRINT_FIELD_FD("{", attr, map_fd, tcp); PRINT_FIELD_X(", ", attr, key); + PRINT_FIELD_X(", ", attr, next_key); + decode_attr_extra_data(tcp, data, size, sizeof(attr)); + tprints("}"); - int rc = decode_attr_extra_data(tcp, data, size, sizeof(attr)); - if (rc & RVAL_DECODED) - tprints("}"); - - return rc; -} - -DEF_BPF_CMD_DECODER(BPF_MAP_LOOKUP_ELEM) -{ - return bpf_map_io(tcp, addr, size, data, "value"); -} - -DEF_BPF_CMD_DECODER(BPF_MAP_GET_NEXT_KEY) -{ - return bpf_map_io(tcp, addr, size, data, "next_key"); + return RVAL_DECODED; } DEF_BPF_CMD_DECODER(BPF_PROG_LOAD) diff --git a/tests/bpf.c b/tests/bpf.c index 20a776c4..bec30f87 100644 --- a/tests/bpf.c +++ b/tests/bpf.c @@ -248,7 +248,7 @@ init_BPF_MAP_LOOKUP_ELEM_first(const unsigned long eop) static void print_BPF_MAP_LOOKUP_ELEM_first(const unsigned long addr) { - printf("map_fd=-1, key=0"); + printf("map_fd=-1, key=0, value=0"); } static unsigned int @@ -270,7 +270,7 @@ init_BPF_MAP_LOOKUP_ELEM_attr(const unsigned long eop) static void print_BPF_MAP_LOOKUP_ELEM_attr(const unsigned long addr) { - printf("map_fd=-1, key=0xdeadbeef"); + printf("map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"); } # define init_BPF_MAP_UPDATE_ELEM_first init_BPF_MAP_LOOKUP_ELEM_first @@ -305,7 +305,12 @@ print_BPF_MAP_UPDATE_ELEM_attr(const unsigned long addr) } # define init_BPF_MAP_DELETE_ELEM_first init_BPF_MAP_LOOKUP_ELEM_first -# define print_BPF_MAP_DELETE_ELEM_first print_BPF_MAP_LOOKUP_ELEM_first + +static void +print_BPF_MAP_DELETE_ELEM_first(const unsigned long addr) +{ + printf("map_fd=-1, key=0"); +} static unsigned int init_BPF_MAP_DELETE_ELEM_attr(const unsigned long eop) @@ -322,10 +327,19 @@ init_BPF_MAP_DELETE_ELEM_attr(const unsigned long eop) return offset; } -# define print_BPF_MAP_DELETE_ELEM_attr print_BPF_MAP_LOOKUP_ELEM_attr +static void +print_BPF_MAP_DELETE_ELEM_attr(const unsigned long addr) +{ + printf("map_fd=-1, key=0xdeadbeef"); +} # define init_BPF_MAP_GET_NEXT_KEY_first init_BPF_MAP_LOOKUP_ELEM_first -# define print_BPF_MAP_GET_NEXT_KEY_first print_BPF_MAP_LOOKUP_ELEM_first + +static void +print_BPF_MAP_GET_NEXT_KEY_first(const unsigned long addr) +{ + printf("map_fd=-1, key=0, next_key=0"); +} static unsigned int init_BPF_MAP_GET_NEXT_KEY_attr(const unsigned long eop) @@ -343,7 +357,11 @@ init_BPF_MAP_GET_NEXT_KEY_attr(const unsigned long eop) return offset; } -# define print_BPF_MAP_GET_NEXT_KEY_attr print_BPF_MAP_LOOKUP_ELEM_attr +static void +print_BPF_MAP_GET_NEXT_KEY_attr(const unsigned long addr) +{ + printf("map_fd=-1, key=0xdeadbeef, next_key=0xbadc0ded"); +} # endif /* HAVE_UNION_BPF_ATTR_FLAGS */ -- 2.40.0