netd ebpf: always match and thus allow incoming udp to unconnected sockets
This also allows other edge case packets where we cannot figure out the
socket which will receive the packet.
This may be because:
- the target socket is an unconnected udp socket not found by early demux
- such a socket doesn't exist: we'll likely send an icmp error or tcp reset,
this should be rare and thus shouldn't affect bandwidth nor power
(and since we just received the packet the relevant radio should already
be awake anyway)
- the socket is in some other weird partial state, ie. possibly
tcp syncookies, or tcp reqsk, or tcp timewait sockets... etc...
While we're at it also change:
return masked_value;
to
return masked_value ? BPF_MATCH : BPF_NOMATCH;
in two spots.
Test: build + cuttlefish atests,
manual testing with previously problematic game
Bug: 140972725
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I17c02d5bf06189e226db9c0edc8da0e013d1eb05
Merged-In: I17c02d5bf06189e226db9c0edc8da0e013d1eb05
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index 8f2863e..1362be2 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -16,6 +16,7 @@
#include "netd.h"
#include <linux/bpf.h>
+#include <linux/if_packet.h>
SEC("cgroupskb/ingress/stats")
int bpf_cgroup_ingress(struct __sk_buff* skb) {
@@ -45,8 +46,18 @@
int xt_bpf_whitelist_prog(struct __sk_buff* skb) {
uint32_t sock_uid = bpf_get_socket_uid(skb);
if (is_system_uid(sock_uid)) return BPF_MATCH;
+
+ // 65534 is the overflow 'nobody' uid, usually this being returned means
+ // that skb->sk is NULL during RX (early decap socket lookup failure),
+ // which commonly happens for incoming packets to an unconnected udp socket.
+ // Additionally bpf_get_socket_cookie() returns 0 if skb->sk is NULL
+ if ((sock_uid == 65534) && !bpf_get_socket_cookie(skb) &&
+ (skb->pkt_type == PACKET_HOST || skb->pkt_type == PACKET_BROADCAST ||
+ skb->pkt_type == PACKET_MULTICAST))
+ return BPF_MATCH;
+
UidOwnerValue* whitelistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
- if (whitelistMatch) return whitelistMatch->rule & HAPPY_BOX_MATCH;
+ if (whitelistMatch) return whitelistMatch->rule & HAPPY_BOX_MATCH ? BPF_MATCH : BPF_NOMATCH;
return BPF_NOMATCH;
}
@@ -54,7 +65,7 @@
int xt_bpf_blacklist_prog(struct __sk_buff* skb) {
uint32_t sock_uid = bpf_get_socket_uid(skb);
UidOwnerValue* blacklistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
- if (blacklistMatch) return blacklistMatch->rule & PENALTY_BOX_MATCH;
+ if (blacklistMatch) return blacklistMatch->rule & PENALTY_BOX_MATCH ? BPF_MATCH : BPF_NOMATCH;
return BPF_NOMATCH;
}