History

bpf: Mark PTR_TO_FUNC register initially with zero offset

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.

Daniel Borkmann committed 4 years ago

Commit d400a6c1 parent be80a1d1 file · +6 −3Browse files

Unified · Split

kernel/bpf/verifier.c+6−3
@@ -9508,9 +9508,13 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) · 9507 unmodified lines
9508 return 0;9508 return 0;
9509 }9509 }
9510 9510
9511 if (insn->src_reg == BPF_PSEUDO_BTF_ID) {9511 /* All special src_reg cases are listed below. From this point onwards
9512 mark_reg_known_zero(env, regs, insn->dst_reg);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 dst_reg->type = aux->btf_var.reg_type;9518 dst_reg->type = aux->btf_var.reg_type;
9515 switch (base_type(dst_reg->type)) {9519 switch (base_type(dst_reg->type)) {
9516 case PTR_TO_MEM: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 map = env->used_maps[aux->map_index];9554 map = env->used_maps[aux->map_index];
9551 mark_reg_known_zero(env, regs, insn->dst_reg);
9552 dst_reg->map_ptr = map;9555 dst_reg->map_ptr = map;
9553 9556
9554 if (insn->src_reg == BPF_PSEUDO_MAP_VALUE ||9557 if (insn->src_reg == BPF_PSEUDO_MAP_VALUE ||