From 9b272fa53abf13b6ddc0e23ce424b7bdfae9381f Mon Sep 17 00:00:00 2001 From: Motomu Utsumi Date: Fri, 15 Mar 2024 19:08:01 +0900 Subject: [PATCH] Use bpf map based isUidNetworkingBlocked on V+ NetworkPolicyManager#isUidNetworkingBlocked does not know about some firewall chains status(e.g. FIREWALL_CHAIN_OEM_DENY_1) So BpfNetMaps#isUidNetworkingBlocked is more correct but there could be some behavior difference. To avoid breaking devices and have longer verification time, this CL updates to use BpfNetMaps#isUidNetworkingBlocked only on V+ devices. Bug: 328732146 Test: TH Change-Id: I60f84a5fff90386103692841dead465652249446 --- .../src/com/android/server/BpfNetMaps.java | 19 +++++++++++++++++++ .../android/server/ConnectivityService.java | 6 +++++- .../server/ConnectivityServiceTest.java | 2 ++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java index fc6d8c47bb..42c1628b3d 100644 --- a/service/src/com/android/server/BpfNetMaps.java +++ b/service/src/com/android/server/BpfNetMaps.java @@ -918,6 +918,25 @@ public class BpfNetMaps { } } + /** + * Return whether the network is blocked by firewall chains for the given uid. + * + * Note that {@link #getDataSaverEnabled()} has a latency before V. + * + * @param uid The target uid. + * @param isNetworkMetered Whether the target network is metered. + * + * @return True if the network is blocked. Otherwise, false. + * @throws ServiceSpecificException if the read fails. + * + * @hide + */ + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + public boolean isUidNetworkingBlocked(final int uid, boolean isNetworkMetered) { + return BpfNetMapsUtils.isUidNetworkingBlocked(uid, isNetworkMetered, + sConfigurationMap, sUidOwnerMap, sDataSaverEnabledMap); + } + /** Register callback for statsd to pull atom. */ @RequiresApi(Build.VERSION_CODES.TIRAMISU) public void setPullAtomCallback(final Context context) { diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 123ad8f865..005d6177e5 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -2235,7 +2235,11 @@ public class ConnectivityService extends IConnectivityManager.Stub final long ident = Binder.clearCallingIdentity(); try { final boolean metered = nc == null ? true : nc.isMetered(); - return mPolicyManager.isUidNetworkingBlocked(uid, metered); + if (mDeps.isAtLeastV()) { + return mBpfNetMaps.isUidNetworkingBlocked(uid, metered); + } else { + return mPolicyManager.isUidNetworkingBlocked(uid, metered); + } } finally { Binder.restoreCallingIdentity(ident); } diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index f41d7b288a..0bc04adfa5 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -1719,6 +1719,8 @@ public class ConnectivityServiceTest { private void mockUidNetworkingBlocked() { doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean()); + doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) + ).when(mBpfNetMaps).isUidNetworkingBlocked(anyInt(), anyBoolean()); } private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) {