[PATCH] net: lwt_bpf: replace name-based BPF program comparison with digest

Matan Cohen posted 1 patch 1 month, 2 weeks ago
net/core/lwt_bpf.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
[PATCH] net: lwt_bpf: replace name-based BPF program comparison with digest
Posted by Matan Cohen 1 month, 2 weeks ago
bpf_lwt_prog_cmp() used strcmp() on program names as a workaround
because delete requests rebuild the LWT state, creating a new
bpf_prog instance for the same program.

Name comparison is unreliable: programs with the same name but
different instructions compare equal, while instruction-identical
programs with different names compare unequal.

Replace it with a two-step approach:
- Pointer equality as a cheap fast path.
- SHA256 digest comparison as the fallback. bpf_prog_calc_tag()
  computes the digest (instructions with map fds zeroed) at the
  end of bpf_check(), so it is valid for every successfully
  loaded BPF program.

Signed-off-by: Matan Cohen <matan@matanco.space>
---
 net/core/lwt_bpf.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c
index f71ef82a5f3d3..6999da98b6b97 100644
--- a/net/core/lwt_bpf.c
+++ b/net/core/lwt_bpf.c
@@ -494,17 +494,20 @@ static int bpf_encap_nlsize(struct lwtunnel_state *lwtstate)
 
 static int bpf_lwt_prog_cmp(struct bpf_lwt_prog *a, struct bpf_lwt_prog *b)
 {
-	/* FIXME:
-	 * The LWT state is currently rebuilt for delete requests which
-	 * results in a new bpf_prog instance. Comparing names for now.
+	/* Delete requests rebuild the LWT state, so pointer equality is
+	 * not sufficient. Compare by digest (SHA256 of instructions with
+	 * map fds zeroed by bpf_prog_calc_tag()) as a reliable fallback.
 	 */
-	if (!a->name && !b->name)
+	if (!a->prog && !b->prog)
 		return 0;
 
-	if (!a->name || !b->name)
+	if (!a->prog || !b->prog)
 		return 1;
 
-	return strcmp(a->name, b->name);
+	if (a->prog == b->prog)
+		return 0;
+
+	return memcmp(a->prog->digest, b->prog->digest, SHA256_DIGEST_SIZE);
 }
 
 static int bpf_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
-- 
2.43.0