bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf v3 1/2] bpf: enforce that struct_ops programs be GPL-only
@ 2021-03-26 10:03 Toke Høiland-Jørgensen
  2021-03-26 10:03 ` [PATCH bpf v3 2/2] bpf/selftests: test that kernel rejects a TCP CC with an invalid license Toke Høiland-Jørgensen
  2021-03-26 17:00 ` [PATCH bpf v3 1/2] bpf: enforce that struct_ops programs be GPL-only patchwork-bot+netdevbpf
  0 siblings, 2 replies; 3+ messages in thread
From: Toke Høiland-Jørgensen @ 2021-03-26 10:03 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann
  Cc: Toke Høiland-Jørgensen, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, David S. Miller,
	Jesper Dangaard Brouer, Andrea Arcangeli, Clark Williams, bpf,
	netdev

With the introduction of the struct_ops program type, it became possible to
implement kernel functionality in BPF, making it viable to use BPF in place
of a regular kernel module for these particular operations.

Thus far, the only user of this mechanism is for implementing TCP
congestion control algorithms. These are clearly marked as GPL-only when
implemented as modules (as seen by the use of EXPORT_SYMBOL_GPL for
tcp_register_congestion_control()), so it seems like an oversight that this
was not carried over to BPF implementations. Since this is the only user
of the struct_ops mechanism, just enforcing GPL-only for the struct_ops
program type seems like the simplest way to fix this.

v3: No change
v2: Move check to the top of check_struct_ops_btf_id().

Fixes: 0baf26b0fcd7 ("bpf: tcp: Support tcp_congestion_ops in bpf")
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 kernel/bpf/verifier.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 44e4ec1640f1..3a738724a380 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -12158,6 +12158,11 @@ static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
 	u32 btf_id, member_idx;
 	const char *mname;
 
+	if (!prog->gpl_compatible) {
+		verbose(env, "struct ops programs must have a GPL compatible license\n");
+		return -EINVAL;
+	}
+
 	btf_id = prog->aux->attach_btf_id;
 	st_ops = bpf_struct_ops_find(btf_id);
 	if (!st_ops) {
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH bpf v3 2/2] bpf/selftests: test that kernel rejects a TCP CC with an invalid license
  2021-03-26 10:03 [PATCH bpf v3 1/2] bpf: enforce that struct_ops programs be GPL-only Toke Høiland-Jørgensen
@ 2021-03-26 10:03 ` Toke Høiland-Jørgensen
  2021-03-26 17:00 ` [PATCH bpf v3 1/2] bpf: enforce that struct_ops programs be GPL-only patchwork-bot+netdevbpf
  1 sibling, 0 replies; 3+ messages in thread
From: Toke Høiland-Jørgensen @ 2021-03-26 10:03 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann
  Cc: Toke Høiland-Jørgensen, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, David S. Miller,
	Jesper Dangaard Brouer, Andrea Arcangeli, Clark Williams, bpf,
	netdev

This adds a selftest to check that the verifier rejects a TCP CC struct_ops
with a non-GPL license.

v3:
- Rename prog to bpf_tcp_nogpl
- Use ASSERT macros instead of CHECK
- Skip unneeded initialisation, unconditionally close skeleton
v2:
- Use a minimal struct_ops BPF program instead of rewriting bpf_dctcp's
  license in memory.
- Check for the verifier reject message instead of just the return code.

Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 .../selftests/bpf/prog_tests/bpf_tcp_ca.c     | 44 +++++++++++++++++++
 .../selftests/bpf/progs/bpf_tcp_nogpl.c       | 19 ++++++++
 2 files changed, 63 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/bpf_tcp_nogpl.c

diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
index 37c5494a0381..e25917f04602 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
@@ -6,6 +6,7 @@
 #include <test_progs.h>
 #include "bpf_dctcp.skel.h"
 #include "bpf_cubic.skel.h"
+#include "bpf_tcp_nogpl.skel.h"
 
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
@@ -227,10 +228,53 @@ static void test_dctcp(void)
 	bpf_dctcp__destroy(dctcp_skel);
 }
 
+static char *err_str;
+static bool found;
+
+static int libbpf_debug_print(enum libbpf_print_level level,
+			      const char *format, va_list args)
+{
+	char *log_buf;
+
+	if (level != LIBBPF_WARN ||
+	    strcmp(format, "libbpf: \n%s\n")) {
+		vprintf(format, args);
+		return 0;
+	}
+
+	log_buf = va_arg(args, char *);
+	if (!log_buf)
+		goto out;
+	if (err_str && strstr(log_buf, err_str) != NULL)
+		found = true;
+out:
+	printf(format, log_buf);
+	return 0;
+}
+
+static void test_invalid_license(void)
+{
+	libbpf_print_fn_t old_print_fn;
+	struct bpf_tcp_nogpl *skel;
+
+	err_str = "struct ops programs must have a GPL compatible license";
+	found = false;
+	old_print_fn = libbpf_set_print(libbpf_debug_print);
+
+	skel = bpf_tcp_nogpl__open_and_load();
+	ASSERT_NULL(skel, "bpf_tcp_nogpl");
+	ASSERT_EQ(found, true, "expected_err_msg");
+
+	bpf_tcp_nogpl__destroy(skel);
+	libbpf_set_print(old_print_fn);
+}
+
 void test_bpf_tcp_ca(void)
 {
 	if (test__start_subtest("dctcp"))
 		test_dctcp();
 	if (test__start_subtest("cubic"))
 		test_cubic();
+	if (test__start_subtest("invalid_license"))
+		test_invalid_license();
 }
diff --git a/tools/testing/selftests/bpf/progs/bpf_tcp_nogpl.c b/tools/testing/selftests/bpf/progs/bpf_tcp_nogpl.c
new file mode 100644
index 000000000000..2ecd833dcd41
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/bpf_tcp_nogpl.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+#include <linux/types.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+#include "bpf_tcp_helpers.h"
+
+char _license[] SEC("license") = "X";
+
+void BPF_STRUCT_OPS(nogpltcp_init, struct sock *sk)
+{
+}
+
+SEC(".struct_ops")
+struct tcp_congestion_ops bpf_nogpltcp = {
+	.init           = (void *)nogpltcp_init,
+	.name           = "bpf_nogpltcp",
+};
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf v3 1/2] bpf: enforce that struct_ops programs be GPL-only
  2021-03-26 10:03 [PATCH bpf v3 1/2] bpf: enforce that struct_ops programs be GPL-only Toke Høiland-Jørgensen
  2021-03-26 10:03 ` [PATCH bpf v3 2/2] bpf/selftests: test that kernel rejects a TCP CC with an invalid license Toke Høiland-Jørgensen
@ 2021-03-26 17:00 ` patchwork-bot+netdevbpf
  1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-03-26 17:00 UTC (permalink / raw)
  To: =?utf-8?b?VG9rZSBIw7hpbGFuZC1Kw7hyZ2Vuc2VuIDx0b2tlQHJlZGhhdC5jb20+?=
  Cc: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, davem, brouer, aarcange, williams, bpf, netdev

Hello:

This series was applied to bpf/bpf.git (refs/heads/master):

On Fri, 26 Mar 2021 11:03:13 +0100 you wrote:
> With the introduction of the struct_ops program type, it became possible to
> implement kernel functionality in BPF, making it viable to use BPF in place
> of a regular kernel module for these particular operations.
> 
> Thus far, the only user of this mechanism is for implementing TCP
> congestion control algorithms. These are clearly marked as GPL-only when
> implemented as modules (as seen by the use of EXPORT_SYMBOL_GPL for
> tcp_register_congestion_control()), so it seems like an oversight that this
> was not carried over to BPF implementations. Since this is the only user
> of the struct_ops mechanism, just enforcing GPL-only for the struct_ops
> program type seems like the simplest way to fix this.
> 
> [...]

Here is the summary with links:
  - [bpf,v3,1/2] bpf: enforce that struct_ops programs be GPL-only
    https://git.kernel.org/bpf/bpf/c/12aa8a9467b3
  - [bpf,v3,2/2] bpf/selftests: test that kernel rejects a TCP CC with an invalid license
    https://git.kernel.org/bpf/bpf/c/d8e8052e42d0

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] 3+ messages in thread

end of thread, other threads:[~2021-03-26 17:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-26 10:03 [PATCH bpf v3 1/2] bpf: enforce that struct_ops programs be GPL-only Toke Høiland-Jørgensen
2021-03-26 10:03 ` [PATCH bpf v3 2/2] bpf/selftests: test that kernel rejects a TCP CC with an invalid license Toke Høiland-Jørgensen
2021-03-26 17:00 ` [PATCH bpf v3 1/2] bpf: enforce that struct_ops programs be GPL-only patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).