From b2c286816d35877ffe22e70f5bc1c03c6d03b214 Mon Sep 17 00:00:00 2001 From: paulhu Date: Wed, 18 Aug 2021 18:35:54 +0800 Subject: [PATCH] Ensure calling package name and uid are matched CS#requestRouteToHostAddress enforcing change permission doesn't check whether the calling package belongs to calling uid. This can be used to check whether package name exists or not without permission. Thus, add a check to ensure calling package name and uid are matched. Bug: 193801134 Test: atest FrameworksNetTests CtsNetTestCases Ignore-AOSP-First: Security fix Change-Id: I980f1c68b5321601aa40da29e283fb4dd717d5de --- .../android/server/ConnectivityService.java | 21 +++++++++++++++++++ .../server/ConnectivityServiceTest.java | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index e34c0640c2..418e9e33b8 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -2361,6 +2361,26 @@ public class ConnectivityService extends IConnectivityManager.Stub return false; } + private int getAppUid(final String app, final UserHandle user) { + final PackageManager pm = + mContext.createContextAsUser(user, 0 /* flags */).getPackageManager(); + final long token = Binder.clearCallingIdentity(); + try { + return pm.getPackageUid(app, 0 /* flags */); + } catch (PackageManager.NameNotFoundException e) { + return -1; + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private void verifyCallingUidAndPackage(String packageName, int callingUid) { + final UserHandle user = UserHandle.getUserHandleForUid(callingUid); + if (getAppUid(packageName, user) != callingUid) { + throw new SecurityException(packageName + " does not belong to uid " + callingUid); + } + } + /** * Ensure that a network route exists to deliver traffic to the specified * host via the specified network interface. @@ -2376,6 +2396,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (disallowedBecauseSystemCaller()) { return false; } + verifyCallingUidAndPackage(callingPackageName, mDeps.getCallingUid()); enforceChangePermission(callingPackageName, callingAttributionTag); if (mProtectedNetworks.contains(networkType)) { enforceConnectivityRestrictedNetworksPermission(); diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index 10b7e14fe5..b90016986c 100644 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -13941,4 +13941,11 @@ public class ConnectivityServiceTest { mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); } + + @Test + public void testRequestRouteToHostAddress_PackageDoesNotBelongToCaller() { + assertThrows(SecurityException.class, () -> mService.requestRouteToHostAddress( + ConnectivityManager.TYPE_NONE, null /* hostAddress */, "com.not.package.owner", + null /* callingAttributionTag */)); + } }