diff options
author | Roshan Pius <rpius@google.com> | 2020-03-13 09:53:39 -0700 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2020-03-13 12:35:48 -0700 |
commit | 5c99f2f1d4c31c81ea0fd4d5928ad47cc15a467e (patch) | |
tree | b81ba8d6ce7a2b7f38eae89f1bd127112e2c3f93 | |
parent | 97b650668bfaff86323216eca1e03b827dc96ee4 (diff) |
WifiAwareDataPath: Use uid + package name to match app
Bug: 149061080
Test: atest com.android.server.wifi.aware
Test: Will verify presubmit test results.
Change-Id: Ib9a73252ce90e1fd5034309f01c80311a47d4f56
4 files changed, 128 insertions, 46 deletions
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java index 0bbd2193e..867587720 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java @@ -672,7 +672,7 @@ public class WifiAwareDataPathStateManager { mAwareMetrics.recordNdpStatus(NanStatusType.SUCCESS, isOutOfBand, nnri.startTimestamp); nnri.startTimestamp = mClock.getElapsedSinceBootMillis(); // update time-stamp - mAwareMetrics.recordNdpCreation(nnri.uid, mNetworkRequestsCache); + mAwareMetrics.recordNdpCreation(nnri.uid, nnri.packageName, mNetworkRequestsCache); } else { if (mClock.getElapsedSinceBootMillis() - nnri.startValidationTimestamp > ADDRESS_VALIDATION_TIMEOUT_MS) { @@ -1160,6 +1160,7 @@ public class WifiAwareDataPathStateManager { public int state; public int uid; + public String packageName; public String interfaceName; public int pubSubId = 0; public int peerInstanceId = 0; @@ -1231,6 +1232,7 @@ public class WifiAwareDataPathStateManager { boolean allowNdpResponderFromAnyOverride) { int uid, pubSubId = 0; int peerInstanceId = 0; + String packageName = null; byte[] peerMac = ns.peerMac; if (VDBG) { @@ -1270,6 +1272,7 @@ public class WifiAwareDataPathStateManager { return null; } uid = client.getUid(); + packageName = client.getCallingPackage(); // API change post 27: no longer allow "ANY"-style responders (initiators were never // permitted). @@ -1350,10 +1353,12 @@ public class WifiAwareDataPathStateManager { } } - // validate UID - if (request.getRequestorUid() != uid) { + // validate UID && package name + if (request.getRequestorUid() != uid + || !TextUtils.equals(request.getRequestorPackageName(), packageName)) { Log.e(TAG, "processNetworkSpecifier: networkSpecifier=" + ns.toString() - + " -- UID mismatch to clientId's uid=" + uid); + + " -- UID or package name mismatch to clientId's uid=" + uid + + ", packageName=" + packageName); return null; } @@ -1375,6 +1380,7 @@ public class WifiAwareDataPathStateManager { AwareNetworkRequestInformation nnri = new AwareNetworkRequestInformation(); nnri.state = AwareNetworkRequestInformation.STATE_IDLE; nnri.uid = uid; + nnri.packageName = packageName; nnri.pubSubId = pubSubId; nnri.peerInstanceId = peerInstanceId; nnri.peerDiscoveryMac = peerMac; @@ -1387,8 +1393,10 @@ public class WifiAwareDataPathStateManager { @Override public String toString() { StringBuilder sb = new StringBuilder("AwareNetworkRequestInformation: "); - sb.append("state=").append(state).append(", ns=").append(networkSpecifier).append( - ", uid=").append(uid).append(", interfaceName=").append(interfaceName).append( + sb.append("state=").append(state).append(", ns=").append(networkSpecifier) + .append(", uid=").append(uid) + .append(", packageName=").append(packageName) + .append(", interfaceName=").append(interfaceName).append( ", pubSubId=").append(pubSubId).append(", peerInstanceId=").append( peerInstanceId).append(", peerDiscoveryMac=").append( peerDiscoveryMac == null ? "" @@ -1500,6 +1508,7 @@ public class WifiAwareDataPathStateManager { } networkCapabilities.setRequestorUid(nnri.uid); + networkCapabilities.setRequestorPackageName(nnri.packageName); networkCapabilities.setNetworkSpecifier(new WifiAwareAgentNetworkSpecifier( networkRequests.stream() .map(NetworkRequest::getNetworkSpecifier) diff --git a/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java b/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java index 1fb5a5306..67b0cd887 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java @@ -392,7 +392,7 @@ public class WifiAwareMetrics { /** * Record NDP (and by extension NDI) usage - on successful creation of an NDP. */ - public void recordNdpCreation(int uid, + public void recordNdpCreation(int uid, String packageName, Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager .AwareNetworkRequestInformation> networkRequestCache) { int numNdpInApp = 0; @@ -412,12 +412,12 @@ public class WifiAwareMetrics { continue; // only count completed (up-and-running) NDPs } - boolean sameUid = anri.uid == uid; + boolean sameApp = (anri.uid == uid) && TextUtils.equals(anri.packageName, packageName); boolean isSecure = !TextUtils.isEmpty(anri.networkSpecifier.passphrase) || ( anri.networkSpecifier.pmk != null && anri.networkSpecifier.pmk.length != 0); // in-app stats - if (sameUid) { + if (sameApp) { numNdpInApp += 1; if (isSecure) { numSecureNdpInApp += 1; diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java index 671d77645..df7417338 100644 --- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java @@ -108,6 +108,8 @@ import java.util.Set; @SmallTest public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { private static final String sAwareInterfacePrefix = "aware_data"; + private static final String TEST_PACKAGE_NAME = "com.android.somePackage"; + private static final String TEST_FEATURE_ID = "com.android.someFeature"; private TestLooper mMockLooper; private Handler mMockLooperHandler; @@ -513,7 +515,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { agentMessengers[i] = messengerCaptor.getValue(); inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), eq(false), anyLong()); - inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any()); + inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); WifiAwareNetworkInfo netInfo = (WifiAwareNetworkInfo) netCapCaptor.getValue().getTransportInfo(); assertArrayEquals(MacAddress.fromBytes( @@ -637,7 +639,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { netCapCaptor.capture(), anyInt(), any(), anyInt()); inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), eq(true), anyLong()); - inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any()); + inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); WifiAwareNetworkInfo netInfo = (WifiAwareNetworkInfo) netCapCaptor.getValue().getTransportInfo(); assertArrayEquals(MacAddress.fromBytes( @@ -755,7 +757,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { netCapCaptor.capture(), anyInt(), any(), anyInt()); inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), eq(true), anyLong()); - inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any()); + inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); WifiAwareNetworkInfo netInfo = (WifiAwareNetworkInfo) netCapCaptor.getValue().getTransportInfo(); assertArrayEquals(MacAddress.fromBytes( @@ -911,20 +913,21 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { } /** - * Validate the fail flow of an Initiator (subscriber) with its UID unset + * Validate the fail flow of an Initiator (subscriber) with its UID set as a malicious + * attacker (i.e. mismatched to its requested client's UID). */ @Test - public void testDataPathInitiatorUidUnsetError() throws Exception { - testDataPathInitiatorResponderInvalidUidUtility(false, false); + public void testDataPathInitiatorUidSetIncorrectlyError() throws Exception { + testDataPathInitiatorResponderInvalidUidUtility(false); } /** - * Validate the fail flow of an Initiator (subscriber) with its UID set as a malicious - * attacker (i.e. mismatched to its requested client's UID). + * Validate the fail flow of an Initiator (subscriber) with its package namee set as a malicious + * attacker (i.e. mismatched to its requested client's package name). */ @Test - public void testDataPathInitiatorUidSetIncorrectlyError() throws Exception { - testDataPathInitiatorResponderInvalidUidUtility(false, true); + public void testDataPathInitiatorPackageNameSetIncorrectlyError() throws Exception { + testDataPathInitiatorResponderInvalidPackageNameUtility(false); } /* @@ -1066,20 +1069,22 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { } /** - * Validate the fail flow of an Initiator (subscriber) with its UID unset + * Validate the fail flow of an Initiator (subscriber) with its UID set as a malicious + * attacker (i.e. mismatched to its requested client's UID). */ @Test - public void testDataPathResponderUidUnsetError() throws Exception { - testDataPathInitiatorResponderInvalidUidUtility(true, false); + public void testDataPathResponderUidSetIncorrectlyError() throws Exception { + testDataPathInitiatorResponderInvalidUidUtility(true); } + /** - * Validate the fail flow of an Initiator (subscriber) with its UID set as a malicious - * attacker (i.e. mismatched to its requested client's UID). + * Validate the fail flow of an Initiator (subscriber) with its package name set as a malicious + * attacker (i.e. mismatched to its requested client's package name). */ @Test - public void testDataPathResponderUidSetIncorrectlyError() throws Exception { - testDataPathInitiatorResponderInvalidUidUtility(true, true); + public void testDataPathResponderPackageNameSetIncorrectlyError() throws Exception { + testDataPathInitiatorResponderInvalidPackageNameUtility(true); } /** @@ -1156,7 +1161,8 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { 0, 0); nr.networkCapabilities.setNetworkSpecifier(ns); - nr.networkCapabilities.setRequestorUid(0); + nr.networkCapabilities.setRequestorUid(Process.myUid()); + nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME); Message reqNetworkMsg = Message.obtain(); reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; @@ -1180,8 +1186,8 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { verifyNoMoreInteractions(mMockNative, mMockCm, mAwareMetricsMock, mMockNetdWrapper); } - private void testDataPathInitiatorResponderInvalidUidUtility(boolean doPublish, - boolean isUidSet) throws Exception { + private void testDataPathInitiatorResponderInvalidUidUtility(boolean doPublish) + throws Exception { final int clientId = 123; final byte pubSubId = 56; final int ndpId = 2; @@ -1216,6 +1222,68 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { 0); nr.networkCapabilities.setNetworkSpecifier(ns); nr.networkCapabilities.setRequestorUid(0 + 1); // corruption hack + nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME); + + // (3) request network + Message reqNetworkMsg = Message.obtain(); + reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; + reqNetworkMsg.obj = nr; + reqNetworkMsg.arg1 = 0; + res.mMessenger.send(reqNetworkMsg); + mMockLooper.dispatchAll(); + + // consequences of failure: + // Responder (publisher): responds with a rejection to any data-path requests + // Initiator (subscribe): doesn't initiate (i.e. no HAL requests) + verifyRequestDeclaredUnfullfillable(nr); + if (doPublish) { + // (2) get request & respond + mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null); + mMockLooper.dispatchAll(); + inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false), + eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any()); + } + + verifyNoMoreInteractions(mMockNative, mMockCm, mAwareMetricsMock, mMockNetdWrapper); + } + + private void testDataPathInitiatorResponderInvalidPackageNameUtility(boolean doPublish) + throws Exception { + final int clientId = 123; + final byte pubSubId = 56; + final int ndpId = 2; + final byte[] pmk = "01234567890123456789012345678901".getBytes(); + final int requestorId = 1341234; + final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); + + InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); + InOrder inOrderM = inOrder(mAwareMetricsMock); + + // (0) initialize + DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, + peerDiscoveryMac, inOrder, inOrderM, doPublish); + + // (1) create network request + NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle, pmk, + null, doPublish, 0); + + // (2) corrupt request's UID + WifiAwareNetworkSpecifier ns = + (WifiAwareNetworkSpecifier) nr.networkCapabilities.getNetworkSpecifier(); + ns = new WifiAwareNetworkSpecifier( + ns.type, + ns.role, + ns.clientId, + ns.sessionId, + ns.peerId, + ns.peerMac, + ns.pmk, + ns.passphrase, + 0, + 0); + nr.networkCapabilities.setNetworkSpecifier(ns); + nr.networkCapabilities.setRequestorUid(Process.myUid()); // corruption hack + nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME + "h"); // corruption hack // (3) request network Message reqNetworkMsg = Message.obtain(); @@ -1370,7 +1438,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { inOrder.verify(mMockNetworkInterface).setConnected(any()); inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), eq(useDirect), anyLong()); - inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any()); + inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); WifiAwareNetworkInfo netInfo = (WifiAwareNetworkInfo) netCapCaptor.getValue().getTransportInfo(); assertEquals(ipv6Address, netInfo.getPeerIpv6Addr().getHostAddress()); @@ -1485,7 +1553,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { any(), netCapCaptor.capture(), anyInt(), any(), anyInt()); inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), eq(useDirect), anyLong()); - inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any()); + inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); WifiAwareNetworkInfo netInfo = (WifiAwareNetworkInfo) netCapCaptor.getValue().getTransportInfo(); assertArrayEquals(MacAddress.fromBytes( @@ -1623,6 +1691,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { nc.setLinkDownstreamBandwidthKbps(1); nc.setSignalStrength(1); nc.setRequestorUid(Process.myUid()); + nc.setRequestorPackageName(TEST_PACKAGE_NAME); return new NetworkRequest(nc, 0, requestId, NetworkRequest.Type.REQUEST); } @@ -1674,6 +1743,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { nc.setLinkDownstreamBandwidthKbps(1); nc.setSignalStrength(1); nc.setRequestorUid(Process.myUid()); + nc.setRequestorPackageName(TEST_PACKAGE_NAME); return new NetworkRequest(nc, 0, requestId, NetworkRequest.Type.REQUEST); } @@ -1727,8 +1797,6 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { int maxNdiInterfaces, int clientId, InOrder inOrder, InOrder inOrderM) throws Exception { final int pid = 2000; - final String callingPackage = "com.android.somePackage"; - final String callingFeatureId = "com.android.someFeature"; final ConfigRequest configRequest = new ConfigRequest.Builder().build(); ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); @@ -1760,7 +1828,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { } // (3) create client - mDut.connect(clientId, Process.myUid(), pid, callingPackage, callingFeatureId, + mDut.connect(clientId, Process.myUid(), pid, TEST_PACKAGE_NAME, TEST_FEATURE_ID, mMockCallback, configRequest, false); mMockLooper.dispatchAll(); diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java index 9bc5ffbf3..824a3e54c 100644 --- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java @@ -466,7 +466,9 @@ public class WifiAwareMetricsTest extends WifiBaseTest { @Test public void testDataPathMetrics() { final int uid1 = 1005; + final String package1 = "com.test1"; final int uid2 = 1006; + final String package2 = "com.test2"; final String ndi0 = "aware_data0"; final String ndi1 = "aware_data1"; Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager.AwareNetworkRequestInformation> @@ -476,27 +478,29 @@ public class WifiAwareMetricsTest extends WifiBaseTest { setTime(5); // uid1: ndp (non-secure) on ndi0 - addNetworkInfoToCache(networkRequestCache, 10, uid1, ndi0, null); - mDut.recordNdpCreation(uid1, networkRequestCache); + addNetworkInfoToCache(networkRequestCache, 10, uid1, package1, ndi0, null); + mDut.recordNdpCreation(uid1, package1, networkRequestCache); setTime(7); // 2ms creation time mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 5); // uid2: ndp (non-secure) on ndi0 - WifiAwareNetworkSpecifier ns = addNetworkInfoToCache(networkRequestCache, 11, uid2, ndi0, - null); - mDut.recordNdpCreation(uid2, networkRequestCache); + WifiAwareNetworkSpecifier ns = addNetworkInfoToCache(networkRequestCache, 11, uid2, + package2, ndi0, null); + mDut.recordNdpCreation(uid2, package2, networkRequestCache); setTime(10); // 3 ms creation time mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 7); // uid2: ndp (secure) on ndi1 (OOB) - addNetworkInfoToCache(networkRequestCache, 12, uid2, ndi1, "passphrase of some kind"); - mDut.recordNdpCreation(uid2, networkRequestCache); + addNetworkInfoToCache(networkRequestCache, 12, uid2, package2, ndi1, + "passphrase of some kind"); + mDut.recordNdpCreation(uid2, package2, networkRequestCache); setTime(25); // 15 ms creation time mDut.recordNdpStatus(NanStatusType.SUCCESS, true, 10); // uid2: ndp (secure) on ndi0 (OOB) - addNetworkInfoToCache(networkRequestCache, 13, uid2, ndi0, "super secret password"); - mDut.recordNdpCreation(uid2, networkRequestCache); + addNetworkInfoToCache(networkRequestCache, 13, uid2, package2, ndi0, + "super secret password"); + mDut.recordNdpCreation(uid2, package2, networkRequestCache); setTime(36); // 11 ms creation time mDut.recordNdpStatus(NanStatusType.SUCCESS, true, 25); @@ -504,8 +508,8 @@ public class WifiAwareMetricsTest extends WifiBaseTest { networkRequestCache.remove(ns); // uid2: ndp (non-secure) on ndi0 - addNetworkInfoToCache(networkRequestCache, 14, uid2, ndi0, null); - mDut.recordNdpCreation(uid2, networkRequestCache); + addNetworkInfoToCache(networkRequestCache, 14, uid2, package2, ndi0, null); + mDut.recordNdpCreation(uid2, package2, networkRequestCache); setTime(37); // 1 ms creation time! mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 36); @@ -670,7 +674,7 @@ public class WifiAwareMetricsTest extends WifiBaseTest { private WifiAwareNetworkSpecifier addNetworkInfoToCache( Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager .AwareNetworkRequestInformation> networkRequestCache, - int index, int uid, String interfaceName, String passphrase) { + int index, int uid, String packageName, String interfaceName, String passphrase) { WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(0, 0, 0, index, 0, null, null, passphrase, 0, 0); WifiAwareDataPathStateManager.AwareNetworkRequestInformation anri = @@ -678,6 +682,7 @@ public class WifiAwareMetricsTest extends WifiBaseTest { anri.networkSpecifier = ns; anri.state = WifiAwareDataPathStateManager.AwareNetworkRequestInformation.STATE_CONFIRMED; anri.uid = uid; + anri.packageName = packageName; anri.interfaceName = interfaceName; networkRequestCache.put(ns, anri); |