bpf: merge block.c into netd.c

Since this is just a special case of a bpf cgroup hook,
it really should be in netd.o with all other such hooks.

Besides moving/renaming the map & programs this should be a no-op.

Test: TreeHugger, atest bpf_existence_test
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I4a2aedaf77f89a9c0a96fa1c369d80659535eabe
diff --git a/bpf/progs/netd.c b/bpf/progs/netd.c
index 4248a46..8804ad5 100644
--- a/bpf/progs/netd.c
+++ b/bpf/progs/netd.c
@@ -69,6 +69,8 @@
 // TODO: consider whether we can merge some of these maps
 // for example it might be possible to merge 2 or 3 of:
 //   uid_counterset_map + uid_owner_map + uid_permission_map
+DEFINE_BPF_MAP_NO_NETD(blocked_ports_map, ARRAY, int, uint64_t,
+                       1024 /* 64K ports -> 1024 u64s */)
 DEFINE_BPF_MAP_RW_NETD(cookie_tag_map, HASH, uint64_t, UidTagValue, COOKIE_UID_MAP_SIZE)
 DEFINE_BPF_MAP_NO_NETD(uid_counterset_map, HASH, uint32_t, uint8_t, UID_COUNTERSET_MAP_SIZE)
 DEFINE_BPF_MAP_NO_NETD(app_uid_stats_map, HASH, uint32_t, StatsValue, APP_STATS_MAP_SIZE)
@@ -670,6 +672,43 @@
     return BPF_ALLOW;
 }
 
+static inline __always_inline int block_port(struct bpf_sock_addr *ctx) {
+    if (!ctx->user_port) return BPF_ALLOW;
+
+    switch (ctx->protocol) {
+        case IPPROTO_TCP:
+        case IPPROTO_MPTCP:
+        case IPPROTO_UDP:
+        case IPPROTO_UDPLITE:
+        case IPPROTO_DCCP:
+        case IPPROTO_SCTP:
+            break;
+        default:
+            return BPF_ALLOW; // unknown protocols are allowed
+    }
+
+    int key = ctx->user_port >> 6;
+    int shift = ctx->user_port & 63;
+
+    uint64_t *val = bpf_blocked_ports_map_lookup_elem(&key);
+    // Lookup should never fail in reality, but if it does return here to keep the
+    // BPF verifier happy.
+    if (!val) return BPF_ALLOW;
+
+    if ((*val >> shift) & 1) return BPF_DISALLOW;
+    return BPF_ALLOW;
+}
+
+DEFINE_NETD_BPF_PROG_KVER("bind4/inet4_bind", AID_ROOT, AID_ROOT, inet4_bind, KVER_4_19)
+(struct bpf_sock_addr *ctx) {
+    return block_port(ctx);
+}
+
+DEFINE_NETD_BPF_PROG_KVER("bind6/inet6_bind", AID_ROOT, AID_ROOT, inet6_bind, KVER_4_19)
+(struct bpf_sock_addr *ctx) {
+    return block_port(ctx);
+}
+
 DEFINE_NETD_V_BPF_PROG_KVER("connect4/inet4_connect", AID_ROOT, AID_ROOT, inet4_connect, KVER_4_14)
 (struct bpf_sock_addr *ctx) {
     return check_localhost(ctx);