diff options
Diffstat (limited to 'kernel/bpf')
| -rw-r--r-- | kernel/bpf/Makefile | 1 | ||||
| -rw-r--r-- | kernel/bpf/core.c | 21 | ||||
| -rw-r--r-- | kernel/bpf/cpumap.c | 4 | ||||
| -rw-r--r-- | kernel/bpf/crypto.c | 2 | ||||
| -rw-r--r-- | kernel/bpf/helpers.c | 16 | ||||
| -rw-r--r-- | kernel/bpf/rqspinlock.c | 2 | ||||
| -rw-r--r-- | kernel/bpf/verifier.c | 6 | 
7 files changed, 36 insertions, 16 deletions
| diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile index 269c04a24664..f6cf8c2af5f7 100644 --- a/kernel/bpf/Makefile +++ b/kernel/bpf/Makefile @@ -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) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 5d1650af899d..e4568d44e827 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -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 @@ out:  	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, diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c index b2b7b8ec2c2a..c46360b27871 100644 --- a/kernel/bpf/cpumap.c +++ b/kernel/bpf/cpumap.c @@ -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(); diff --git a/kernel/bpf/crypto.c b/kernel/bpf/crypto.c index 94854cd9c4cc..83c4d9943084 100644 --- a/kernel/bpf/crypto.c +++ b/kernel/bpf/crypto.c @@ -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) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index cdffd74ddbe6..67d49059aebb 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -1274,8 +1274,11 @@ static int __bpf_async_init(struct bpf_async_kern *async, struct bpf_map *map, u  		goto out;  	} -	/* allocate hrtimer via map_kmalloc to use memcg accounting */ -	cb = bpf_map_kmalloc_node(map, size, GFP_ATOMIC, map->numa_node); +	/* Allocate via bpf_map_kmalloc_node() for memcg accounting. Until +	 * kmalloc_nolock() is available, avoid locking issues by using +	 * __GFP_HIGH (GFP_ATOMIC & ~__GFP_RECLAIM). +	 */ +	cb = bpf_map_kmalloc_node(map, size, __GFP_HIGH, map->numa_node);  	if (!cb) {  		ret = -ENOMEM;  		goto out; @@ -3675,10 +3678,17 @@ __bpf_kfunc int bpf_strnstr(const char *s1__ign, const char *s2__ign, size_t len  	guard(pagefault)();  	for (i = 0; i < XATTR_SIZE_MAX; i++) { -		for (j = 0; i + j < len && j < XATTR_SIZE_MAX; j++) { +		for (j = 0; i + j <= len && j < XATTR_SIZE_MAX; j++) {  			__get_kernel_nofault(&c2, s2__ign + j, char, err_out);  			if (c2 == '\0')  				return i; +			/* +			 * We allow reading an extra byte from s2 (note the +			 * `i + j <= len` above) to cover the case when s2 is +			 * a suffix of the first len chars of s1. +			 */ +			if (i + j == len) +				break;  			__get_kernel_nofault(&c1, s1__ign + j, char, err_out);  			if (c1 == '\0')  				return -ENOENT; diff --git a/kernel/bpf/rqspinlock.c b/kernel/bpf/rqspinlock.c index 5ab354d55d82..a00561b1d3e5 100644 --- a/kernel/bpf/rqspinlock.c +++ b/kernel/bpf/rqspinlock.c @@ -471,7 +471,7 @@ queue:  	 * any MCS node. This is not the most elegant solution, but is  	 * simple enough.  	 */ -	if (unlikely(idx >= _Q_MAX_NODES)) { +	if (unlikely(idx >= _Q_MAX_NODES || in_nmi())) {  		lockevent_inc(lock_no_node);  		RES_RESET_TIMEOUT(ts, RES_DEF_TIMEOUT);  		while (!queued_spin_trylock(lock)) { diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 5964bed40ffb..27f0bc28ee12 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8552,6 +8552,10 @@ static int process_timer_func(struct bpf_verifier_env *env, int regno,  		verifier_bug(env, "Two map pointers in a timer helper");  		return -EFAULT;  	} +	if (IS_ENABLED(CONFIG_PREEMPT_RT)) { +		verbose(env, "bpf_timer cannot be used for PREEMPT_RT.\n"); +		return -EOPNOTSUPP; +	}  	meta->map_uid = reg->map_uid;  	meta->map_ptr = map;  	return 0; @@ -11359,7 +11363,7 @@ static int get_helper_proto(struct bpf_verifier_env *env, int func_id,  		return -EINVAL;  	*ptr = env->ops->get_func_proto(func_id, env->prog); -	return *ptr ? 0 : -EINVAL; +	return *ptr && (*ptr)->func ? 0 : -EINVAL;  }  static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn, | 
