diff --git a/include/linux/bpf.h b/include/linux/bpf.h index f87fb203aaaef..6d4d100380a44 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -940,6 +940,7 @@ struct bpf_func_proto { }; int *ret_btf_id; /* return value btf_id */ bool (*allowed)(const struct bpf_prog *prog); + bool must_not_sleep; }; /* bpf_context is intentionally undefined structure. Pointer to bpf_context is diff --git a/kernel/bpf/task_iter.c b/kernel/bpf/task_iter.c index 98d9b4c0daff3..5f43d91dc9021 100644 --- a/kernel/bpf/task_iter.c +++ b/kernel/bpf/task_iter.c @@ -792,6 +792,7 @@ const struct bpf_func_proto bpf_find_vma_proto = { .arg3_type = ARG_PTR_TO_FUNC, .arg4_type = ARG_PTR_TO_STACK_OR_NULL, .arg5_type = ARG_ANYTHING, + .must_not_sleep = false, }; struct bpf_iter_task_vma_kern_data { diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c908015b2d34b..6517b80e7d887 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -11431,6 +11431,11 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn return -EINVAL; } + if (in_sleepable(env) && fn->must_not_sleep) { + verbose(env, "helper call must not sleep, but called in a sleepable prog\n"); + return -EINVAL; + } + /* With LD_ABS/IND some JITs save/restore skb from r1. */ changes_data = bpf_helper_changes_pkt_data(func_id); if (changes_data && fn->arg1_type != ARG_PTR_TO_CTX) {