Skip to content

Commit 7f0ffcf

Browse files
authored
Joshd/sc 127330/network reporting still returns data for (#7)
* Validate socket in process_tcp
1 parent 8ca2ce5 commit 7f0ffcf

File tree

2 files changed

+84
-10
lines changed

2 files changed

+84
-10
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ sudo apt install linux-headers-$(uname -r) \
8686
Build the test release of `pktstat-bpf`:
8787
8888
```shell
89-
make build
89+
make generate build
9090
```
9191
9292
Move the release into the `network-report-collector-path` set in

bpf/counter.c

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ static inline int process_ip4(struct iphdr *ip4, void *data_end, statkey *key) {
167167
return NOK;
168168
}
169169

170+
// Skip packets with both source and destination addresses zero
171+
if (ip4->saddr == 0 && ip4->daddr == 0) {
172+
return NOK;
173+
}
174+
170175
// convert to V4MAPPED address
171176
__builtin_memcpy(key->srcip.s6_addr, ip4in6, sizeof(ip4in6));
172177
__builtin_memcpy(key->srcip.s6_addr + sizeof(ip4in6), &ip4->saddr,
@@ -223,6 +228,12 @@ static inline int process_ip4(struct iphdr *ip4, void *data_end, statkey *key) {
223228
}
224229
}
225230

231+
// Skip packets with destination IP 0.0.0.0 and destination port 0
232+
// This catches unconnected/invalid socket states
233+
if (ip4->daddr == 0 && key->dst_port == 0) {
234+
return NOK;
235+
}
236+
226237
return OK;
227238
}
228239

@@ -249,6 +260,16 @@ static inline int process_ip6(struct ipv6hdr *ip6, void *data_end,
249260
key->dstip = ip6->daddr;
250261
key->proto = ip6->nexthdr;
251262

263+
// Check if both IPv6 addresses are unspecified (all zeros)
264+
int src_empty = 1, dst_empty = 1;
265+
for (int i = 0; i < 4; i++) {
266+
if (key->srcip.s6_addr32[i] != 0) src_empty = 0;
267+
if (key->dstip.s6_addr32[i] != 0) dst_empty = 0;
268+
}
269+
if (src_empty && dst_empty) {
270+
return NOK;
271+
}
272+
252273
switch (ip6->nexthdr) {
253274
case IPPROTO_TCP: {
254275
struct tcphdr *tcp = (void *)ip6 + sizeof(*ip6);
@@ -293,6 +314,11 @@ static inline int process_ip6(struct ipv6hdr *ip6, void *data_end,
293314
}
294315
}
295316

317+
// Skip packets with destination IPv6 unspecified and destination port 0
318+
if (dst_empty && key->dst_port == 0) {
319+
return NOK;
320+
}
321+
296322
return OK;
297323
}
298324

@@ -584,18 +610,43 @@ int cgroup_skb_egress(struct __sk_buff *skb) {
584610
*
585611
* @throws none
586612
*/
587-
static inline void process_tcp(struct sock *sk, statkey *key, pid_t pid) {
613+
static inline int process_tcp(struct sock *sk, statkey *key, pid_t pid) {
614+
// Validate socket pointer
615+
if (!sk) {
616+
return -1;
617+
}
618+
588619
__u16 family = BPF_CORE_READ(sk, __sk_common.skc_family);
620+
621+
// Only process supported address families
622+
if (family != AF_INET && family != AF_INET6) {
623+
return -1;
624+
}
589625

590626
switch (family) {
591627
case AF_INET: {
592628
// convert to V4MAPPED address
593629
__be32 ip4_src = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr);
630+
__be32 ip4_dst = BPF_CORE_READ(sk, __sk_common.skc_daddr);
631+
632+
// Skip sockets with both addresses zero (unconnected/invalid state)
633+
if (ip4_src == 0 && ip4_dst == 0) {
634+
return -1;
635+
}
636+
637+
// Also skip sockets with destination IP 0.0.0.0 and port 0 (unconnected state)
638+
if (ip4_dst == 0) {
639+
// Need to read ports first to check dst_port
640+
__u16 sport = BPF_CORE_READ(sk, __sk_common.skc_num);
641+
__u16 dport = BPF_CORE_READ(sk, __sk_common.skc_dport);
642+
if (bpf_ntohs(dport) == 0) {
643+
return -1;
644+
}
645+
}
646+
594647
key->srcip.s6_addr16[5] = bpf_htons(0xffff);
595648
__builtin_memcpy(&key->srcip.s6_addr32[3], &ip4_src, sizeof(ip4_src));
596649

597-
// convert to V4MAPPED address
598-
__be32 ip4_dst = BPF_CORE_READ(sk, __sk_common.skc_daddr);
599650
key->dstip.s6_addr16[5] = bpf_htons(0xffff);
600651
__builtin_memcpy(&key->dstip.s6_addr32[3], &ip4_dst, sizeof(ip4_dst));
601652

@@ -605,23 +656,38 @@ static inline void process_tcp(struct sock *sk, statkey *key, pid_t pid) {
605656
BPF_CORE_READ_INTO(&key->srcip, sk, __sk_common.skc_v6_rcv_saddr);
606657
BPF_CORE_READ_INTO(&key->dstip, sk, __sk_common.skc_v6_daddr);
607658

659+
// Check if both IPv6 addresses are unspecified (all zeros)
660+
int src_empty = 1, dst_empty = 1;
661+
for (int i = 0; i < 4; i++) {
662+
if (key->srcip.s6_addr32[i] != 0) src_empty = 0;
663+
if (key->dstip.s6_addr32[i] != 0) dst_empty = 0;
664+
}
665+
if (src_empty && dst_empty) {
666+
return -1;
667+
}
668+
608669
break;
609670
}
610671
default: {
611-
return;
672+
return -1;
612673
}
613674
}
614675

615676
__u16 sport = BPF_CORE_READ(sk, __sk_common.skc_num);
677+
__u16 dport = BPF_CORE_READ(sk, __sk_common.skc_dport);
678+
616679
if (sport == 0) {
617680
struct inet_sock *isk = (struct inet_sock *)sk;
618681
BPF_CORE_READ_INTO(&sport, isk, inet_sport);
619682
}
683+
620684
key->src_port = bpf_ntohs(sport);
621-
key->dst_port = bpf_ntohs(BPF_CORE_READ(sk, __sk_common.skc_dport));
685+
key->dst_port = bpf_ntohs(dport);
622686

623687
key->proto = IPPROTO_TCP;
624688
key->pid = pid;
689+
690+
return 0;
625691
}
626692

627693
/**
@@ -948,7 +1014,9 @@ int BPF_KPROBE(tcp_sendmsg, struct sock *sk, struct msghdr *msg, size_t size) {
9481014
bpf_get_current_comm(&key.comm, sizeof(key.comm));
9491015
}
9501016

951-
process_tcp(sk, &key, pid);
1017+
if (process_tcp(sk, &key, pid) != 0) {
1018+
return 0; // Skip invalid socket
1019+
}
9521020
update_val(&key, size);
9531021

9541022
return 0;
@@ -982,7 +1050,9 @@ int BPF_KPROBE(tcp_cleanup_rbuf, struct sock *sk, int copied) {
9821050
bpf_get_current_comm(&key.comm, sizeof(key.comm));
9831051
}
9841052

985-
process_tcp(sk, &key, pid);
1053+
if (process_tcp(sk, &key, pid) != 0) {
1054+
return 0; // Skip invalid socket
1055+
}
9861056
update_val(&key, copied);
9871057

9881058
return 0;
@@ -1281,7 +1351,9 @@ int BPF_KPROBE(ip_local_out_fn, struct sk_buff *skb, struct net *net) {
12811351
if (sk) {
12821352
// Let's use the safer process_tcp function which already works in existing
12831353
// kprobes
1284-
process_tcp(sk, &key, pid);
1354+
if (process_tcp(sk, &key, pid) != 0) {
1355+
return 0; // Skip invalid socket
1356+
}
12851357
update_val(&key, len);
12861358
return 0;
12871359
}
@@ -1328,7 +1400,9 @@ int BPF_KPROBE(ip_output_fn, struct net *net, struct sock *sk,
13281400
if (sk) {
13291401
// Use the existing process_tcp function which already works in other
13301402
// kprobes
1331-
process_tcp(sk, &key, pid);
1403+
if (process_tcp(sk, &key, pid) != 0) {
1404+
return 0; // Skip invalid socket
1405+
}
13321406
update_val(&key, len);
13331407
return 0;
13341408
}

0 commit comments

Comments
 (0)