bpf_filter.c: add support for decoding eBPF instruction codes

* bpf_filter.c (print_bpf_filter_code): Add extended argument, remove
static qualifier.  Add support for decoding eBPF instruction code.
* defs.h (print_bpf_filter_code): New declaration.
* xlat/ebpf_class.in: New file.
* xlat/ebpf_mode.in: Likewise.
* xlat/ebpf_op_alu.in: Likewise.
* xlat/ebpf_op_jmp.in: Likewise.
* xlat/ebpf_size.in: Likewise.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
This commit is contained in:
Eugene Syromyatnikov 2018-02-22 07:55:32 +01:00 committed by Dmitry V. Levin
parent 2713444cb7
commit 94ea427a31
7 changed files with 84 additions and 28 deletions

View File

@ -34,6 +34,7 @@
#include "bpf_fprog.h"
#include <linux/filter.h>
#include "xlat/bpf_class.h"
#include "xlat/bpf_miscop.h"
#include "xlat/bpf_mode.h"
@ -43,56 +44,84 @@
#include "xlat/bpf_size.h"
#include "xlat/bpf_src.h"
static void
print_bpf_filter_code(const uint16_t code)
#include "xlat/ebpf_class.h"
#include "xlat/ebpf_mode.h"
#include "xlat/ebpf_op_alu.h"
#include "xlat/ebpf_op_jmp.h"
#include "xlat/ebpf_size.h"
void
print_bpf_filter_code(const uint16_t code, bool extended)
{
const struct xlat *class = extended ? ebpf_class : bpf_class;
const struct xlat *mode = extended ? ebpf_mode : bpf_mode;
uint16_t i = code & ~BPF_CLASS(code);
printxval(bpf_class, BPF_CLASS(code), "BPF_???");
printxval(class, BPF_CLASS(code), "BPF_???");
switch (BPF_CLASS(code)) {
case BPF_ST:
case BPF_STX:
if (!extended) {
if (i) {
tprintf("|%#x", i);
tprints_comment("BPF_???");
}
break;
}
ATTRIBUTE_FALLTHROUGH; /* extended == true */
case BPF_LD:
case BPF_LDX:
tprints("|");
printxval(bpf_size, BPF_SIZE(code), "BPF_???");
printxvals(BPF_SIZE(code), "BPF_???",
bpf_size, extended ? ebpf_size : NULL, NULL);
tprints("|");
printxval(bpf_mode, BPF_MODE(code), "BPF_???");
printxval(mode, BPF_MODE(code), "BPF_???");
break;
case BPF_ST:
case BPF_STX:
if (i) {
tprintf("|%#x", i);
tprints_comment("BPF_???");
case BPF_MISC: /* BPF_ALU64 in eBPF */
if (!extended) {
tprints("|");
printxval(bpf_miscop, BPF_MISCOP(code), "BPF_???");
i &= ~BPF_MISCOP(code);
if (i) {
tprintf("|%#x", i);
tprints_comment("BPF_???");
}
break;
}
break;
ATTRIBUTE_FALLTHROUGH; /* extended == true */
case BPF_ALU:
tprints("|");
printxval(bpf_src, BPF_SRC(code), "BPF_???");
tprints("|");
printxval(bpf_op_alu, BPF_OP(code), "BPF_???");
printxvals(BPF_OP(code), "BPF_???",
bpf_op_alu,
extended ? ebpf_op_alu : NULL, NULL);
break;
case BPF_JMP:
tprints("|");
printxval(bpf_src, BPF_SRC(code), "BPF_???");
tprints("|");
printxval(bpf_op_jmp, BPF_OP(code), "BPF_???");
printxvals(BPF_OP(code), "BPF_???",
bpf_op_jmp, extended ? ebpf_op_jmp : NULL, NULL);
break;
case BPF_RET:
tprints("|");
printxval(bpf_rval, BPF_RVAL(code), "BPF_???");
i &= ~BPF_RVAL(code);
if (i) {
tprintf("|%#x", i);
tprints_comment("BPF_???");
}
break;
case BPF_MISC:
tprints("|");
printxval(bpf_miscop, BPF_MISCOP(code), "BPF_???");
i &= ~BPF_MISCOP(code);
case BPF_RET: /* Reserved in eBPF */
if (!extended) {
tprints("|");
printxval(bpf_rval, BPF_RVAL(code), "BPF_???");
i &= ~BPF_RVAL(code);
}
if (i) {
tprintf("|%#x", i);
tprints_comment("BPF_???");
}
break;
}
}
@ -102,7 +131,7 @@ print_bpf_filter_stmt(const struct bpf_filter_block *const filter,
const print_bpf_filter_fn print_k)
{
tprints("BPF_STMT(");
print_bpf_filter_code(filter->code);
print_bpf_filter_code(filter->code, false);
tprints(", ");
if (!print_k || !print_k(filter))
tprintf("%#x", filter->k);
@ -113,7 +142,7 @@ static void
print_bpf_filter_jump(const struct bpf_filter_block *const filter)
{
tprints("BPF_JUMP(");
print_bpf_filter_code(filter->code);
print_bpf_filter_code(filter->code, false);
tprintf(", %#x, %#x, %#x)", filter->k, filter->jt, filter->jf);
}

2
defs.h
View File

@ -683,6 +683,8 @@ print_struct_statfs64(struct tcb *, kernel_ulong_t addr, kernel_ulong_t size);
extern void print_ifindex(unsigned int);
extern void print_bpf_filter_code(const uint16_t code, bool extended);
extern void qualify(const char *);
extern unsigned int qual_flags(const unsigned int);

7
xlat/ebpf_class.in Normal file
View File

@ -0,0 +1,7 @@
BPF_LD 0x0
BPF_LDX 0x1
BPF_ST 0x2
BPF_STX 0x3
BPF_ALU 0x4
BPF_JMP 0x5
BPF_ALU64 0x7

5
xlat/ebpf_mode.in Normal file
View File

@ -0,0 +1,5 @@
BPF_IMM 0x00
BPF_ABS 0x20
BPF_IND 0x40
BPF_MEM 0x60
BPF_XADD 0xc0

3
xlat/ebpf_op_alu.in Normal file
View File

@ -0,0 +1,3 @@
BPF_MOV 0xb0
BPF_ARSH 0xc0
BPF_END 0xd0

9
xlat/ebpf_op_jmp.in Normal file
View File

@ -0,0 +1,9 @@
BPF_JNE 0x50
BPF_JSGT 0x60
BPF_JSGE 0x70
BPF_CALL 0x80
BPF_EXIT 0x90
BPF_JLT 0xa0
BPF_JLE 0xb0
BPF_JSLT 0xc0
BPF_JSLE 0xd0

1
xlat/ebpf_size.in Normal file
View File

@ -0,0 +1 @@
BPF_DW 0x18