Also fix bpf-bindsnoop, ttysnoop and sync libbpf. Resolves: bz#2253688 Resolves: bz#2249458
115 lines
4.0 KiB
Diff
115 lines
4.0 KiB
Diff
From abf7b251c1461dcbe0c1e75d1d0da71662c9fae1 Mon Sep 17 00:00:00 2001
|
|
From: Hengqi Chen <hengqi.chen@gmail.com>
|
|
Date: Sun, 17 Dec 2023 11:27:10 +0000
|
|
Subject: [PATCH] libbpf-tools: Fix bindsnoop for kernel v6.6+
|
|
|
|
The freebind field in struct inet_sock gone in recent kernel
|
|
versions due to some kernel refactor works ([0]). The change
|
|
breaks the bindsnoop tool. Fix it in a CO-RE way.
|
|
|
|
This should close #4838.
|
|
|
|
[0]: https://lore.kernel.org/all/20230816081547.1272409-1-edumazet@google.com/
|
|
|
|
Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
|
|
---
|
|
libbpf-tools/bindsnoop.bpf.c | 8 +++--
|
|
libbpf-tools/core_fixes.bpf.h | 56 +++++++++++++++++++++++++++++++++++
|
|
2 files changed, 61 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/libbpf-tools/bindsnoop.bpf.c b/libbpf-tools/bindsnoop.bpf.c
|
|
index 41dce942..ead19c67 100644
|
|
--- a/libbpf-tools/bindsnoop.bpf.c
|
|
+++ b/libbpf-tools/bindsnoop.bpf.c
|
|
@@ -5,7 +5,9 @@
|
|
#include <bpf/bpf_core_read.h>
|
|
#include <bpf/bpf_tracing.h>
|
|
#include <bpf/bpf_endian.h>
|
|
+
|
|
#include "bindsnoop.h"
|
|
+#include "core_fixes.bpf.h"
|
|
|
|
#define MAX_ENTRIES 10240
|
|
#define MAX_PORTS 1024
|
|
@@ -85,9 +87,9 @@ static int probe_exit(struct pt_regs *ctx, short ver)
|
|
if (filter_by_port && !port)
|
|
goto cleanup;
|
|
|
|
- opts.fields.freebind = BPF_CORE_READ_BITFIELD_PROBED(inet_sock, freebind);
|
|
- opts.fields.transparent = BPF_CORE_READ_BITFIELD_PROBED(inet_sock, transparent);
|
|
- opts.fields.bind_address_no_port = BPF_CORE_READ_BITFIELD_PROBED(inet_sock, bind_address_no_port);
|
|
+ opts.fields.freebind = get_inet_sock_freebind(inet_sock);
|
|
+ opts.fields.transparent = get_inet_sock_transparent(inet_sock);
|
|
+ opts.fields.bind_address_no_port = get_inet_sock_bind_address_no_port(inet_sock);
|
|
opts.fields.reuseaddress = BPF_CORE_READ_BITFIELD_PROBED(sock, __sk_common.skc_reuse);
|
|
opts.fields.reuseport = BPF_CORE_READ_BITFIELD_PROBED(sock, __sk_common.skc_reuseport);
|
|
event.opts = opts.data;
|
|
diff --git a/libbpf-tools/core_fixes.bpf.h b/libbpf-tools/core_fixes.bpf.h
|
|
index 84cb7f18..a4c84c02 100644
|
|
--- a/libbpf-tools/core_fixes.bpf.h
|
|
+++ b/libbpf-tools/core_fixes.bpf.h
|
|
@@ -249,4 +249,60 @@ static __always_inline __u64 get_sock_ident(struct sock *sk)
|
|
return (__u64)sk;
|
|
}
|
|
|
|
+/**
|
|
+ * During kernel 6.6 development cycle, several bitfields in struct inet_sock gone,
|
|
+ * they are placed in inet_sock::inet_flags instead ([0]).
|
|
+ *
|
|
+ * References:
|
|
+ * [0]: https://lore.kernel.org/all/20230816081547.1272409-1-edumazet@google.com/
|
|
+ */
|
|
+struct inet_sock___o {
|
|
+ __u8 freebind: 1;
|
|
+ __u8 transparent: 1;
|
|
+ __u8 bind_address_no_port: 1;
|
|
+};
|
|
+
|
|
+enum {
|
|
+ INET_FLAGS_FREEBIND___x = 11,
|
|
+ INET_FLAGS_TRANSPARENT___x = 15,
|
|
+ INET_FLAGS_BIND_ADDRESS_NO_PORT___x = 18,
|
|
+};
|
|
+
|
|
+struct inet_sock___x {
|
|
+ unsigned long inet_flags;
|
|
+};
|
|
+
|
|
+static __always_inline __u8 get_inet_sock_freebind(void *inet_sock)
|
|
+{
|
|
+ unsigned long inet_flags;
|
|
+
|
|
+ if (bpf_core_field_exists(struct inet_sock___o, freebind))
|
|
+ return BPF_CORE_READ_BITFIELD_PROBED((struct inet_sock___o *)inet_sock, freebind);
|
|
+
|
|
+ inet_flags = BPF_CORE_READ((struct inet_sock___x *)inet_sock, inet_flags);
|
|
+ return (1 << INET_FLAGS_FREEBIND___x) & inet_flags ? 1 : 0;
|
|
+}
|
|
+
|
|
+static __always_inline __u8 get_inet_sock_transparent(void *inet_sock)
|
|
+{
|
|
+ unsigned long inet_flags;
|
|
+
|
|
+ if (bpf_core_field_exists(struct inet_sock___o, transparent))
|
|
+ return BPF_CORE_READ_BITFIELD_PROBED((struct inet_sock___o *)inet_sock, transparent);
|
|
+
|
|
+ inet_flags = BPF_CORE_READ((struct inet_sock___x *)inet_sock, inet_flags);
|
|
+ return (1 << INET_FLAGS_TRANSPARENT___x) & inet_flags ? 1 : 0;
|
|
+}
|
|
+
|
|
+static __always_inline __u8 get_inet_sock_bind_address_no_port(void *inet_sock)
|
|
+{
|
|
+ unsigned long inet_flags;
|
|
+
|
|
+ if (bpf_core_field_exists(struct inet_sock___o, bind_address_no_port))
|
|
+ return BPF_CORE_READ_BITFIELD_PROBED((struct inet_sock___o *)inet_sock, bind_address_no_port);
|
|
+
|
|
+ inet_flags = BPF_CORE_READ((struct inet_sock___x *)inet_sock, inet_flags);
|
|
+ return (1 << INET_FLAGS_BIND_ADDRESS_NO_PORT___x) & inet_flags ? 1 : 0;
|
|
+}
|
|
+
|
|
#endif /* __CORE_FIXES_BPF_H */
|
|
--
|
|
2.43.0
|
|
|