From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <martin.lau@linux.dev>,
Yonghong Song <yonghong.song@linux.dev>,
David Vernet <void@manifault.com>,
Puranjay Mohan <puranjay12@gmail.com>
Subject: [PATCH bpf-next v3 08/17] bpf: Treat first argument as return value for bpf_throw
Date: Wed, 13 Sep 2023 01:32:05 +0200 [thread overview]
Message-ID: <20230912233214.1518551-9-memxor@gmail.com> (raw)
In-Reply-To: <20230912233214.1518551-1-memxor@gmail.com>
In case of the default exception callback, change the behavior of
bpf_throw, where the passed cookie value is no longer ignored, but
is instead the return value of the default exception callback. As
such, we need to place restrictions on the value being passed into
bpf_throw in such a case, only allowing those permitted by the
check_return_code function.
Thus, bpf_throw can now control the return value of the program from
each call site without having the user install a custom exception
callback just to override the return value when an exception is thrown.
We also modify the hidden subprog instructions to now move BPF_REG_1 to
BPF_REG_0, so as to set the return value before exit in the default
callback.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
kernel/bpf/verifier.c | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 863e4e6c4616..0ba32b626320 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -11485,6 +11485,8 @@ static int fetch_kfunc_meta(struct bpf_verifier_env *env,
return 0;
}
+static int check_return_code(struct bpf_verifier_env *env, int regno);
+
static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
int *insn_idx_p)
{
@@ -11613,6 +11615,15 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
return -ENOTSUPP;
}
env->seen_exception = true;
+
+ /* In the case of the default callback, the cookie value passed
+ * to bpf_throw becomes the return value of the program.
+ */
+ if (!env->exception_callback_subprog) {
+ err = check_return_code(env, BPF_REG_1);
+ if (err < 0)
+ return err;
+ }
}
for (i = 0; i < CALLER_SAVED_REGS; i++)
@@ -14709,7 +14720,7 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
return 0;
}
-static int check_return_code(struct bpf_verifier_env *env)
+static int check_return_code(struct bpf_verifier_env *env, int regno)
{
struct tnum enforce_attach_type_range = tnum_unknown;
const struct bpf_prog *prog = env->prog;
@@ -14743,22 +14754,22 @@ static int check_return_code(struct bpf_verifier_env *env)
* of bpf_exit, which means that program wrote
* something into it earlier
*/
- err = check_reg_arg(env, BPF_REG_0, SRC_OP);
+ err = check_reg_arg(env, regno, SRC_OP);
if (err)
return err;
- if (is_pointer_value(env, BPF_REG_0)) {
- verbose(env, "R0 leaks addr as return value\n");
+ if (is_pointer_value(env, regno)) {
+ verbose(env, "R%d leaks addr as return value\n", regno);
return -EACCES;
}
- reg = cur_regs(env) + BPF_REG_0;
+ reg = cur_regs(env) + regno;
if (frame->in_async_callback_fn) {
/* enforce return zero from async callbacks like timer */
if (reg->type != SCALAR_VALUE) {
- verbose(env, "In async callback the register R0 is not a known value (%s)\n",
- reg_type_str(env, reg->type));
+ verbose(env, "In async callback the register R%d is not a known value (%s)\n",
+ regno, reg_type_str(env, reg->type));
return -EINVAL;
}
@@ -14771,8 +14782,8 @@ static int check_return_code(struct bpf_verifier_env *env)
if (is_subprog && !frame->in_exception_callback_fn) {
if (reg->type != SCALAR_VALUE) {
- verbose(env, "At subprogram exit the register R0 is not a scalar value (%s)\n",
- reg_type_str(env, reg->type));
+ verbose(env, "At subprogram exit the register R%d is not a scalar value (%s)\n",
+ regno, reg_type_str(env, reg->type));
return -EINVAL;
}
return 0;
@@ -14854,8 +14865,8 @@ static int check_return_code(struct bpf_verifier_env *env)
}
if (reg->type != SCALAR_VALUE) {
- verbose(env, "At program exit the register R0 is not a known value (%s)\n",
- reg_type_str(env, reg->type));
+ verbose(env, "At program exit the register R%d is not a known value (%s)\n",
+ regno, reg_type_str(env, reg->type));
return -EINVAL;
}
@@ -17053,7 +17064,7 @@ static int do_check(struct bpf_verifier_env *env)
continue;
}
- err = check_return_code(env);
+ err = check_return_code(env, BPF_REG_0);
if (err)
return err;
process_bpf_exit:
@@ -18722,7 +18733,7 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
if (env->seen_exception && !env->exception_callback_subprog) {
struct bpf_insn patch[] = {
env->prog->insnsi[insn_cnt - 1],
- BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
BPF_EXIT_INSN(),
};
--
2.41.0
next prev parent reply other threads:[~2023-09-12 23:32 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-12 23:31 [PATCH bpf-next v3 00/17] Exceptions - 1/2 Kumar Kartikeya Dwivedi
2023-09-12 23:31 ` [PATCH bpf-next v3 01/17] bpf: Use bpf_is_subprog to check for subprogs Kumar Kartikeya Dwivedi
2023-09-12 23:31 ` [PATCH bpf-next v3 02/17] arch/x86: Implement arch_bpf_stack_walk Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 03/17] bpf: Implement support for adding hidden subprogs Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 04/17] bpf: Implement BPF exceptions Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 05/17] bpf: Refactor check_btf_func and split into two phases Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 06/17] bpf: Add support for custom exception callbacks Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 07/17] bpf: Perform CFG walk for exception callback Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` Kumar Kartikeya Dwivedi [this message]
2023-09-12 23:32 ` [PATCH bpf-next v3 09/17] mm: kasan: Declare kasan_unpoison_task_stack_below in kasan.h Kumar Kartikeya Dwivedi
2023-09-16 16:24 ` Andrey Konovalov
2023-09-12 23:32 ` [PATCH bpf-next v3 10/17] bpf: Prevent KASAN false positive with bpf_throw Kumar Kartikeya Dwivedi
2023-09-16 16:25 ` Andrey Konovalov
2023-09-18 13:20 ` Matthieu Baerts
2023-09-18 13:26 ` Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 11/17] bpf: Detect IP == ksym.end as part of BPF program Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 12/17] bpf: Disallow fentry/fexit/freplace for exception callbacks Kumar Kartikeya Dwivedi
2023-09-13 15:24 ` Puranjay Mohan
2023-09-14 12:13 ` Kumar Kartikeya Dwivedi
2023-09-16 16:44 ` Alexei Starovoitov
2023-09-16 17:30 ` Kumar Kartikeya Dwivedi
2023-09-16 19:34 ` Kumar Kartikeya Dwivedi
2023-09-18 1:56 ` Alexei Starovoitov
2023-09-12 23:32 ` [PATCH bpf-next v3 13/17] bpf: Fix kfunc callback register type handling Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 14/17] libbpf: Refactor bpf_object__reloc_code Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 15/17] libbpf: Add support for custom exception callbacks Kumar Kartikeya Dwivedi
2023-09-20 0:25 ` Andrii Nakryiko
2023-09-20 1:02 ` Kumar Kartikeya Dwivedi
2023-09-20 17:08 ` Andrii Nakryiko
2023-09-12 23:32 ` [PATCH bpf-next v3 16/17] selftests/bpf: Add BPF assertion macros Kumar Kartikeya Dwivedi
2023-09-12 23:32 ` [PATCH bpf-next v3 17/17] selftests/bpf: Add tests for BPF exceptions Kumar Kartikeya Dwivedi
2023-09-13 15:14 ` Puranjay Mohan
2023-09-13 16:12 ` Puranjay Mohan
2023-09-12 23:37 ` [PATCH bpf-next v3 00/17] Exceptions - 1/2 Kumar Kartikeya Dwivedi
2023-09-12 23:53 ` Puranjay Mohan
2023-09-16 16:50 ` patchwork-bot+netdevbpf
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=20230912233214.1518551-9-memxor@gmail.com \
--to=memxor@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=martin.lau@linux.dev \
--cc=puranjay12@gmail.com \
--cc=void@manifault.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox