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.
Showing the changes to include/uapi/linux (1 of 6 files). Show all
Unified · Split
| @@ -356,18 +356,36 @@ enum bpf_link_type { · 355 unmodified lines | ||
| 356 | 356 | #define BPF_F_SLEEPABLE (1U << 4) |
| 357 | 357 | |
| 358 | 358 | /* 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 | |
| 368 | 368 | */ |
| 369 | 369 | #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 | 378 | #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 | 390 | /* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative |
| 373 | 391 | * offset to another bpf function |