diff --git a/GPL/Events/EbpfEventProto.h b/GPL/Events/EbpfEventProto.h index 1f3dadb7..0bcb70e7 100644 --- a/GPL/Events/EbpfEventProto.h +++ b/GPL/Events/EbpfEventProto.h @@ -11,10 +11,6 @@ #define EBPF_EVENTPROBE_EBPFEVENTPROTO_H #define TASK_COMM_LEN 16 -// The theoretical max size of DNS packets over UDP is 512. -// Like so many things in DNS this number probaby isn't 100% accurate. -// DNS extensions in RFC2671 and RFC6891 mean the actual size can be larger. -#define MAX_DNS_PACKET 4096 #ifndef __KERNEL__ #include @@ -44,7 +40,6 @@ enum ebpf_event_type { EBPF_EVENT_PROCESS_SHMGET = (1 << 17), EBPF_EVENT_PROCESS_PTRACE = (1 << 18), EBPF_EVENT_PROCESS_LOAD_MODULE = (1 << 19), - EBPF_EVENT_NETWORK_DNS_PKT = (1 << 20), }; struct ebpf_event_header { @@ -72,7 +67,6 @@ enum ebpf_varlen_field_type { EBPF_VL_FIELD_SYMLINK_TARGET_PATH, EBPF_VL_FIELD_MOD_VERSION, EBPF_VL_FIELD_MOD_SRCVERSION, - EBPF_VL_FIELD_DNS_BODY, }; // Convenience macro to iterate all the variable length fields in an event @@ -374,11 +368,6 @@ enum ebpf_net_udp_info { EBPF_NETWORK_EVENT_IP_SEND_UDP = 2, }; -enum ebpf_net_packet_direction { - EBPF_NETWORK_DIR_EGRESS = 1, - EBPF_NETWORK_DIR_INGRESS = 2, -}; - struct ebpf_net_info_tcp_close { uint64_t bytes_sent; uint64_t bytes_received; @@ -410,20 +399,10 @@ struct ebpf_net_event { char comm[TASK_COMM_LEN]; } __attribute__((packed)); -struct ebpf_dns_event { - struct ebpf_event_header hdr; - uint32_t tgid; - uint32_t cap_len; - uint32_t orig_len; - enum ebpf_net_packet_direction direction; - struct ebpf_varlen_fields_start vl_fields; -} __attribute__((packed)); - // Basic event statistics struct ebpf_event_stats { - uint64_t lost; // lost events due to a full ringbuffer - uint64_t sent; // events sent through the ringbuffer - uint64_t dns_zero_body; // indicates that the dns body of a sk_buff was unavailable + uint64_t lost; // lost events due to a full ringbuffer + uint64_t sent; // events sent through the ringbuffer }; #endif // EBPF_EVENTPROBE_EBPFEVENTPROTO_H diff --git a/GPL/Events/Network/Probe.bpf.c b/GPL/Events/Network/Probe.bpf.c index ee08a349..4ddf18da 100644 --- a/GPL/Events/Network/Probe.bpf.c +++ b/GPL/Events/Network/Probe.bpf.c @@ -197,229 +197,3 @@ int BPF_KPROBE(kprobe__tcp_close, struct sock *sk, long timeout) { return tcp_close__enter(sk); } - -#ifdef notyet -/* - * XXX naive, only handles ROUTING and DEST, untested, ipv6 needs more work to - * be enabled. - */ -int skb_peel_nexthdr(struct __sk_buff *skb, u8 wanted) -{ - struct ipv6hdr ip6; - int off; - u16 next; - - off = 0; - if (bpf_skb_load_bytes(skb, off, &ip6, sizeof(ip6))) - return (-1); - off += sizeof(ip6); - next = ip6.nexthdr; - - for (;;) { - if (next == wanted) - return (off); - switch (next) { - case NEXTHDR_ROUTING: /* FALLTHROUGH */ - case NEXTHDR_DEST: - if (bpf_skb_load_bytes(skb, off, &next, sizeof(next))) - return (-1); - off += ((next >> 8) + 1) * 8; - next = next & 0xff; - continue; - default: - return (-1); - } - } - - return (-1); /* NOTREACHED */ -} -#endif - -int skb_in_or_egress(struct __sk_buff *skb, int ingress) -{ - struct udphdr udp; - struct bpf_sock *sk; - u32 *tgid, cap_len, zero = 0; - u64 *sk_addr; - struct ebpf_dns_event *event; - struct ebpf_varlen_field *field; - - if (skb->family != AF_INET && skb->family != AF_INET6) - goto ignore; - if ((sk = skb->sk) == NULL) - goto ignore; - if ((sk = bpf_sk_fullsock(sk)) == NULL) - goto ignore; - if (sk->protocol != IPPROTO_UDP) - goto ignore; - - if (sk->family == AF_INET) { - struct iphdr ip; - - if (bpf_skb_load_bytes(skb, 0, &ip, sizeof(ip))) - goto ignore; - if (ip.protocol != IPPROTO_UDP) - goto ignore; - if (bpf_skb_load_bytes(skb, ip.ihl << 2, &udp, sizeof(udp))) - goto ignore; - } else { - goto ignore; - } -#ifdef notyet /* ipv6 needs further work */ - else if (sk->family == AF_INET6) - { - int t_off; - - t_off = skb_peel_nexthdr(skb, NEXTHDR_UDP); - if (t_off == -1) - goto ignore; - - if (bpf_skb_load_bytes(skb, t_off, &udp, sizeof(udp))) - goto ignore; - } -#endif - - if (bpf_ntohs(udp.dest) != 53 && bpf_ntohs(udp.source) != 53) - goto ignore; - - /* - * Needed for kernels prior to f79efcb0075a20633cbf9b47759f2c0d538f78d8 - * bpf: Permits pointers on stack for helper calls - */ - sk_addr = bpf_map_lookup_elem(&scratch64, &zero); - if (sk_addr == NULL) - goto ignore; - *sk_addr = (u64)sk; - tgid = bpf_map_lookup_elem(&sk_to_tgid, sk_addr); - if (tgid == NULL) - goto ignore; - - cap_len = skb->len; - /* - * verifier will complain, even with a skb->len - * check at the beginning. - */ - if (cap_len > MAX_DNS_PACKET) - cap_len = MAX_DNS_PACKET; - - /* - * Yes this code is weird, but it convinces old verifiers (5.10), don't - * blame me, be sure to test 5.10 if you change it. The minimal packet - * should be iphlen + udphlen + 12(dns header size). Old verifiers - * (5.10) are very sensitive here and a non constant right expression - * (since iphlen is not constant due to options) fails. Do what we can - * and filter the remaining bad packets in userland, same applies to - * ipv6. Also be careful with `if cap_len > 0`, as clang will compile it - * to a JNZ, which doesn't adjust umin, causing the - * bpf_skb_load_bytes() down below to think cap_len can be zero. - */ - if (cap_len >= (sizeof(struct iphdr) + sizeof(udp) + 12)) { - event = get_event_buffer(); - if (event == NULL) - goto ignore; - - event->hdr.type = EBPF_EVENT_NETWORK_DNS_PKT; - event->hdr.ts = bpf_ktime_get_ns(); - event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); - event->tgid = *tgid; - event->cap_len = cap_len; - event->orig_len = skb->len; - event->direction = ingress ? EBPF_NETWORK_DIR_INGRESS : EBPF_NETWORK_DIR_EGRESS; - - ebpf_vl_fields__init(&event->vl_fields); - field = ebpf_vl_field__add(&event->vl_fields, EBPF_VL_FIELD_DNS_BODY); - if (bpf_skb_load_bytes(skb, 0, field->data, cap_len)) - goto ignore; - ebpf_vl_field__set_size(&event->vl_fields, field, cap_len); - - ebpf_ringbuf_write(&ringbuf, event, EVENT_SIZE(event), 0); - } - -ignore: - return (1); -} - -SEC("cgroup_skb/egress") -int skb_egress(struct __sk_buff *skb) -{ - return skb_in_or_egress(skb, 0); -} - -SEC("cgroup_skb/ingress") -int skb_ingress(struct __sk_buff *skb) -{ - return skb_in_or_egress(skb, 1); -} - -int sk_maybe_save_tgid(struct bpf_sock *sk) -{ - u32 tgid, zero = 0; - u64 *sk_addr; - - if (sk->protocol != IPPROTO_UDP) - return (1); - - tgid = bpf_get_current_pid_tgid() >> 32; - - /* - * Needed for kernels prior to f79efcb0075a20633cbf9b47759f2c0d538f78d8 - * bpf: Permits pointers on stack for helper calls - */ - sk_addr = bpf_map_lookup_elem(&scratch64, &zero); - if (sk_addr == NULL) - return (1); - *sk_addr = (u64)sk; - bpf_map_update_elem(&sk_to_tgid, sk_addr, &tgid, BPF_ANY); - - return (1); -} - -/* - * We save tgid again in send/recv/connect as the file descriptor might have - * been passed to another process. - */ -SEC("cgroup/sendmsg4") -int sendmsg4(struct bpf_sock_addr *sa) -{ - return sk_maybe_save_tgid(sa->sk); -} - -SEC("cgroup/recvmsg4") -int recvmsg4(struct bpf_sock_addr *sa) -{ - return sk_maybe_save_tgid(sa->sk); -} - -SEC("cgroup/connect4") -int connect4(struct bpf_sock_addr *sa) -{ - return sk_maybe_save_tgid(sa->sk); -} - -SEC("cgroup/sock_create") -int sock_create(struct bpf_sock *sk) -{ - return sk_maybe_save_tgid(sk); -} - -SEC("cgroup/sock_release") -int sock_release(struct bpf_sock *sk) -{ - u32 zero = 0; - u64 *sk_addr; - - if (sk->protocol != IPPROTO_UDP) - return (1); - - /* - * Needed for kernels prior to f79efcb0075a20633cbf9b47759f2c0d538f78d8 - * bpf: Permits pointers on stack for helper calls - */ - sk_addr = bpf_map_lookup_elem(&scratch64, &zero); - if (sk_addr == NULL) - return (1); - *sk_addr = (u64)sk; - bpf_map_delete_elem(&sk_to_tgid, sk_addr); - - return (1); -} diff --git a/GPL/Events/State.h b/GPL/Events/State.h index 45e6c505..cf23e58e 100644 --- a/GPL/Events/State.h +++ b/GPL/Events/State.h @@ -174,14 +174,6 @@ static long ebpf_events_scratch_space__set(enum ebpf_events_state_op op, return bpf_map_update_elem(&elastic_ebpf_events_scratch_space, &key, ss, BPF_ANY); } -/* Scratch 64bits as an array, as bpf_get_current_pid_tgid is not always available */ -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, u64); - __uint(max_entries, 1); -} scratch64 SEC(".maps"); - /* Trusted Apps - list of trusted pids */ struct { __uint(type, BPF_MAP_TYPE_HASH); diff --git a/non-GPL/Events/EventsTrace/EventsTrace.c b/non-GPL/Events/EventsTrace/EventsTrace.c index 14942c61..59a2b594 100644 --- a/non-GPL/Events/EventsTrace/EventsTrace.c +++ b/non-GPL/Events/EventsTrace/EventsTrace.c @@ -63,7 +63,6 @@ enum cmdline_opts { NETWORK_CONNECTION_ATTEMPTED, NETWORK_CONNECTION_ACCEPTED, NETWORK_CONNECTION_CLOSED, - NETWORK_DNS_PKT, CMDLINE_MAX }; @@ -90,7 +89,6 @@ static uint64_t cmdline_to_lib[CMDLINE_MAX] = { x(NETWORK_CONNECTION_ATTEMPTED) x(NETWORK_CONNECTION_ACCEPTED) x(NETWORK_CONNECTION_CLOSED) - x(NETWORK_DNS_PKT) #undef x // clang-format on }; @@ -116,7 +114,6 @@ static const struct argp_option opts[] = { {"process-load-module", PROCESS_LOAD_MODULE, NULL, false, "Print kernel module load events", 0}, {"net-conn-accept", NETWORK_CONNECTION_ACCEPTED, NULL, false, "Print network connection accepted events", 0}, - {"net-conn-dns-pkt", NETWORK_DNS_PKT, NULL, false, "Print DNS events", 0}, {"net-conn-attempt", NETWORK_CONNECTION_ATTEMPTED, NULL, false, "Print network connection attempted events", 0}, {"net-conn-closed", NETWORK_CONNECTION_CLOSED, NULL, false, @@ -176,7 +173,6 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) case NETWORK_CONNECTION_ACCEPTED: case NETWORK_CONNECTION_ATTEMPTED: case NETWORK_CONNECTION_CLOSED: - case NETWORK_DNS_PKT: g_events_env |= cmdline_to_lib[key]; break; case ARGP_KEY_ARG: @@ -1084,43 +1080,6 @@ static void out_network_connection_accepted_event(struct ebpf_net_event *evt) out_network_event("NETWORK_CONNECTION_ACCEPTED", evt); } -static void out_network_dns_event(struct ebpf_dns_event *event) -{ - out_object_start(); - out_event_type("DNS_PKT"); - out_comma(); - - out_int("tgid", event->tgid); - out_comma(); - - out_int("cap_len", event->cap_len); - out_comma(); - - out_int("orig_len", event->orig_len); - out_comma(); - - out_string("direction", event->direction == EBPF_NETWORK_DIR_INGRESS ? "in" : "out"); - out_comma(); - - printf("\"data\":"); - out_array_start(); - struct ebpf_varlen_field *field; - FOR_EACH_VARLEN_FIELD(event->vl_fields, field) - { - for (size_t i = 0; i < field->size; i++) { - uint8_t part = field->data[i]; - printf("%d", part); - if (i < field->size - 1) { - printf(", "); - } - } - } - out_array_end(); - - out_object_end(); - out_newline(); -} - static void out_network_connection_attempted_event(struct ebpf_net_event *evt) { out_network_event("NETWORK_CONNECTION_ATTEMPTED", evt); @@ -1200,9 +1159,6 @@ static int event_ctx_callback(struct ebpf_event_header *evt_hdr) case EBPF_EVENT_NETWORK_CONNECTION_CLOSED: out_network_connection_closed_event((struct ebpf_net_event *)evt_hdr); break; - case EBPF_EVENT_NETWORK_DNS_PKT: - out_network_dns_event((struct ebpf_dns_event *)evt_hdr); - break; } return 0; diff --git a/non-GPL/Events/Lib/EbpfEvents.c b/non-GPL/Events/Lib/EbpfEvents.c index 2b6a79b4..90062a79 100644 --- a/non-GPL/Events/Lib/EbpfEvents.c +++ b/non-GPL/Events/Lib/EbpfEvents.c @@ -417,38 +417,6 @@ static int probe_set_autoload(struct btf *btf, struct EventProbe_bpf *obj, uint6 return err; } -#if 0 // Do not load DNS probes -static int probe_attach_cgroup(struct EventProbe_bpf *obj) -{ - int cgroup_fd; - - /* - * Hardcoded for now, consider making the path an argument. - */ - cgroup_fd = open("/sys/fs/cgroup", O_RDONLY); - if (cgroup_fd == -1) - return -1; - -#define ATTACH_OR_FAIL(_program) \ - if (bpf_program__attach_cgroup(obj->progs._program, cgroup_fd) == NULL) { \ - close(cgroup_fd); \ - return -1; \ - } - ATTACH_OR_FAIL(skb_egress); - ATTACH_OR_FAIL(skb_ingress); - ATTACH_OR_FAIL(sock_create); - ATTACH_OR_FAIL(sock_release); - ATTACH_OR_FAIL(sendmsg4); - ATTACH_OR_FAIL(connect4); - ATTACH_OR_FAIL(recvmsg4); -#undef ATTACH_OR_FAIL - - close(cgroup_fd); - - return 0; -} -#endif - static bool system_has_bpf_tramp(void) { /* @@ -792,14 +760,6 @@ int ebpf_event_ctx__new(struct ebpf_event_ctx **ctx, ebpf_event_handler_fn cb, u goto out_destroy_probe; } -#if 0 // Do not load DNS probes - err = probe_attach_cgroup(probe); - if (err != 0) { - verbose("probe_attach_cgroup: %d\n", err); - goto out_destroy_probe; - } -#endif - if (!ctx) goto out_destroy_probe; @@ -879,7 +839,6 @@ int ebpf_event_ctx__read_stats(struct ebpf_event_ctx *ctx, struct ebpf_event_sta for (i = 0; i < libbpf_num_possible_cpus(); i++) { ees->lost += pcpu_ees[i].lost; ees->sent += pcpu_ees[i].sent; - ees->dns_zero_body += pcpu_ees[i].dns_zero_body; } return 0; diff --git a/testing/testrunner/ebpf_test.go b/testing/testrunner/ebpf_test.go index 8bb16f24..ddd5fcaa 100644 --- a/testing/testrunner/ebpf_test.go +++ b/testing/testrunner/ebpf_test.go @@ -13,7 +13,6 @@ import ( "context" "encoding/json" "fmt" - "net" "os" "os/exec" "strings" @@ -689,55 +688,6 @@ func Tcpv6ConnectionClose(t *testing.T, et *Runner) { require.Equal(t, evs[1].Comm, "tcpv6_connect") } -func DNSMonitor(t *testing.T, et *Runner) { - addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:53") - require.NoError(t, err) - - listen, err := net.ListenUDP("udp", addr) - require.NoError(t, err) - defer listen.Close() - - conn, err := net.DialUDP("udp", nil, addr) - require.NoError(t, err) - defer conn.Close() - - pattern := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") - n, err := conn.Write(pattern) - require.NoError(t, err) - require.Equal(t, n, len(pattern)) - - var buf [256]byte - n, _, err = listen.ReadFromUDP(buf[:]) - require.NoError(t, err) - require.Equal(t, n, len(pattern)) - - type dnsOutput struct { - Tgid int64 `json:"tgid"` - CapLen int `json:"cap_len"` - OrigLen int `json:"orig_len"` - Dir string `json:"direction"` - Data []uint8 `json:"data"` - } - // out - lineData := dnsOutput{} - et.UnmarshalNextEvent(&lineData, "DNS_PKT") - require.Equal(t, int64(os.Getpid()), lineData.Tgid) - require.Equal(t, 90, lineData.CapLen) - require.Equal(t, 90, lineData.OrigLen) - require.Equal(t, "out", lineData.Dir) - require.Equal(t, pattern, lineData.Data[28:]) - - // in - lineData = dnsOutput{} - et.UnmarshalNextEvent(&lineData, "DNS_PKT") - require.Equal(t, int64(os.Getpid()), lineData.Tgid) - require.Equal(t, 90, lineData.CapLen) - require.Equal(t, 90, lineData.OrigLen) - require.Equal(t, "in", lineData.Dir) - require.Equal(t, pattern, lineData.Data[28:]) - -} - func TcFilter(t *testing.T, et *Runner) { // TC test is weird, and doesn't actually use the // return-json-and-check-eventsTrace-output the other tests use @@ -773,7 +723,6 @@ func TestEbpf(t *testing.T) { {"Tcpv4ConnectionAttempt", Tcpv4ConnectionAttempt, []string{"--net-conn-attempt"}, false}, {"Tcpv4ConnectionAccept", Tcpv4ConnectionAccept, []string{"--net-conn-accept"}, false}, {"Tcpv4ConnectionClose", Tcpv4ConnectionClose, []string{"--net-conn-close"}, false}, - //{"DNSMonitor", DNSMonitor, []string{"--net-conn-dns-pkt"}, false}, {"Ptrace", Ptrace, []string{"--process-ptrace"}, false}, {"Shmget", Shmget, []string{"--process-shmget"}, false}, {"MemfdCreate", MemfdCreate, []string{"--process-memfd-create", "--process-exec"}, false},