Commit 02ffd6f8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull bpf fixes from Alexei Starovoitov:
 "A number of fixes accumulated due to summer vacations

   - Fix out-of-bounds dynptr write in bpf_crypto_crypt() kfunc which
     was misidentified as a security issue (Daniel Borkmann)

   - Update the list of BPF selftests maintainers (Eduard Zingerman)

   - Fix selftests warnings with icecc compiler (Ilya Leoshkevich)

   - Disable XDP/cpumap direct return optimization (Jesper Dangaard
     Brouer)

   - Fix unexpected get_helper_proto() result in unusual configuration
     BPF_SYSCALL=y and BPF_EVENTS=n (Jiri Olsa)

   - Allow fallback to interpreter when JIT support is limited (KaFai
     Wan)

   - Fix rqspinlock and choose trylock fallback for NMI waiters. Pick
     the simplest fix. More involved fix is targeted bpf-next (Kumar
     Kartikeya Dwivedi)

   - Fix cleanup when tcp_bpf_send_verdict() fails to allocate
     psock->cork (Kuniyuki Iwashima)

   - Disallow bpf_timer in PREEMPT_RT for now. Proper solution is being
     discussed for bpf-next. (Leon Hwang)

   - Fix XSK cq descriptor production (Maciej Fijalkowski)

   - Tell memcg to use allow_spinning=false path in bpf_timer_init() to
     avoid lockup in cgroup_file_notify() (Peilin Ye)

   - Fix bpf_strnstr() to handle suffix match cases (Rong Tao)"

* tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
  selftests/bpf: Skip timer cases when bpf_timer is not supported
  bpf: Reject bpf_timer for PREEMPT_RT
  tcp_bpf: Call sk_msg_free() when tcp_bpf_send_verdict() fails to allocate psock->cork.
  bpf: Tell memcg to use allow_spinning=false path in bpf_timer_init()
  bpf: Allow fall back to interpreter for programs with stack size <= 512
  rqspinlock: Choose trylock fallback for NMI waiters
  xsk: Fix immature cq descriptor production
  bpf: Update the list of BPF selftests maintainers
  selftests/bpf: Add tests for bpf_strnstr
  selftests/bpf: Fix "expression result unused" warnings with icecc
  bpf: Fix bpf_strnstr() to handle suffix match cases better
  selftests/bpf: Extend crypto_sanity selftest with invalid dst buffer
  bpf: Fix out-of-bounds dynptr write in bpf_crypto_crypt
  bpf: Check the helper function is valid in get_helper_proto
  bpf, cpumap: Disable page_pool direct xdp_return need larger scope
parents 4f553c1e 91f34aaa
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -4683,7 +4683,6 @@ F: security/bpf/
BPF [SELFTESTS] (Test Runners & Infrastructure)
M:	Andrii Nakryiko <andrii@kernel.org>
M:	Eduard Zingerman <eddyz87@gmail.com>
R:	Mykola Lysenko <mykolal@fb.com>
L:	bpf@vger.kernel.org
S:	Maintained
F:	tools/testing/selftests/bpf/
+1 −0
Original line number Diff line number Diff line
@@ -62,3 +62,4 @@ CFLAGS_REMOVE_bpf_lru_list.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_queue_stack_maps.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_lpm_trie.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_ringbuf.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_rqspinlock.o = $(CC_FLAGS_FTRACE)
+13 −8
Original line number Diff line number Diff line
@@ -2366,8 +2366,7 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx,
					 const struct bpf_insn *insn)
{
	/* If this handler ever gets executed, then BPF_JIT_ALWAYS_ON
	 * is not working properly, or interpreter is being used when
	 * prog->jit_requested is not 0, so warn about it!
	 * is not working properly, so warn about it!
	 */
	WARN_ON_ONCE(1);
	return 0;
@@ -2468,8 +2467,9 @@ static int bpf_check_tail_call(const struct bpf_prog *fp)
	return ret;
}

static void bpf_prog_select_func(struct bpf_prog *fp)
static bool bpf_prog_select_interpreter(struct bpf_prog *fp)
{
	bool select_interpreter = false;
#ifndef CONFIG_BPF_JIT_ALWAYS_ON
	u32 stack_depth = max_t(u32, fp->aux->stack_depth, 1);
	u32 idx = (round_up(stack_depth, 32) / 32) - 1;
@@ -2478,15 +2478,16 @@ static void bpf_prog_select_func(struct bpf_prog *fp)
	 * But for non-JITed programs, we don't need bpf_func, so no bounds
	 * check needed.
	 */
	if (!fp->jit_requested &&
	    !WARN_ON_ONCE(idx >= ARRAY_SIZE(interpreters))) {
	if (idx < ARRAY_SIZE(interpreters)) {
		fp->bpf_func = interpreters[idx];
		select_interpreter = true;
	} else {
		fp->bpf_func = __bpf_prog_ret0_warn;
	}
#else
	fp->bpf_func = __bpf_prog_ret0_warn;
#endif
	return select_interpreter;
}

/**
@@ -2505,7 +2506,7 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
	/* In case of BPF to BPF calls, verifier did all the prep
	 * work with regards to JITing, etc.
	 */
	bool jit_needed = fp->jit_requested;
	bool jit_needed = false;

	if (fp->bpf_func)
		goto finalize;
@@ -2514,7 +2515,8 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
	    bpf_prog_has_kfunc_call(fp))
		jit_needed = true;

	bpf_prog_select_func(fp);
	if (!bpf_prog_select_interpreter(fp))
		jit_needed = true;

	/* eBPF JITs can rewrite the program in case constant
	 * blinding is active. However, in case of error during
@@ -3024,7 +3026,10 @@ EXPORT_SYMBOL_GPL(bpf_event_output);

/* Always built-in helper functions. */
const struct bpf_func_proto bpf_tail_call_proto = {
	.func		= NULL,
	/* func is unused for tail_call, we set it to pass the
	 * get_helper_proto check
	 */
	.func		= BPF_PTR_POISON,
	.gpl_only	= false,
	.ret_type	= RET_VOID,
	.arg1_type	= ARG_PTR_TO_CTX,
+2 −2
Original line number Diff line number Diff line
@@ -186,7 +186,6 @@ static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu,
	struct xdp_buff xdp;
	int i, nframes = 0;

	xdp_set_return_frame_no_direct();
	xdp.rxq = &rxq;

	for (i = 0; i < n; i++) {
@@ -231,7 +230,6 @@ static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu,
		}
	}

	xdp_clear_return_frame_no_direct();
	stats->pass += nframes;

	return nframes;
@@ -255,6 +253,7 @@ static void cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames,

	rcu_read_lock();
	bpf_net_ctx = bpf_net_ctx_set(&__bpf_net_ctx);
	xdp_set_return_frame_no_direct();

	ret->xdp_n = cpu_map_bpf_prog_run_xdp(rcpu, frames, ret->xdp_n, stats);
	if (unlikely(ret->skb_n))
@@ -264,6 +263,7 @@ static void cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames,
	if (stats->redirect)
		xdp_do_flush();

	xdp_clear_return_frame_no_direct();
	bpf_net_ctx_clear(bpf_net_ctx);
	rcu_read_unlock();

+1 −1
Original line number Diff line number Diff line
@@ -278,7 +278,7 @@ static int bpf_crypto_crypt(const struct bpf_crypto_ctx *ctx,
	siv_len = siv ? __bpf_dynptr_size(siv) : 0;
	src_len = __bpf_dynptr_size(src);
	dst_len = __bpf_dynptr_size(dst);
	if (!src_len || !dst_len)
	if (!src_len || !dst_len || src_len > dst_len)
		return -EINVAL;

	if (siv_len != ctx->siv_len)
Loading