bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link
@ 2022-01-07 22:11 Toke Høiland-Jørgensen
  2022-01-07 22:11 ` [PATCH bpf v2 2/3] bpf/selftests: convert xdp_link test to ASSERT_* macros Toke Høiland-Jørgensen
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Toke Høiland-Jørgensen @ 2022-01-07 22:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
	Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, Yonghong Song,
	KP Singh
  Cc: Toke Høiland-Jørgensen, syzbot+983941aa85af6ded1fd9,
	netdev, bpf

The bpf_xdp_link_update() function didn't check the program type before
updating the program, which made it possible to install any program type as
an XDP program, which is obviously not good. Syzbot managed to trigger this
by swapping in an LWT program on the XDP hook which would crash in a helper
call.

Fix this by adding a check and bailing out if the types don't match.

Fixes: 026a4c28e1db ("bpf, xdp: Implement LINK_UPDATE for BPF XDP link")
Reported-by: syzbot+983941aa85af6ded1fd9@syzkaller.appspotmail.com
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 net/core/dev.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index c4708e2487fb..2078d04c6482 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9656,6 +9656,12 @@ static int bpf_xdp_link_update(struct bpf_link *link, struct bpf_prog *new_prog,
 		goto out_unlock;
 	}
 	old_prog = link->prog;
+	if (old_prog->type != new_prog->type ||
+	    old_prog->expected_attach_type != new_prog->expected_attach_type) {
+		err = -EINVAL;
+		goto out_unlock;
+	}
+
 	if (old_prog == new_prog) {
 		/* no-op, don't disturb drivers */
 		bpf_prog_put(new_prog);
-- 
2.34.1


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

* [PATCH bpf v2 2/3] bpf/selftests: convert xdp_link test to ASSERT_* macros
  2022-01-07 22:11 [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Toke Høiland-Jørgensen
@ 2022-01-07 22:11 ` Toke Høiland-Jørgensen
  2022-01-07 22:11 ` [PATCH bpf v2 3/3] bpf/selftests: Add check for updating XDP bpf_link with wrong program type Toke Høiland-Jørgensen
  2022-01-08 19:37 ` [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Alexei Starovoitov
  2 siblings, 0 replies; 6+ messages in thread
From: Toke Høiland-Jørgensen @ 2022-01-07 22:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
	Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, Yonghong Song,
	KP Singh
  Cc: Toke Høiland-Jørgensen, Shuah Khan, netdev, bpf

Convert the selftest to use the preferred ASSERT_* macros instead of the
deprecated CHECK().

v2:
- Don't add if statements around checks if they weren't there before.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 .../selftests/bpf/prog_tests/xdp_link.c       | 56 +++++++++----------
 1 file changed, 25 insertions(+), 31 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_link.c b/tools/testing/selftests/bpf/prog_tests/xdp_link.c
index 983ab0b47d30..eec0bf83546b 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_link.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_link.c
@@ -8,46 +8,47 @@
 
 void serial_test_xdp_link(void)
 {
-	__u32 duration = 0, id1, id2, id0 = 0, prog_fd1, prog_fd2, err;
 	DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, .old_fd = -1);
 	struct test_xdp_link *skel1 = NULL, *skel2 = NULL;
+	__u32 id1, id2, id0 = 0, prog_fd1, prog_fd2;
 	struct bpf_link_info link_info;
 	struct bpf_prog_info prog_info;
 	struct bpf_link *link;
+	int err;
 	__u32 link_info_len = sizeof(link_info);
 	__u32 prog_info_len = sizeof(prog_info);
 
 	skel1 = test_xdp_link__open_and_load();
-	if (CHECK(!skel1, "skel_load", "skeleton open and load failed\n"))
+	if (!ASSERT_OK_PTR(skel1, "skel_load"))
 		goto cleanup;
 	prog_fd1 = bpf_program__fd(skel1->progs.xdp_handler);
 
 	skel2 = test_xdp_link__open_and_load();
-	if (CHECK(!skel2, "skel_load", "skeleton open and load failed\n"))
+	if (!ASSERT_OK_PTR(skel2, "skel_load"))
 		goto cleanup;
 	prog_fd2 = bpf_program__fd(skel2->progs.xdp_handler);
 
 	memset(&prog_info, 0, sizeof(prog_info));
 	err = bpf_obj_get_info_by_fd(prog_fd1, &prog_info, &prog_info_len);
-	if (CHECK(err, "fd_info1", "failed %d\n", -errno))
+	if (!ASSERT_OK(err, "fd_info1"))
 		goto cleanup;
 	id1 = prog_info.id;
 
 	memset(&prog_info, 0, sizeof(prog_info));
 	err = bpf_obj_get_info_by_fd(prog_fd2, &prog_info, &prog_info_len);
-	if (CHECK(err, "fd_info2", "failed %d\n", -errno))
+	if (!ASSERT_OK(err, "fd_info2"))
 		goto cleanup;
 	id2 = prog_info.id;
 
 	/* set initial prog attachment */
 	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, prog_fd1, XDP_FLAGS_REPLACE, &opts);
-	if (CHECK(err, "fd_attach", "initial prog attach failed: %d\n", err))
+	if (!ASSERT_OK(err, "fd_attach"))
 		goto cleanup;
 
 	/* validate prog ID */
 	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
-	CHECK(err || id0 != id1, "id1_check",
-	      "loaded prog id %u != id1 %u, err %d", id0, id1, err);
+	if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))
+		goto cleanup;
 
 	/* BPF link is not allowed to replace prog attachment */
 	link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
@@ -62,7 +63,7 @@ void serial_test_xdp_link(void)
 	/* detach BPF program */
 	opts.old_fd = prog_fd1;
 	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, -1, XDP_FLAGS_REPLACE, &opts);
-	if (CHECK(err, "prog_detach", "failed %d\n", err))
+	if (!ASSERT_OK(err, "prog_detach"))
 		goto cleanup;
 
 	/* now BPF link should attach successfully */
@@ -73,24 +74,23 @@ void serial_test_xdp_link(void)
 
 	/* validate prog ID */
 	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
-	if (CHECK(err || id0 != id1, "id1_check",
-		  "loaded prog id %u != id1 %u, err %d", id0, id1, err))
+	if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))
 		goto cleanup;
 
 	/* BPF prog attach is not allowed to replace BPF link */
 	opts.old_fd = prog_fd1;
 	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, prog_fd2, XDP_FLAGS_REPLACE, &opts);
-	if (CHECK(!err, "prog_attach_fail", "unexpected success\n"))
+	if (!ASSERT_ERR(err, "prog_attach_fail"))
 		goto cleanup;
 
 	/* Can't force-update when BPF link is active */
 	err = bpf_set_link_xdp_fd(IFINDEX_LO, prog_fd2, 0);
-	if (CHECK(!err, "prog_update_fail", "unexpected success\n"))
+	if (!ASSERT_ERR(err, "prog_update_fail"))
 		goto cleanup;
 
 	/* Can't force-detach when BPF link is active */
 	err = bpf_set_link_xdp_fd(IFINDEX_LO, -1, 0);
-	if (CHECK(!err, "prog_detach_fail", "unexpected success\n"))
+	if (!ASSERT_ERR(err, "prog_detach_fail"))
 		goto cleanup;
 
 	/* BPF link is not allowed to replace another BPF link */
@@ -110,40 +110,34 @@ void serial_test_xdp_link(void)
 	skel2->links.xdp_handler = link;
 
 	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
-	if (CHECK(err || id0 != id2, "id2_check",
-		  "loaded prog id %u != id2 %u, err %d", id0, id1, err))
+	if (!ASSERT_OK(err, "id2_check_err") || !ASSERT_EQ(id0, id2, "id2_check_val"))
 		goto cleanup;
 
 	/* updating program under active BPF link works as expected */
 	err = bpf_link__update_program(link, skel1->progs.xdp_handler);
-	if (CHECK(err, "link_upd", "failed: %d\n", err))
+	if (!ASSERT_OK(err, "link_upd"))
 		goto cleanup;
 
 	memset(&link_info, 0, sizeof(link_info));
 	err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
-	if (CHECK(err, "link_info", "failed: %d\n", err))
+	if (!ASSERT_OK(err, "link_info"))
 		goto cleanup;
 
-	CHECK(link_info.type != BPF_LINK_TYPE_XDP, "link_type",
-	      "got %u != exp %u\n", link_info.type, BPF_LINK_TYPE_XDP);
-	CHECK(link_info.prog_id != id1, "link_prog_id",
-	      "got %u != exp %u\n", link_info.prog_id, id1);
-	CHECK(link_info.xdp.ifindex != IFINDEX_LO, "link_ifindex",
-	      "got %u != exp %u\n", link_info.xdp.ifindex, IFINDEX_LO);
+	ASSERT_EQ(link_info.type, BPF_LINK_TYPE_XDP, "link_type");
+	ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
+	ASSERT_EQ(link_info.xdp.ifindex, IFINDEX_LO, "link_ifindex");
 
 	err = bpf_link__detach(link);
-	if (CHECK(err, "link_detach", "failed %d\n", err))
+	if (!ASSERT_OK(err, "link_detach"))
 		goto cleanup;
 
 	memset(&link_info, 0, sizeof(link_info));
 	err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
-	if (CHECK(err, "link_info", "failed: %d\n", err))
-		goto cleanup;
-	CHECK(link_info.prog_id != id1, "link_prog_id",
-	      "got %u != exp %u\n", link_info.prog_id, id1);
+
+	ASSERT_OK(err, "link_info");
+	ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
 	/* ifindex should be zeroed out */
-	CHECK(link_info.xdp.ifindex != 0, "link_ifindex",
-	      "got %u != exp %u\n", link_info.xdp.ifindex, 0);
+	ASSERT_EQ(link_info.xdp.ifindex, 0, "link_ifindex");
 
 cleanup:
 	test_xdp_link__destroy(skel1);
-- 
2.34.1


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

* [PATCH bpf v2 3/3] bpf/selftests: Add check for updating XDP bpf_link with wrong program type
  2022-01-07 22:11 [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Toke Høiland-Jørgensen
  2022-01-07 22:11 ` [PATCH bpf v2 2/3] bpf/selftests: convert xdp_link test to ASSERT_* macros Toke Høiland-Jørgensen
@ 2022-01-07 22:11 ` Toke Høiland-Jørgensen
  2022-01-08 19:37 ` [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Alexei Starovoitov
  2 siblings, 0 replies; 6+ messages in thread
From: Toke Høiland-Jørgensen @ 2022-01-07 22:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
	Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, Yonghong Song,
	KP Singh
  Cc: Toke Høiland-Jørgensen, Shuah Khan, netdev, bpf

Add a check to the xdp_link selftest that the kernel rejects replacing an
XDP program with a different program type on link update.

v2:
- Split this out into its own patch.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 tools/testing/selftests/bpf/prog_tests/xdp_link.c | 5 +++++
 tools/testing/selftests/bpf/progs/test_xdp_link.c | 6 ++++++
 2 files changed, 11 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_link.c b/tools/testing/selftests/bpf/prog_tests/xdp_link.c
index eec0bf83546b..b2b357f8c74c 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_link.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_link.c
@@ -127,6 +127,11 @@ void serial_test_xdp_link(void)
 	ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
 	ASSERT_EQ(link_info.xdp.ifindex, IFINDEX_LO, "link_ifindex");
 
+	/* updating program under active BPF link with different type fails */
+	err = bpf_link__update_program(link, skel1->progs.tc_handler);
+	if (!ASSERT_ERR(err, "link_upd_invalid"))
+		goto cleanup;
+
 	err = bpf_link__detach(link);
 	if (!ASSERT_OK(err, "link_detach"))
 		goto cleanup;
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_link.c b/tools/testing/selftests/bpf/progs/test_xdp_link.c
index ee7d6ac0f615..64ff32eaae92 100644
--- a/tools/testing/selftests/bpf/progs/test_xdp_link.c
+++ b/tools/testing/selftests/bpf/progs/test_xdp_link.c
@@ -10,3 +10,9 @@ int xdp_handler(struct xdp_md *xdp)
 {
 	return 0;
 }
+
+SEC("tc")
+int tc_handler(struct __sk_buff *skb)
+{
+	return 0;
+}
-- 
2.34.1


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

* Re: [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link
  2022-01-07 22:11 [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Toke Høiland-Jørgensen
  2022-01-07 22:11 ` [PATCH bpf v2 2/3] bpf/selftests: convert xdp_link test to ASSERT_* macros Toke Høiland-Jørgensen
  2022-01-07 22:11 ` [PATCH bpf v2 3/3] bpf/selftests: Add check for updating XDP bpf_link with wrong program type Toke Høiland-Jørgensen
@ 2022-01-08 19:37 ` Alexei Starovoitov
  2022-01-08 20:21   ` Toke Høiland-Jørgensen
  2022-01-11 17:49   ` Alexei Starovoitov
  2 siblings, 2 replies; 6+ messages in thread
From: Alexei Starovoitov @ 2022-01-08 19:37 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
	Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, Yonghong Song,
	KP Singh, syzbot, Network Development, bpf

On Fri, Jan 7, 2022 at 2:11 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> The bpf_xdp_link_update() function didn't check the program type before
> updating the program, which made it possible to install any program type as
> an XDP program, which is obviously not good. Syzbot managed to trigger this
> by swapping in an LWT program on the XDP hook which would crash in a helper
> call.
>
> Fix this by adding a check and bailing out if the types don't match.
>
> Fixes: 026a4c28e1db ("bpf, xdp: Implement LINK_UPDATE for BPF XDP link")
> Reported-by: syzbot+983941aa85af6ded1fd9@syzkaller.appspotmail.com
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>

Thanks a lot for the quick fix!
The merge window is about to begin.
We will land it as soon as possible when bpf tree will be ready
to accept fixes.

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

* Re: [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link
  2022-01-08 19:37 ` [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Alexei Starovoitov
@ 2022-01-08 20:21   ` Toke Høiland-Jørgensen
  2022-01-11 17:49   ` Alexei Starovoitov
  1 sibling, 0 replies; 6+ messages in thread
From: Toke Høiland-Jørgensen @ 2022-01-08 20:21 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
	Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, Yonghong Song,
	KP Singh, syzbot, Network Development, bpf

Alexei Starovoitov <alexei.starovoitov@gmail.com> writes:

> On Fri, Jan 7, 2022 at 2:11 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>>
>> The bpf_xdp_link_update() function didn't check the program type before
>> updating the program, which made it possible to install any program type as
>> an XDP program, which is obviously not good. Syzbot managed to trigger this
>> by swapping in an LWT program on the XDP hook which would crash in a helper
>> call.
>>
>> Fix this by adding a check and bailing out if the types don't match.
>>
>> Fixes: 026a4c28e1db ("bpf, xdp: Implement LINK_UPDATE for BPF XDP link")
>> Reported-by: syzbot+983941aa85af6ded1fd9@syzkaller.appspotmail.com
>> Acked-by: Andrii Nakryiko <andrii@kernel.org>
>> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
>
> Thanks a lot for the quick fix!
> The merge window is about to begin.
> We will land it as soon as possible when bpf tree will be ready
> to accept fixes.

You're welcome! That's fine; FWIW, I believe the patch applies cleanly
to bpf-next as well, if that makes things easier on your end :)

-Toke


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

* Re: [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link
  2022-01-08 19:37 ` [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Alexei Starovoitov
  2022-01-08 20:21   ` Toke Høiland-Jørgensen
@ 2022-01-11 17:49   ` Alexei Starovoitov
  1 sibling, 0 replies; 6+ messages in thread
From: Alexei Starovoitov @ 2022-01-11 17:49 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
	Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, Yonghong Song,
	KP Singh, syzbot, Network Development, bpf

On Sat, Jan 8, 2022 at 11:37 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Jan 7, 2022 at 2:11 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
> >
> > The bpf_xdp_link_update() function didn't check the program type before
> > updating the program, which made it possible to install any program type as
> > an XDP program, which is obviously not good. Syzbot managed to trigger this
> > by swapping in an LWT program on the XDP hook which would crash in a helper
> > call.
> >
> > Fix this by adding a check and bailing out if the types don't match.
> >
> > Fixes: 026a4c28e1db ("bpf, xdp: Implement LINK_UPDATE for BPF XDP link")
> > Reported-by: syzbot+983941aa85af6ded1fd9@syzkaller.appspotmail.com
> > Acked-by: Andrii Nakryiko <andrii@kernel.org>
> > Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
>
> Thanks a lot for the quick fix!
> The merge window is about to begin.
> We will land it as soon as possible when bpf tree will be ready
> to accept fixes.

Applied to bpf tree.

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

end of thread, other threads:[~2022-01-11 17:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-07 22:11 [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Toke Høiland-Jørgensen
2022-01-07 22:11 ` [PATCH bpf v2 2/3] bpf/selftests: convert xdp_link test to ASSERT_* macros Toke Høiland-Jørgensen
2022-01-07 22:11 ` [PATCH bpf v2 3/3] bpf/selftests: Add check for updating XDP bpf_link with wrong program type Toke Høiland-Jørgensen
2022-01-08 19:37 ` [PATCH bpf v2 1/3] xdp: check prog type before updating BPF link Alexei Starovoitov
2022-01-08 20:21   ` Toke Høiland-Jørgensen
2022-01-11 17:49   ` Alexei Starovoitov

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).