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 include/uapi (1 of 6 files). Show all

Unified · Split

include/uapi/linux/bpf.h+27−9
@@ -356,18 +356,36 @@ enum bpf_link_type { · 355 unmodified lines
356356 #define BPF_F_SLEEPABLE (1U << 4)
357357
358358 /* When BPF ldimm64's insn[0].src_reg != 0 then this can have
359− * two extensions:
360− *
361− * insn[0].src_reg: BPF_PSEUDO_MAP_FD BPF_PSEUDO_MAP_VALUE
362− * insn[0].imm: map fd map fd
363− * insn[1].imm: 0 offset into value
364− * insn[0].off: 0 0
365− * insn[1].off: 0 0
366− * ldimm64 rewrite: address of map address of map[0]+offset
367− * verifier type: CONST_PTR_TO_MAP PTR_TO_MAP_VALUE
359+ * the following extensions:
360+ *
361+ * insn[0].src_reg: BPF_PSEUDO_MAP_FD
362+ * insn[0].imm: map fd
363+ * insn[1].imm: 0
364+ * insn[0].off: 0
365+ * insn[1].off: 0
366+ * ldimm64 rewrite: address of map
367+ * verifier type: CONST_PTR_TO_MAP
368368 */
369369 #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+ */
370378 #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
371389
372390 /* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative
373391 * offset to another bpf function