* [PATCH bpf-next v5 1/3] bpf: add destructive kfunc flag
2022-08-10 6:59 [PATCH bpf-next v5 0/3] destructive bpf_kfuncs Artem Savkov
@ 2022-08-10 6:59 ` Artem Savkov
2022-08-10 6:59 ` [PATCH bpf-next v5 2/3] bpf: export crash_kexec() as destructive kfunc Artem Savkov
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Artem Savkov @ 2022-08-10 6:59 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, bpf, netdev
Cc: linux-kernel, Andrea Arcangeli, Daniel Vacek, Jiri Olsa, Song Liu,
Daniel Xu, Kumar Kartikeya Dwivedi, Artem Savkov
Add KF_DESTRUCTIVE flag for destructive functions. Functions with this
flag set will require CAP_SYS_BOOT capabilities.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
---
Documentation/bpf/kfuncs.rst | 9 +++++++++
include/linux/btf.h | 3 ++-
kernel/bpf/verifier.c | 5 +++++
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
index c8b21de1c772..781731749e55 100644
--- a/Documentation/bpf/kfuncs.rst
+++ b/Documentation/bpf/kfuncs.rst
@@ -152,6 +152,15 @@ ensure the integrity of the operation being performed on the expected object.
The KF_SLEEPABLE flag is used for kfuncs that may sleep. Such kfuncs can only
be called by sleepable BPF programs (BPF_F_SLEEPABLE).
+2.4.7 KF_DESTRUCTIVE flag
+--------------------------
+
+The KF_DESTRUCTIVE flag is used to indicate functions calling which is
+destructive to the system. For example such a call can result in system
+rebooting or panicking. Due to this additional restrictions apply to these
+calls. At the moment they only require CAP_SYS_BOOT capability, but more can be
+added later.
+
2.5 Registering the kfuncs
--------------------------
diff --git a/include/linux/btf.h b/include/linux/btf.h
index 976cbdd2981f..ad93c2d9cc1c 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -49,7 +49,8 @@
* for this case.
*/
#define KF_TRUSTED_ARGS (1 << 4) /* kfunc only takes trusted pointer arguments */
-#define KF_SLEEPABLE (1 << 5) /* kfunc may sleep */
+#define KF_SLEEPABLE (1 << 5) /* kfunc may sleep */
+#define KF_DESTRUCTIVE (1 << 6) /* kfunc performs destructive actions */
struct btf;
struct btf_member;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 28b02dc67a2a..2c1f8069f7b7 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -7584,6 +7584,11 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
func_name);
return -EACCES;
}
+ if (*kfunc_flags & KF_DESTRUCTIVE && !capable(CAP_SYS_BOOT)) {
+ verbose(env, "destructive kfunc calls require CAP_SYS_BOOT capabilities\n");
+ return -EACCES;
+ }
+
acq = *kfunc_flags & KF_ACQUIRE;
/* Check the arguments */
--
2.37.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH bpf-next v5 2/3] bpf: export crash_kexec() as destructive kfunc
2022-08-10 6:59 [PATCH bpf-next v5 0/3] destructive bpf_kfuncs Artem Savkov
2022-08-10 6:59 ` [PATCH bpf-next v5 1/3] bpf: add destructive kfunc flag Artem Savkov
@ 2022-08-10 6:59 ` Artem Savkov
2022-08-10 6:59 ` [PATCH bpf-next v5 3/3] selftests/bpf: add destructive kfunc test Artem Savkov
2022-08-10 16:30 ` [PATCH bpf-next v5 0/3] destructive bpf_kfuncs patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: Artem Savkov @ 2022-08-10 6:59 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, bpf, netdev
Cc: linux-kernel, Andrea Arcangeli, Daniel Vacek, Jiri Olsa, Song Liu,
Daniel Xu, Kumar Kartikeya Dwivedi, Artem Savkov
Allow properly marked bpf programs to call crash_kexec().
Signed-off-by: Artem Savkov <asavkov@redhat.com>
---
kernel/bpf/helpers.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index a95eb9fb01ff..3c1b9bbcf971 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -1725,3 +1725,21 @@ bpf_base_func_proto(enum bpf_func_id func_id)
return NULL;
}
}
+
+BTF_SET8_START(tracing_btf_ids)
+#ifdef CONFIG_KEXEC_CORE
+BTF_ID_FLAGS(func, crash_kexec, KF_DESTRUCTIVE)
+#endif
+BTF_SET8_END(tracing_btf_ids)
+
+static const struct btf_kfunc_id_set tracing_kfunc_set = {
+ .owner = THIS_MODULE,
+ .set = &tracing_btf_ids,
+};
+
+static int __init kfunc_init(void)
+{
+ return register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &tracing_kfunc_set);
+}
+
+late_initcall(kfunc_init);
--
2.37.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH bpf-next v5 3/3] selftests/bpf: add destructive kfunc test
2022-08-10 6:59 [PATCH bpf-next v5 0/3] destructive bpf_kfuncs Artem Savkov
2022-08-10 6:59 ` [PATCH bpf-next v5 1/3] bpf: add destructive kfunc flag Artem Savkov
2022-08-10 6:59 ` [PATCH bpf-next v5 2/3] bpf: export crash_kexec() as destructive kfunc Artem Savkov
@ 2022-08-10 6:59 ` Artem Savkov
2022-08-10 16:30 ` [PATCH bpf-next v5 0/3] destructive bpf_kfuncs patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: Artem Savkov @ 2022-08-10 6:59 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, bpf, netdev
Cc: linux-kernel, Andrea Arcangeli, Daniel Vacek, Jiri Olsa, Song Liu,
Daniel Xu, Kumar Kartikeya Dwivedi, Artem Savkov
Add a test checking that programs calling destructive kfuncs can only do
so if they have CAP_SYS_BOOT capabilities.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
---
net/bpf/test_run.c | 5 +++
.../selftests/bpf/prog_tests/kfunc_call.c | 36 +++++++++++++++++++
.../bpf/progs/kfunc_call_destructive.c | 14 ++++++++
3 files changed, 55 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/kfunc_call_destructive.c
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index cbc9cd5058cb..afa7125252f6 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -695,6 +695,10 @@ noinline void bpf_kfunc_call_test_ref(struct prog_test_ref_kfunc *p)
{
}
+noinline void bpf_kfunc_call_test_destructive(void)
+{
+}
+
__diag_pop();
ALLOW_ERROR_INJECTION(bpf_modify_return_test, ERRNO);
@@ -719,6 +723,7 @@ BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_pass1)
BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_fail1)
BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_fail2)
BTF_ID_FLAGS(func, bpf_kfunc_call_test_ref, KF_TRUSTED_ARGS)
+BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE)
BTF_SET8_END(test_sk_check_kfunc_ids)
static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
diff --git a/tools/testing/selftests/bpf/prog_tests/kfunc_call.c b/tools/testing/selftests/bpf/prog_tests/kfunc_call.c
index c00eb974eb85..351fafa006fb 100644
--- a/tools/testing/selftests/bpf/prog_tests/kfunc_call.c
+++ b/tools/testing/selftests/bpf/prog_tests/kfunc_call.c
@@ -5,6 +5,9 @@
#include "kfunc_call_test.lskel.h"
#include "kfunc_call_test_subprog.skel.h"
#include "kfunc_call_test_subprog.lskel.h"
+#include "kfunc_call_destructive.skel.h"
+
+#include "cap_helpers.h"
static void test_main(void)
{
@@ -86,6 +89,36 @@ static void test_subprog_lskel(void)
kfunc_call_test_subprog_lskel__destroy(skel);
}
+static int test_destructive_open_and_load(void)
+{
+ struct kfunc_call_destructive *skel;
+ int err;
+
+ skel = kfunc_call_destructive__open();
+ if (!ASSERT_OK_PTR(skel, "prog_open"))
+ return -1;
+
+ err = kfunc_call_destructive__load(skel);
+
+ kfunc_call_destructive__destroy(skel);
+
+ return err;
+}
+
+static void test_destructive(void)
+{
+ __u64 save_caps = 0;
+
+ ASSERT_OK(test_destructive_open_and_load(), "succesful_load");
+
+ if (!ASSERT_OK(cap_disable_effective(1ULL << CAP_SYS_BOOT, &save_caps), "drop_caps"))
+ return;
+
+ ASSERT_EQ(test_destructive_open_and_load(), -13, "no_caps_failure");
+
+ cap_enable_effective(save_caps, NULL);
+}
+
void test_kfunc_call(void)
{
if (test__start_subtest("main"))
@@ -96,4 +129,7 @@ void test_kfunc_call(void)
if (test__start_subtest("subprog_lskel"))
test_subprog_lskel();
+
+ if (test__start_subtest("destructive"))
+ test_destructive();
}
diff --git a/tools/testing/selftests/bpf/progs/kfunc_call_destructive.c b/tools/testing/selftests/bpf/progs/kfunc_call_destructive.c
new file mode 100644
index 000000000000..767472bc5a97
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/kfunc_call_destructive.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+
+extern void bpf_kfunc_call_test_destructive(void) __ksym;
+
+SEC("tc")
+int kfunc_destructive_test(void)
+{
+ bpf_kfunc_call_test_destructive();
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
--
2.37.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH bpf-next v5 0/3] destructive bpf_kfuncs
2022-08-10 6:59 [PATCH bpf-next v5 0/3] destructive bpf_kfuncs Artem Savkov
` (2 preceding siblings ...)
2022-08-10 6:59 ` [PATCH bpf-next v5 3/3] selftests/bpf: add destructive kfunc test Artem Savkov
@ 2022-08-10 16:30 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-08-10 16:30 UTC (permalink / raw)
To: Artem Savkov
Cc: ast, daniel, andrii, bpf, netdev, linux-kernel, aarcange, dvacek,
olsajiri, song, dxu, memxor
Hello:
This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:
On Wed, 10 Aug 2022 08:59:02 +0200 you wrote:
> eBPF is often used for kernel debugging, and one of the widely used and
> powerful debugging techniques is post-mortem debugging with a full memory dump.
> Triggering a panic at exactly the right moment allows the user to get such a
> dump and thus a better view at the system's state. Right now the only way to
> do this in BPF is to signal userspace to trigger kexec/panic. This is
> suboptimal as going through userspace requires context changes and adds
> significant delays taking system further away from "the right moment". On a
> single-cpu system the situation is even worse because BPF program won't even be
> able to block the thread of interest.
>
> [...]
Here is the summary with links:
- [bpf-next,v5,1/3] bpf: add destructive kfunc flag
https://git.kernel.org/bpf/bpf-next/c/4dd48c6f1f83
- [bpf-next,v5,2/3] bpf: export crash_kexec() as destructive kfunc
https://git.kernel.org/bpf/bpf-next/c/133790596406
- [bpf-next,v5,3/3] selftests/bpf: add destructive kfunc test
https://git.kernel.org/bpf/bpf-next/c/e33894581675
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread