Merge "Use correct P2P GO intent value"
diff --git a/libwifi_hal/Android.mk b/libwifi_hal/Android.mk
index a34075d..b06171f 100644
--- a/libwifi_hal/Android.mk
+++ b/libwifi_hal/Android.mk
@@ -64,9 +64,11 @@
# ============================================================
include $(CLEAR_VARS)
LOCAL_MODULE := libwifi-hal-common
+LOCAL_VENDOR_MODULE := true
LOCAL_CFLAGS := $(wifi_hal_cflags)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES := libbase
+LOCAL_HEADER_LIBRARIES := libcutils_headers
LOCAL_SRC_FILES := wifi_hal_common.cpp
include $(BUILD_STATIC_LIBRARY)
@@ -75,6 +77,7 @@
# ============================================================
include $(CLEAR_VARS)
LOCAL_MODULE := libwifi-hal-fallback
+LOCAL_VENDOR_MODULE := true
LOCAL_CFLAGS := $(wifi_hal_cflags)
LOCAL_SRC_FILES := wifi_hal_fallback.cpp
LOCAL_HEADER_LIBRARIES := libhardware_legacy_headers
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index c5f3675..b81878d 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -703,6 +703,29 @@
}
/**
+ * see {@link android.net.wifi.WifiManager#updateInterfaceIpState(String, int)}
+ *
+ * The possible modes include: {@link WifiManager#IFACE_IP_MODE_TETHERED},
+ * {@link WifiManager#IFACE_IP_MODE_LOCAL_ONLY},
+ * {@link WifiManager#IFACE_IP_MODE_CONFIGURATION_ERROR}
+ *
+ * @param ifaceName String name of the updated interface
+ * @param mode new operating mode of the interface
+ *
+ * @throws SecurityException if the caller does not have permission to call update
+ */
+ @Override
+ public void updateInterfaceIpState(String ifaceName, int mode) {
+ // NETWORK_STACK is a signature only permission.
+ enforceNetworkStackPermission();
+
+ Slog.d(TAG, "updateInterfaceIpState: ifaceName=" + ifaceName + " mode=" + mode);
+ // TODO: keep track of modes in a datastructure - protect it with a lock of some sort.
+ // TODO: check the mode when startLOHS comes in in case it is already active
+ // TODO: if mode == LOCAL_ONLY, trigger onStarted callbacks
+ }
+
+ /**
* see {@link android.net.wifi.WifiManager#startSoftAp(WifiConfiguration)}
* @param wifiConfig SSID, security and channel details as
* part of WifiConfiguration
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index ccd1d46..21d6be1 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -5800,7 +5800,9 @@
// If this network was explicitly selected by the user, evaluate whether to call
// explicitlySelected() so the system can treat it appropriately.
WifiConfiguration config = getCurrentWifiConfiguration();
- if (mWifiConfigManager.getLastSelectedNetwork() == config.networkId) {
+ if (config == null) {
+ Log.wtf(TAG, "Current WifiConfiguration is null, but IP provisioning just succeeded");
+ } else if (mWifiConfigManager.getLastSelectedNetwork() == config.networkId) {
boolean prompt =
mWifiPermissionsUtil.checkConfigOverridePermission(config.lastConnectUid);
if (mVerboseLoggingEnabled) {
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
index 14d855e..723828d 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
@@ -592,8 +592,6 @@
return true;
}
- // TODO: validate that the client ID actually comes from the correct process and is
- // not faked?
nnri = AwareNetworkRequestInformation.processNetworkSpecifier(networkSpecifier, mMgr);
if (nnri == null) {
Log.e(TAG, "WifiAwareNetworkFactory.acceptRequest: request=" + request
@@ -903,6 +901,13 @@
}
}
+ // validate UID
+ if (ns.requestorUid != uid) {
+ Log.e(TAG, "processNetworkSpecifier: networkSpecifier=" + ns.toString()
+ + " -- UID mismatch to clientId's uid=" + uid);
+ return null;
+ }
+
// create container and populate
AwareNetworkRequestInformation nnri = new AwareNetworkRequestInformation();
nnri.state = (ns.role == WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR)
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index 6de39ac..8b687db 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -81,7 +81,8 @@
* @param context Context object of the caller.
*/
public void enforceTetherChangePermission(Context context) {
- ConnectivityManager.enforceTetherChangePermission(context);
+ String pkgName = context.getOpPackageName();
+ ConnectivityManager.enforceTetherChangePermission(context, pkgName);
}
/**
diff --git a/tests/wifitests/Android.mk b/tests/wifitests/Android.mk
index b285db6..5dbd756 100644
--- a/tests/wifitests/Android.mk
+++ b/tests/wifitests/Android.mk
@@ -100,7 +100,6 @@
libstagefright_foundation \
libstdc++ \
libsync \
- libwifi-hal \
libwifi-system \
libui \
libunwind \
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 e7a383c..a2e7c77 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
@@ -57,6 +57,7 @@
import android.os.INetworkManagementService;
import android.os.Message;
import android.os.Messenger;
+import android.os.Process;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
@@ -302,6 +303,23 @@
testDataPathInitiatorResponderMismatchUtility(true);
}
+ /**
+ * Validate the fail flow of an Initiator (subscriber) with its UID unset
+ */
+ @Test
+ public void testDataPathInitiatorUidUnsetError() throws Exception {
+ testDataPathInitiatorResponderInvalidUidUtility(false, 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).
+ */
+ @Test
+ public void testDataPathInitiatorUidSetIncorrectlyError() throws Exception {
+ testDataPathInitiatorResponderInvalidUidUtility(false, true);
+ }
+
/*
* Responder tests
*/
@@ -395,6 +413,23 @@
testDataPathInitiatorResponderMismatchUtility(false);
}
+ /**
+ * Validate the fail flow of an Initiator (subscriber) with its UID unset
+ */
+ @Test
+ public void testDataPathResponderUidUnsetError() throws Exception {
+ testDataPathInitiatorResponderInvalidUidUtility(true, 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).
+ */
+ @Test
+ public void testDataPathResponderUidSetIncorrectlyError() throws Exception {
+ testDataPathInitiatorResponderInvalidUidUtility(true, true);
+ }
+
/*
* Utilities
*/
@@ -428,8 +463,8 @@
ns.peerId,
ns.peerMac,
ns.pmk,
- ns.passphrase
- );
+ ns.passphrase,
+ ns.requestorUid);
nr.networkCapabilities.setNetworkSpecifier(ns);
Message reqNetworkMsg = Message.obtain();
@@ -453,6 +488,62 @@
verifyNoMoreInteractions(mMockNative, mMockCm);
}
+ private void testDataPathInitiatorResponderInvalidUidUtility(boolean doPublish,
+ boolean isUidSet) throws Exception {
+ final int clientId = 123;
+ final int pubSubId = 11234;
+ final int ndpId = 2;
+ final byte[] pmk = "some bytes".getBytes();
+ final PeerHandle peerHandle = new PeerHandle(1341234);
+ final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
+
+ InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
+
+ // (0) initialize
+ Pair<Integer, Messenger> res = initDataPathEndPoint(clientId, pubSubId, peerHandle,
+ peerDiscoveryMac, inOrder, doPublish);
+
+ // (1) create network request
+ NetworkRequest nr = getSessionNetworkRequest(clientId, res.first, peerHandle, pmk,
+ doPublish);
+
+ // (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,
+ ns.requestorUid + 1); // corruption hack
+ nr.networkCapabilities.setNetworkSpecifier(ns);
+
+ // (3) request network
+ Message reqNetworkMsg = Message.obtain();
+ reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK;
+ reqNetworkMsg.obj = nr;
+ reqNetworkMsg.arg1 = 0;
+ res.second.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)
+ if (doPublish) {
+ // (2) get request & respond
+ mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false),
+ eq(ndpId), eq(""), eq(null), eq(null), any());
+ }
+
+ verifyNoMoreInteractions(mMockNative, mMockCm);
+ }
+
private void testDataPathInitiatorUtility(boolean useDirect, boolean provideMac,
boolean providePmk, boolean getConfirmation, boolean immediateHalFailure)
throws Exception {
@@ -751,7 +842,6 @@
PeerHandle peerHandle, byte[] peerDiscoveryMac, InOrder inOrder,
boolean doPublish)
throws Exception {
- final int uid = 1000;
final int pid = 2000;
final String callingPackage = "com.android.somePackage";
final String someMsg = "some arbitrary message from peer";
@@ -790,7 +880,8 @@
mMockLooper.dispatchAll();
// (3) create client & session & rx message
- mDut.connect(clientId, uid, pid, callingPackage, mMockCallback, configRequest, false);
+ mDut.connect(clientId, Process.myUid(), pid, callingPackage, mMockCallback, configRequest,
+ false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
eq(configRequest), eq(false), eq(true));