History

bpf: Add support for BTF pointers to interpreter

Pointer to BTF object is a pointer to kernel object or NULL. The memory access in the interpreter has to be done via probe_kernel_read to avoid page faults.

Alexei Starovoitov committed 7 years ago

Commit 2a027591 parent ac4414b3 files · +30 −0Browse files

Unified · Split

3 files
  1. include/linux/filter.h +3 −0
  2. kernel/bpf/core.c +19 −0
  3. kernel/bpf/verifier.c +8 −0
include/linux/filter.h+3−0
@@ -65,6 +65,9 @@ struct ctl_table_header; · 64 unmodified lines
6565 /* unused opcode to mark special call to bpf_tail_call() helper */
6666 #define BPF_TAIL_CALL 0xf0
6767
68+/* unused opcode to mark special load instruction. Same as BPF_ABS */
69+#define BPF_PROBE_MEM 0x20
70+
6871 /* unused opcode to mark call to interpreter with arguments */
6972 #define BPF_CALL_ARGS 0xe0
7073
kernel/bpf/core.c+19−0
@@ -1291,6 +1291,11 @@ bool bpf_opcode_in_insntable(u8 code) · 1290 unmodified lines
12911291 }
12921292
12931293 #ifndef CONFIG_BPF_JIT_ALWAYS_ON
1294+u64 __weak bpf_probe_read(void * dst, u32 size, const void * unsafe_ptr)
1295+{
1296+ memset(dst, 0, size);
1297+ return -EFAULT;
1298+}
12941299 /**
12951300 * __bpf_prog_run - run eBPF program on a given context
12961301 * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers
@@ -1310,6 +1315,10 @@ static u64 __no_fgcse ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u6 · 13 unmodified lines
13101315 /* Non-UAPI available opcodes. */
13111316 [BPF_JMP | BPF_CALL_ARGS] = &&JMP_CALL_ARGS,
13121317 [BPF_JMP | BPF_TAIL_CALL] = &&JMP_TAIL_CALL,
1318+ [BPF_LDX | BPF_PROBE_MEM | BPF_B] = &&LDX_PROBE_MEM_B,
1319+ [BPF_LDX | BPF_PROBE_MEM | BPF_H] = &&LDX_PROBE_MEM_H,
1320+ [BPF_LDX | BPF_PROBE_MEM | BPF_W] = &&LDX_PROBE_MEM_W,
1321+ [BPF_LDX | BPF_PROBE_MEM | BPF_DW] = &&LDX_PROBE_MEM_DW,
13131322 };
13141323 #undef BPF_INSN_3_LBL
13151324 #undef BPF_INSN_2_LBL
@@ -1542,6 +1551,16 @@ out: · 226 unmodified lines
15421551 LDST(W, u32)
15431552 LDST(DW, u64)
15441553 #undef LDST
1554+#define LDX_PROBE(SIZEOP, SIZE) \
1555+ LDX_PROBE_MEM_##SIZEOP: \
1556+ bpf_probe_read(&DST, SIZE, (const void *)(long) SRC); \
1557+ CONT;
1558+ LDX_PROBE(B, 1)
1559+ LDX_PROBE(H, 2)
1560+ LDX_PROBE(W, 4)
1561+ LDX_PROBE(DW, 8)
1562+#undef LDX_PROBE
1563+
15451564 STX_XADD_W: /* lock xadd *(u32 *)(dst_reg + off16) += src_reg */
15461565 atomic_add((u32) SRC, (atomic_t *)(unsigned long)
15471566 (DST + insn->off));
kernel/bpf/verifier.c+8−0
@@ -7581,6 +7581,7 @@ static bool reg_type_mismatch_ok(enum bpf_reg_type type) · 7580 unmodified lines
75817581 case PTR_TO_TCP_SOCK:
75827582 case PTR_TO_TCP_SOCK_OR_NULL:
75837583 case PTR_TO_XDP_SOCK:
7584+ case PTR_TO_BTF_ID:
75847585 return false;
75857586 default:
75867587 return true;
@@ -8722,6 +8723,13 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) · 1135 unmodified lines
87228723 case PTR_TO_XDP_SOCK:
87238724 convert_ctx_access = bpf_xdp_sock_convert_ctx_access;
87248725 break;
8726+ case PTR_TO_BTF_ID:
8727+ if (type == BPF_WRITE) {
8728+ verbose(env, "Writes through BTF pointers are not allowed\n");
8729+ return -EINVAL;
8730+ }
8731+ insn->code = BPF_LDX | BPF_PROBE_MEM | BPF_SIZE((insn)->code);
8732+ continue;
87258733 default:
87268734 continue;
87278735 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t