Make firewall bpf code multi-user aware

The check is_system_uid should mirror the definition of core_uids in
UserHandle.isCore until it is available to be read from mainline code.
isUidNetworkingBlocked should also do the same.

Test: All existing tests should pass.
Test: atest CtsHostsideNetworkPolicyTests
Test: atest FrameworksNetTests

Bug: 348316140
Change-Id: Id5e01289b301a725b162ef249062e0f2806876dc
diff --git a/bpf_progs/netd.h b/bpf_progs/netd.h
index 332979b..4877a4b 100644
--- a/bpf_progs/netd.h
+++ b/bpf_progs/netd.h
@@ -270,5 +270,5 @@
 static inline bool is_system_uid(uint32_t uid) {
     // MIN_SYSTEM_UID is AID_ROOT == 0, so uint32_t is *always* >= 0
     // MAX_SYSTEM_UID is AID_NOBODY == 9999, while AID_APP_START == 10000
-    return (uid < AID_APP_START);
+    return ((uid % AID_USER_OFFSET) < AID_APP_START);
 }
diff --git a/framework/src/android/net/BpfNetMapsUtils.java b/framework/src/android/net/BpfNetMapsUtils.java
index 4099e2a..282a11e 100644
--- a/framework/src/android/net/BpfNetMapsUtils.java
+++ b/framework/src/android/net/BpfNetMapsUtils.java
@@ -68,6 +68,7 @@
 import android.os.Build;
 import android.os.Process;
 import android.os.ServiceSpecificException;
+import android.os.UserHandle;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.Pair;
@@ -330,9 +331,9 @@
     ) {
         throwIfPreT("isUidBlockedByFirewallChains is not available on pre-T devices");
 
-        // System uid is not blocked by firewall chains, see bpf_progs/netd.c
-        // TODO: use UserHandle.isCore() once it is accessible
-        if (uid < Process.FIRST_APPLICATION_UID) {
+        // System uids are not blocked by firewall chains, see bpf_progs/netd.c
+        // TODO: b/348513058 - use UserHandle.isCore() once it is accessible
+        if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) {
             return false;
         }
 
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index cbc060a..859c54a 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -87,7 +87,9 @@
 import android.net.InetAddresses;
 import android.net.UidOwnerValue;
 import android.os.Build;
+import android.os.Process;
 import android.os.ServiceSpecificException;
+import android.os.UserHandle;
 import android.system.ErrnoException;
 import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
@@ -1249,6 +1251,32 @@
         );
     }
 
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testIsUidNetworkingBlockedForCoreUids() throws Exception {
+        final long allowlistMatch = BACKGROUND_MATCH;    // Enable any allowlist match.
+        mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(allowlistMatch));
+
+        // Verify that a normal uid that is not on this chain is indeed blocked.
+        assertTrue(BpfNetMapsUtils.isUidNetworkingBlocked(TEST_UID, false, mConfigurationMap,
+                mUidOwnerMap, mDataSaverEnabledMap));
+
+        final int[] coreAids = new int[] {
+                Process.ROOT_UID,
+                Process.SYSTEM_UID,
+                Process.FIRST_APPLICATION_UID - 10,
+                Process.FIRST_APPLICATION_UID - 1,
+        };
+        // Core appIds are not on the chain but should still be allowed on any user.
+        for (int userId = 0; userId < 20; userId++) {
+            for (final int aid : coreAids) {
+                final int uid = UserHandle.getUid(userId, aid);
+                assertFalse(BpfNetMapsUtils.isUidNetworkingBlocked(uid, false, mConfigurationMap,
+                        mUidOwnerMap, mDataSaverEnabledMap));
+            }
+        }
+    }
+
     private void doTestIsUidRestrictedOnMeteredNetworks(
             final long enabledMatches,
             final long uidRules,