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 (1 of 6 files). Show all
Unified · Split
| @@ -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 have | 358 | /* 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_VALUE | 361 | * insn[0].src_reg: BPF_PSEUDO_MAP_FD |
| 362 | * insn[0].imm: map fd map fd | 362 | * insn[0].imm: map fd |
| 363 | * insn[1].imm: 0 offset into value | 363 | * insn[1].imm: 0 |
| 364 | * insn[0].off: 0 0 | 364 | * insn[0].off: 0 |
| 365 | * insn[1].off: 0 0 | 365 | * insn[1].off: 0 |
| 366 | * ldimm64 rewrite: address of map address of map[0]+offset | 366 | * ldimm64 rewrite: address of map |
| 367 | * verifier type: CONST_PTR_TO_MAP PTR_TO_MAP_VALUE | 367 | * verifier type: CONST_PTR_TO_MAP |
| 368 | */ | 368 | */ |
| 369 | #define BPF_PSEUDO_MAP_FD 1 | 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 | #define BPF_PSEUDO_MAP_VALUE 2 | 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 | /* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative | 390 | /* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative |
| 373 | * offset to another bpf function | 391 | * offset to another bpf function |