Revert "bpf: remove unnecessary prune and jump points"

This reverts commit 8266c47d04 which is
commit 618945fbed501b6e5865042068a51edfb2dda948 upstream.

It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.

Bug: 161946584
Change-Id: Id463c785d61b9588f95ba45a11333c0900fe225a
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2024-01-15 11:28:48 +00:00
parent 9212bbf98b
commit eba57b3513

View File

@ -11110,12 +11110,13 @@ static int visit_func_call_insn(int t, int insn_cnt,
if (ret)
return ret;
mark_prune_point(env, t + 1);
/* when we exit from subprog, we need to record non-linear history */
mark_jmp_point(env, t + 1);
if (t + 1 < insn_cnt) {
mark_prune_point(env, t + 1);
mark_jmp_point(env, t + 1);
}
if (visit_callee) {
mark_prune_point(env, t);
mark_jmp_point(env, t);
ret = push_insn(t, t + insns[t].imm + 1, BRANCH, env,
/* It's ok to allow recursion from CFG point of
* view. __check_func_call() will do the actual
@ -11149,13 +11150,15 @@ static int visit_insn(int t, int insn_cnt, struct bpf_verifier_env *env)
return DONE_EXPLORING;
case BPF_CALL:
if (insns[t].imm == BPF_FUNC_timer_set_callback)
/* Mark this call insn as a prune point to trigger
* is_state_visited() check before call itself is
* processed by __check_func_call(). Otherwise new
* async state will be pushed for further exploration.
if (insns[t].imm == BPF_FUNC_timer_set_callback) {
/* Mark this call insn to trigger is_state_visited() check
* before call itself is processed by __check_func_call().
* Otherwise new async state will be pushed for further
* exploration.
*/
mark_prune_point(env, t);
mark_jmp_point(env, t);
}
return visit_func_call_insn(t, insn_cnt, insns, env,
insns[t].src_reg == BPF_PSEUDO_CALL);
@ -11169,15 +11172,26 @@ static int visit_insn(int t, int insn_cnt, struct bpf_verifier_env *env)
if (ret)
return ret;
/* unconditional jmp is not a good pruning point,
* but it's marked, since backtracking needs
* to record jmp history in is_state_visited().
*/
mark_prune_point(env, t + insns[t].off + 1);
mark_jmp_point(env, t + insns[t].off + 1);
/* tell verifier to check for equivalent states
* after every call and jump
*/
if (t + 1 < insn_cnt) {
mark_prune_point(env, t + 1);
mark_jmp_point(env, t + 1);
}
return ret;
default:
/* conditional jump with two edges */
mark_prune_point(env, t);
mark_jmp_point(env, t);
ret = push_insn(t, t + 1, FALLTHROUGH, env, true);
if (ret)
return ret;