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