All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: stable@vger.kernel.org, ast@kernel.org
Cc: andrii@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev,
	yonghong.song@linux.dev, mykolal@fb.com,
	gregkh@linuxfoundation.org, mat.gienieczko@tum.de,
	Eduard Zingerman <eddyz87@gmail.com>
Subject: [PATCH 6.6.y 14/17] bpf: widening for callback iterators
Date: Thu, 25 Jan 2024 02:15:51 +0200	[thread overview]
Message-ID: <20240125001554.25287-15-eddyz87@gmail.com> (raw)
In-Reply-To: <20240125001554.25287-1-eddyz87@gmail.com>

[ Upstream commit cafe2c21508a ]

Callbacks are similar to open coded iterators, so add imprecise
widening logic for callback body processing. This makes callback based
loops behave identically to open coded iterators, e.g. allowing to
verify programs like below:

  struct ctx { u32 i; };
  int cb(u32 idx, struct ctx* ctx)
  {
          ++ctx->i;
          return 0;
  }
  ...
  struct ctx ctx = { .i = 0 };
  bpf_loop(100, cb, &ctx, 0);
  ...

Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20231121020701.26440-9-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
 kernel/bpf/verifier.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 0eb0de55a443..638ab1fdf214 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -9614,9 +9614,10 @@ static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env)
 
 static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
 {
-	struct bpf_verifier_state *state = env->cur_state;
+	struct bpf_verifier_state *state = env->cur_state, *prev_st;
 	struct bpf_func_state *caller, *callee;
 	struct bpf_reg_state *r0;
+	bool in_callback_fn;
 	int err;
 
 	callee = state->frame[state->curframe];
@@ -9671,7 +9672,8 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
 	 * there function call logic would reschedule callback visit. If iteration
 	 * converges is_state_visited() would prune that visit eventually.
 	 */
-	if (callee->in_callback_fn)
+	in_callback_fn = callee->in_callback_fn;
+	if (in_callback_fn)
 		*insn_idx = callee->callsite;
 	else
 		*insn_idx = callee->callsite + 1;
@@ -9685,6 +9687,24 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
 	/* clear everything in the callee */
 	free_func_state(callee);
 	state->frame[state->curframe--] = NULL;
+
+	/* for callbacks widen imprecise scalars to make programs like below verify:
+	 *
+	 *   struct ctx { int i; }
+	 *   void cb(int idx, struct ctx *ctx) { ctx->i++; ... }
+	 *   ...
+	 *   struct ctx = { .i = 0; }
+	 *   bpf_loop(100, cb, &ctx, 0);
+	 *
+	 * This is similar to what is done in process_iter_next_call() for open
+	 * coded iterators.
+	 */
+	prev_st = in_callback_fn ? find_prev_entry(env, state, *insn_idx) : NULL;
+	if (prev_st) {
+		err = widen_imprecise_scalars(env, prev_st, state);
+		if (err)
+			return err;
+	}
 	return 0;
 }
 
-- 
2.43.0


  parent reply	other threads:[~2024-01-25  0:16 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-25  0:15 [PATCH 6.6.y 00/17] bpf: backport of iterator and callback handling fixes Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 01/17] bpf: move explored_state() closer to the beginning of verifier.c Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 02/17] bpf: extract same_callsites() as utility function Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 03/17] bpf: exact states comparison for iterator convergence checks Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 04/17] selftests/bpf: tests with delayed read/precision makrs in loop body Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 05/17] bpf: correct loop detection for iterators convergence Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 06/17] selftests/bpf: test if state loops are detected in a tricky case Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 07/17] bpf: print full verifier states on infinite loop detection Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 08/17] selftests/bpf: track tcp payload offset as scalar in xdp_synproxy Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 09/17] selftests/bpf: track string payload offset as scalar in strobemeta Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 10/17] bpf: extract __check_reg_arg() utility function Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 11/17] bpf: extract setup_func_entry() " Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 12/17] bpf: verify callbacks as if they are called unknown number of times Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 13/17] selftests/bpf: tests for iterating callbacks Eduard Zingerman
2024-01-25  0:15 ` Eduard Zingerman [this message]
2024-01-25  0:15 ` [PATCH 6.6.y 15/17] selftests/bpf: test widening " Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 16/17] bpf: keep track of max number of bpf_loop callback iterations Eduard Zingerman
2024-01-25  0:15 ` [PATCH 6.6.y 17/17] selftests/bpf: check if max number of bpf_loop iterations is tracked Eduard Zingerman
2024-01-27  1:13 ` [PATCH 6.6.y 00/17] bpf: backport of iterator and callback handling fixes Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240125001554.25287-15-eddyz87@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=martin.lau@linux.dev \
    --cc=mat.gienieczko@tum.de \
    --cc=mykolal@fb.com \
    --cc=stable@vger.kernel.org \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.