|
Jiri Slaby |
5a6b25 |
From: Martin KaFai Lau <martin.lau@kernel.org>
|
|
Jiri Slaby |
5a6b25 |
Date: Thu, 16 Feb 2023 16:41:48 -0800
|
|
Jiri Slaby |
5a6b25 |
Subject: [PATCH] bpf: bpf_fib_lookup should not return neigh in NUD_FAILED
|
|
Jiri Slaby |
5a6b25 |
state
|
|
Jiri Slaby |
5a6b25 |
References: bsc#1012628
|
|
Jiri Slaby |
5a6b25 |
Patch-mainline: 6.2.2
|
|
Jiri Slaby |
5a6b25 |
Git-commit: 1fe4850b34ab512ff911e2c035c75fb6438f7307
|
|
Jiri Slaby |
5a6b25 |
|
|
Jiri Slaby |
5a6b25 |
commit 1fe4850b34ab512ff911e2c035c75fb6438f7307 upstream.
|
|
Jiri Slaby |
5a6b25 |
|
|
Jiri Slaby |
5a6b25 |
The bpf_fib_lookup() helper does not only look up the fib (ie. route)
|
|
Jiri Slaby |
5a6b25 |
but it also looks up the neigh. Before returning the neigh, the helper
|
|
Jiri Slaby |
5a6b25 |
does not check for NUD_VALID. When a neigh state (neigh->nud_state)
|
|
Jiri Slaby |
5a6b25 |
is in NUD_FAILED, its dmac (neigh->ha) could be all zeros. The helper
|
|
Jiri Slaby |
5a6b25 |
still returns SUCCESS instead of NO_NEIGH in this case. Because of the
|
|
Jiri Slaby |
5a6b25 |
SUCCESS return value, the bpf prog directly uses the returned dmac
|
|
Jiri Slaby |
5a6b25 |
and ends up filling all zero in the eth header.
|
|
Jiri Slaby |
5a6b25 |
|
|
Jiri Slaby |
5a6b25 |
This patch checks for NUD_VALID and returns NO_NEIGH if the neigh is
|
|
Jiri Slaby |
5a6b25 |
not valid.
|
|
Jiri Slaby |
5a6b25 |
|
|
Jiri Slaby |
5a6b25 |
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
|
|
Jiri Slaby |
5a6b25 |
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Jiri Slaby |
5a6b25 |
Link: https://lore.kernel.org/bpf/20230217004150.2980689-3-martin.lau@linux.dev
|
|
Jiri Slaby |
5a6b25 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Jiri Slaby |
5a6b25 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
5a6b25 |
---
|
|
Jiri Slaby |
5a6b25 |
net/core/filter.c | 4 ++--
|
|
Jiri Slaby |
5a6b25 |
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
Jiri Slaby |
5a6b25 |
|
|
Jiri Slaby |
5a6b25 |
diff --git a/net/core/filter.c b/net/core/filter.c
|
|
Jiri Slaby |
5a6b25 |
index 43cc1fe5..a00a4b54 100644
|
|
Jiri Slaby |
5a6b25 |
--- a/net/core/filter.c
|
|
Jiri Slaby |
5a6b25 |
+++ b/net/core/filter.c
|
|
Jiri Slaby |
5a6b25 |
@@ -5816,7 +5816,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
|
|
Jiri Slaby |
5a6b25 |
neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
|
|
Jiri Slaby |
5a6b25 |
}
|
|
Jiri Slaby |
5a6b25 |
|
|
Jiri Slaby |
5a6b25 |
- if (!neigh)
|
|
Jiri Slaby |
5a6b25 |
+ if (!neigh || !(neigh->nud_state & NUD_VALID))
|
|
Jiri Slaby |
5a6b25 |
return BPF_FIB_LKUP_RET_NO_NEIGH;
|
|
Jiri Slaby |
5a6b25 |
|
|
Jiri Slaby |
5a6b25 |
return bpf_fib_set_fwd_params(params, neigh, dev, mtu);
|
|
Jiri Slaby |
5a6b25 |
@@ -5931,7 +5931,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
|
|
Jiri Slaby |
5a6b25 |
* not needed here.
|
|
Jiri Slaby |
5a6b25 |
*/
|
|
Jiri Slaby |
5a6b25 |
neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
|
|
Jiri Slaby |
5a6b25 |
- if (!neigh)
|
|
Jiri Slaby |
5a6b25 |
+ if (!neigh || !(neigh->nud_state & NUD_VALID))
|
|
Jiri Slaby |
5a6b25 |
return BPF_FIB_LKUP_RET_NO_NEIGH;
|
|
Jiri Slaby |
5a6b25 |
|
|
Jiri Slaby |
5a6b25 |
return bpf_fib_set_fwd_params(params, neigh, dev, mtu);
|
|
Jiri Slaby |
5a6b25 |
--
|
|
Jiri Slaby |
5a6b25 |
2.35.3
|
|
Jiri Slaby |
5a6b25 |
|