diff --git a/kernel/bpf/backtrack.c b/kernel/bpf/backtrack.c index 43d5740034c0..2d6535f271a6 100644 --- a/kernel/bpf/backtrack.c +++ b/kernel/bpf/backtrack.c @@ -746,6 +746,17 @@ void bpf_mark_all_scalars_precise(struct bpf_verifier_env *env, i, -(j + 1) * 8); } } + for (j = 0; j < func->out_stack_arg_cnt; j++) { + reg = &func->stack_arg_regs[j]; + if (reg->type != SCALAR_VALUE || reg->precise) + continue; + reg->precise = true; + if (env->log.level & BPF_LOG_LEVEL2) { + verbose(env, + "force_precise: frame%d: forcing r11%d to be precise\n", + i, -(j + 1) * BPF_REG_SIZE); + } + } } } } diff --git a/kernel/bpf/states.c b/kernel/bpf/states.c index a6ae86f973e3..50480c42bcad 100644 --- a/kernel/bpf/states.c +++ b/kernel/bpf/states.c @@ -1116,6 +1116,20 @@ static int propagate_precision(struct bpf_verifier_env *env, bpf_bt_set_frame_slot(&env->bt, fr, i); first = false; } + for (i = 0; i < state->out_stack_arg_cnt; i++) { + state_reg = &state->stack_arg_regs[i]; + if (state_reg->type != SCALAR_VALUE || !state_reg->precise) + continue; + if (env->log.level & BPF_LOG_LEVEL2) { + if (first) + verbose(env, "frame %d: propagating r11%d", + fr, -(i + 1) * BPF_REG_SIZE); + else + verbose(env, ",r11%d", -(i + 1) * BPF_REG_SIZE); + } + bt_set_frame_stack_arg_slot(&env->bt, fr, i); + first = false; + } if (!first && (env->log.level & BPF_LOG_LEVEL2)) verbose(env, "\n"); }