History

bpf: Introduce pseudo_btf_id

Pseudo_btf_id is a type of ld_imm insn that associates a btf_id to a ksym so that further dereferences on the ksym can use the BTF info to validate accesses. Internally, when seeing a pseudo_btf_id ld insn, the verifier reads the btf_id stored in the insn[0]'s imm field and marks the dst_reg as PTR_TO_BTF_ID. The btf_id points to a VAR_KIND, which is encoded in btf_vminux by pahole. If the VAR is not of a struct type, the dst reg will be marked as PTR_TO_MEM instead of PTR_TO_BTF_ID and the mem_size is resolved to the size of the VAR's type. >From the VAR btf_id, the verifier can also read the address of the ksym's corresponding kernel var from kallsyms and use that to fill dst_reg. Therefore, the proper functionality of pseudo_btf_id depends on (1) kallsyms and (2) the encoding of kernel global VARs in pahole, which should be available since pahole v1.18.

Hao Luo committed 6 years ago

Commit 4976b711 parent 440c5756 files · +188 −46Browse files

Showing the changes to tools/include/uapi (1 of 6 files). Show all

Unified · Split

tools/include/uapi/linux/bpf.h+27−9
@@ -356,18 +356,36 @@ enum bpf_link_type { · 355 unmodified lines
356#define BPF_F_SLEEPABLE (1U << 4)356#define BPF_F_SLEEPABLE (1U << 4)
357 357
358/* When BPF ldimm64's insn[0].src_reg != 0 then this can have358/* When BPF ldimm64's insn[0].src_reg != 0 then this can have
359 * two extensions:359 * the following extensions:
360 *360 *
361 * insn[0].src_reg: BPF_PSEUDO_MAP_FD BPF_PSEUDO_MAP_VALUE361 * insn[0].src_reg: BPF_PSEUDO_MAP_FD
362 * insn[0].imm: map fd map fd362 * insn[0].imm: map fd
363 * insn[1].imm: 0 offset into value363 * insn[1].imm: 0
364 * insn[0].off: 0 0364 * insn[0].off: 0
365 * insn[1].off: 0 0365 * insn[1].off: 0
366 * ldimm64 rewrite: address of map address of map[0]+offset366 * ldimm64 rewrite: address of map
367 * verifier type: CONST_PTR_TO_MAP PTR_TO_MAP_VALUE367 * verifier type: CONST_PTR_TO_MAP
368 */368 */
369#define BPF_PSEUDO_MAP_FD 1369#define BPF_PSEUDO_MAP_FD 1
370/* insn[0].src_reg: BPF_PSEUDO_MAP_VALUE
371 * insn[0].imm: map fd
372 * insn[1].imm: offset into value
373 * insn[0].off: 0
374 * insn[1].off: 0
375 * ldimm64 rewrite: address of map[0]+offset
376 * verifier type: PTR_TO_MAP_VALUE
377 */
370#define BPF_PSEUDO_MAP_VALUE 2378#define BPF_PSEUDO_MAP_VALUE 2
379/* insn[0].src_reg: BPF_PSEUDO_BTF_ID
380 * insn[0].imm: kernel btd id of VAR
381 * insn[1].imm: 0
382 * insn[0].off: 0
383 * insn[1].off: 0
384 * ldimm64 rewrite: address of the kernel variable
385 * verifier type: PTR_TO_BTF_ID or PTR_TO_MEM, depending on whether the var
386 * is struct/union.
387 */
388#define BPF_PSEUDO_BTF_ID 3
371 389
372/* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative390/* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative
373 * offset to another bpf function391 * offset to another bpf function