Implement decoding of BPF_OBJ_GET_INFO_BY_FD command of bpf syscall

* configure.ac (AC_CHECK_MEMBERS): Add union bpf_attr.info.info.
* bpf.c (decode_BPF_OBJ_GET_INFO_BY_FD): New function.
(SYS_FUNC(bpf)) <bpf_cmd_decoders>: Use it.
* NEWS: Mention this.
* tests/bpf.c: Add macro guard for BPF_OBJ_GET_INFO_BY_FD decoder test.
[HAVE_UNION_BPF_ATTR_INFO_INFO] (sample_BPF_OBJ_GET_INFO_BY_FD_attr):
New variable.
[HAVE_UNION_BPF_ATTR_INFO_INFO] (init_BPF_OBJ_GET_INFO_BY_FD_first,
print_BPF_OBJ_GET_INFO_BY_FD_first, init_BPF_OBJ_GET_INFO_BY_FD_attr,
print_BPF_OBJ_GET_INFO_BY_FD_attr): New functions.
(main) [HAVE_UNION_BPF_ATTR_INFO_INFO]: Use them.
This commit is contained in:
Дмитрий Левин 2017-11-21 23:12:04 +00:00
parent 9df60f314d
commit 5c51173830
4 changed files with 77 additions and 2 deletions

4
NEWS
View File

@ -5,8 +5,8 @@ Noteworthy changes in release ?.?? (????-??-??)
* Implemented decoding of netlink descriptor attributes as file descriptors.
* Implemented decoding of hugetlb page size selection flags.
* Implemented decoding of BPF_PROG_TEST_RUN, BPF_PROG_GET_NEXT_ID,
BPF_MAP_GET_NEXT_ID, BPF_PROG_GET_FD_BY_ID, and BPF_MAP_GET_FD_BY_ID
commands of bpf syscall.
BPF_MAP_GET_NEXT_ID, BPF_PROG_GET_FD_BY_ID, BPF_MAP_GET_FD_BY_ID,
and BPF_OBJ_GET_INFO_BY_FD commands of bpf syscall.
* Enhanced decoding of getsockopt and setsockopt syscalls for SOL_NETLINK
level.
* Enhanced decoding of BPF_MAP_CREATE command of bpf syscall.

21
bpf.c
View File

@ -359,6 +359,26 @@ DEF_BPF_CMD_DECODER(BPF_MAP_GET_FD_BY_ID)
return RVAL_DECODED;
}
DEF_BPF_CMD_DECODER(BPF_OBJ_GET_INFO_BY_FD)
{
struct {
uint32_t bpf_fd, info_len;
uint64_t ATTRIBUTE_ALIGNED(8) info;
} attr = {};
const unsigned int len = size < sizeof(attr) ? size : sizeof(attr);
memcpy(&attr, data, len);
PRINT_FIELD_FD("{info={", attr, bpf_fd, tcp);
PRINT_FIELD_U(", ", attr, info_len);
PRINT_FIELD_X(", ", attr, info);
tprints("}");
decode_attr_extra_data(tcp, data, size, sizeof(attr));
tprints("}");
return RVAL_DECODED | RVAL_FD;
}
SYS_FUNC(bpf)
{
static const bpf_cmd_decoder_t bpf_cmd_decoders[] = {
@ -377,6 +397,7 @@ SYS_FUNC(bpf)
BPF_CMD_ENTRY(BPF_MAP_GET_NEXT_ID),
BPF_CMD_ENTRY(BPF_PROG_GET_FD_BY_ID),
BPF_CMD_ENTRY(BPF_MAP_GET_FD_BY_ID),
BPF_CMD_ENTRY(BPF_OBJ_GET_INFO_BY_FD),
};
const unsigned int cmd = tcp->u_arg[0];

View File

@ -463,6 +463,7 @@ AC_CHECK_HEADERS([linux/bpf.h], [
union bpf_attr.attach_flags,
union bpf_attr.bpf_fd,
union bpf_attr.flags,
union bpf_attr.info.info,
union bpf_attr.next_id,
union bpf_attr.numa_node,
union bpf_attr.prog_flags,

View File

@ -34,6 +34,7 @@
&& (defined HAVE_UNION_BPF_ATTR_ATTACH_FLAGS \
|| defined HAVE_UNION_BPF_ATTR_BPF_FD \
|| defined HAVE_UNION_BPF_ATTR_FLAGS \
|| defined HAVE_UNION_BPF_ATTR_INFO_INFO \
|| defined HAVE_UNION_BPF_ATTR_NEXT_ID \
|| defined HAVE_UNION_BPF_ATTR_NUMA_NODE \
|| defined HAVE_UNION_BPF_ATTR_PROG_FLAGS \
@ -701,6 +702,54 @@ print_BPF_MAP_GET_FD_BY_ID_attr(const unsigned long addr)
# endif /* HAVE_UNION_BPF_ATTR_NEXT_ID */
# ifdef HAVE_UNION_BPF_ATTR_INFO_INFO
static unsigned int
init_BPF_OBJ_GET_INFO_BY_FD_first(const unsigned long eop)
{
static const union bpf_attr attr = { .info.bpf_fd = -1 };
static const unsigned int offset = sizeof(attr.info.bpf_fd);
const unsigned long addr = eop - offset;
memcpy((void *) addr, &attr.info.bpf_fd, offset);
return offset;
}
static void
print_BPF_OBJ_GET_INFO_BY_FD_first(const unsigned long addr)
{
printf("info={bpf_fd=-1, info_len=0, info=0}");
}
static const union bpf_attr sample_BPF_OBJ_GET_INFO_BY_FD_attr = {
.info = {
.bpf_fd = -1,
.info_len = 0xdeadbeef,
.info = (uint64_t) 0xfacefeedbadc0ded
}
};
static unsigned int
init_BPF_OBJ_GET_INFO_BY_FD_attr(const unsigned long eop)
{
static const unsigned int offset =
offsetofend(union bpf_attr, info);
const unsigned long addr = eop - offset;
memcpy((void *) addr, &sample_BPF_OBJ_GET_INFO_BY_FD_attr, offset);
return offset;
}
static void
print_BPF_OBJ_GET_INFO_BY_FD_attr(const unsigned long addr)
{
PRINT_FIELD_D("info={", sample_BPF_OBJ_GET_INFO_BY_FD_attr.info, bpf_fd);
PRINT_FIELD_U(", ", sample_BPF_OBJ_GET_INFO_BY_FD_attr.info, info_len);
PRINT_FIELD_X(", ", sample_BPF_OBJ_GET_INFO_BY_FD_attr.info, info);
printf("}");
}
# endif /* HAVE_UNION_BPF_ATTR_INFO_INFO */
int
main(void)
{
@ -743,6 +792,10 @@ main(void)
TEST_BPF(BPF_MAP_GET_FD_BY_ID);
# endif
# ifdef HAVE_UNION_BPF_ATTR_INFO_INFO
TEST_BPF(BPF_OBJ_GET_INFO_BY_FD);
# endif
sys_bpf(0xfacefeed, end_of_page, 40);
printf("bpf(0xfacefeed /* BPF_??? */, %#lx, 40) = %s\n",
end_of_page, errstr);