Similar as with other pointer types where we use ldimm64, clear the register content to zero first, and then populate the PTR_TO_FUNC type and subprogno number. Currently this is not done, and leads to reuse of stale register tracking data. Given for special ldimm64 cases we always clear the register offset, make it common for all cases, so it won't be forgotten in future.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -9508,9 +9508,13 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) · 9507 unmodified lines | ||
| 9508 | 9508 | return 0; |
| 9509 | 9509 | } |
| 9510 | 9510 | |
| 9511 | − if (insn->src_reg == BPF_PSEUDO_BTF_ID) { | |
| 9512 | − mark_reg_known_zero(env, regs, insn->dst_reg); | |
| 9511 | + /* All special src_reg cases are listed below. From this point onwards | |
| 9512 | + * we either succeed and assign a corresponding dst_reg->type after | |
| 9513 | + * zeroing the offset, or fail and reject the program. | |
| 9514 | + */ | |
| 9515 | + mark_reg_known_zero(env, regs, insn->dst_reg); | |
| 9513 | 9516 | |
| 9517 | + if (insn->src_reg == BPF_PSEUDO_BTF_ID) { | |
| 9514 | 9518 | dst_reg->type = aux->btf_var.reg_type; |
| 9515 | 9519 | switch (base_type(dst_reg->type)) { |
| 9516 | 9520 | case PTR_TO_MEM: |
| @@ -9548,7 +9552,6 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) · 31 unmodified lines | ||
| 9548 | 9552 | } |
| 9549 | 9553 | |
| 9550 | 9554 | map = env->used_maps[aux->map_index]; |
| 9551 | − mark_reg_known_zero(env, regs, insn->dst_reg); | |
| 9552 | 9555 | dst_reg->map_ptr = map; |
| 9553 | 9556 | |
| 9554 | 9557 | if (insn->src_reg == BPF_PSEUDO_MAP_VALUE || |