bpf netd: block local network calls if permission is not allowed.
Adding map local_net_blocked_uid_map, which will store uid for
the applications that have opted in but do not have the required
permission. The entry would be absent or the value would be false if the
application is allowed to access local network.
Test: Manually populating the values and checking EPERM error.
Bug: 390168818
Change-Id: Idf6caff204295a3f0aa7f552ea4af50bfd2df78c
diff --git a/bpf/progs/netd.c b/bpf/progs/netd.c
index 4ff68da..aab9c26 100644
--- a/bpf/progs/netd.c
+++ b/bpf/progs/netd.c
@@ -104,6 +104,12 @@
BPFLOADER_MAINLINE_25Q2_VERSION, BPFLOADER_MAX_VER, LOAD_ON_ENG, LOAD_ON_USER,
LOAD_ON_USERDEBUG, 0)
+// not preallocated
+DEFINE_BPF_MAP_EXT(local_net_blocked_uid_map, HASH, uint32_t, bool, -1000,
+ AID_ROOT, AID_NET_BW_ACCT, 0060, "fs_bpf_net_shared", "", PRIVATE,
+ BPFLOADER_MAINLINE_25Q2_VERSION, BPFLOADER_MAX_VER, LOAD_ON_ENG, LOAD_ON_USER,
+ LOAD_ON_USERDEBUG, 0)
+
// iptables xt_bpf programs need to be usable by both netd and netutils_wrappers
// selinux contexts, because even non-xt_bpf iptables mutations are implemented as
// a full table dump, followed by an update in userspace, and then a reload into the kernel,
@@ -250,10 +256,15 @@
return v ? *v : true;
}
-static __always_inline inline
-bool should_block_local_network_packets(struct __sk_buff *skb,
- const struct egress_bool egress,
- const struct kver_uint kver) {
+static __always_inline inline bool should_block_local_network_packets(struct __sk_buff *skb,
+ const uint32_t uid, const struct egress_bool egress,
+ const struct kver_uint kver) {
+ if (is_system_uid(uid)) return false;
+
+ bool* block_local_net = bpf_local_net_blocked_uid_map_lookup_elem(&uid);
+ if (!block_local_net) return false; // uid not found in map
+ if (!*block_local_net) return false; // lookup returned 'bool false'
+
struct in6_addr remote_ip6;
uint8_t ip_proto;
uint8_t L4_off;
@@ -548,7 +559,7 @@
}
if (SDK_LEVEL_IS_AT_LEAST(lvl, 25Q2) && (match != DROP)) {
- if (should_block_local_network_packets(skb, egress, kver)) match = DROP;
+ if (should_block_local_network_packets(skb, uid, egress, kver)) match = DROP;
}
// If an outbound packet is going to be dropped, we do not count that traffic.
diff --git a/bpf/progs/netd.h b/bpf/progs/netd.h
index 6561311..8400679 100644
--- a/bpf/progs/netd.h
+++ b/bpf/progs/netd.h
@@ -186,6 +186,7 @@
#define PACKET_TRACE_ENABLED_MAP_PATH BPF_NETD_PATH "map_netd_packet_trace_enabled_map"
#define DATA_SAVER_ENABLED_MAP_PATH BPF_NETD_PATH "map_netd_data_saver_enabled_map"
#define LOCAL_NET_ACCESS_MAP_PATH BPF_NETD_PATH "map_netd_local_net_access_map"
+#define LOCAL_NET_BLOCKED_UID_MAP_PATH BPF_NETD_PATH "map_netd_local_net_blocked_uid_map"
#endif // __cplusplus
diff --git a/bpf/tests/mts/bpf_existence_test.cpp b/bpf/tests/mts/bpf_existence_test.cpp
index d605379..2cfa546 100644
--- a/bpf/tests/mts/bpf_existence_test.cpp
+++ b/bpf/tests/mts/bpf_existence_test.cpp
@@ -169,6 +169,7 @@
// Provided by *current* mainline module for 25Q2+ devices
static const set<string> MAINLINE_FOR_25Q2_PLUS = {
NETD "map_netd_local_net_access_map",
+ NETD "map_netd_local_net_blocked_uid_map",
};
static void addAll(set<string>& a, const set<string>& b) {