summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorBram Bonné <brambonne@google.com>2019-05-07 14:02:05 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-05-07 14:02:05 +0000
commit5e8961db0f7866b354c2c1a213267ee1d32185ea (patch)
treed2b4b12123bdd78d168a1a1dca07ff066cc031f0 /service
parent353e8733c58131f4f78e63f2adb6a4f6379a1d59 (diff)
parent6192d528888183b233f78977d2c974bbfb971d5f (diff)
Merge "Limit access to the device's fixed 802.11 MAC address." into qt-dev
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java133
-rw-r--r--service/java/com/android/server/wifi/util/WifiPermissionsUtil.java9
2 files changed, 137 insertions, 5 deletions
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 32b46e4d1..adc863ba9 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -262,6 +262,10 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// The empty device address set by wpa_supplicant.
private static final String EMPTY_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ // An anonymized device address. This is used instead of the own device MAC to prevent the
+ // latter from leaking to apps
+ private static final String ANONYMIZED_DEVICE_ADDRESS = "02:00:00:00:00:00";
+
/**
* Error code definition.
* see the Table.8 in the WiFi Direct specification for the detail.
@@ -1049,11 +1053,13 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
}
replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
- mGroup != null ? new WifiP2pGroup(mGroup) : null);
+ maybeEraseOwnDeviceAddress(mGroup, message.sendingUid));
break;
case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
- new WifiP2pGroupList(mGroups, null));
+ new WifiP2pGroupList(
+ maybeEraseOwnDeviceAddress(mGroups, message.sendingUid),
+ null));
break;
case WifiP2pManager.REQUEST_P2P_STATE:
replyToMessage(message, WifiP2pManager.RESPONSE_P2P_STATE,
@@ -1197,7 +1203,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
}
replyToMessage(message, WifiP2pManager.RESPONSE_DEVICE_INFO,
- new WifiP2pDevice(mThisDevice));
+ maybeEraseOwnDeviceAddress(mThisDevice, message.sendingUid));
break;
default:
loge("Unhandled message " + message);
@@ -2979,7 +2985,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private void sendThisDeviceChangedBroadcast() {
final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, new WifiP2pDevice(mThisDevice));
+ intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE,
+ eraseOwnDeviceAddress(mThisDevice));
mContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
RECEIVER_PERMISSIONS_FOR_BROADCAST);
}
@@ -2999,7 +3006,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
- intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, new WifiP2pGroup(mGroup));
+ intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, eraseOwnDeviceAddress(mGroup));
mContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
RECEIVER_PERMISSIONS_FOR_BROADCAST);
if (mWifiChannel != null) {
@@ -3285,6 +3292,122 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
/**
+ * Erase the MAC address of our interface if it is present in a given device, to prevent
+ * apps from having access to persistent identifiers.
+ *
+ * @param device a device possibly having the same physical address as the wlan interface.
+ * @return a copy of the input, possibly with the device address erased.
+ */
+ private WifiP2pDevice eraseOwnDeviceAddress(WifiP2pDevice device) {
+ if (device == null) {
+ return null;
+ }
+ WifiP2pDevice result = new WifiP2pDevice(device);
+ if (device.deviceAddress != null
+ && mThisDevice.deviceAddress != null
+ && device.deviceAddress.length() > 0
+ && mThisDevice.deviceAddress.equals(device.deviceAddress)) {
+ result.deviceAddress = ANONYMIZED_DEVICE_ADDRESS;
+ }
+ return result;
+ }
+
+ /**
+ * Erase the MAC address of our interface if it is set as the device address for any of the
+ * devices in a group.
+ *
+ * @param group a p2p group containing p2p devices.
+ * @return a copy of the input, with any devices corresponding to our wlan interface having
+ * their device address erased.
+ */
+ private WifiP2pGroup eraseOwnDeviceAddress(WifiP2pGroup group) {
+ if (group == null) {
+ return null;
+ }
+
+ WifiP2pGroup result = new WifiP2pGroup(group);
+
+ // Create copies of the clients so they're not shared with the original object.
+ for (WifiP2pDevice originalDevice : group.getClientList()) {
+ result.removeClient(originalDevice);
+ result.addClient(eraseOwnDeviceAddress(originalDevice));
+ }
+
+ WifiP2pDevice groupOwner = group.getOwner();
+ result.setOwner(eraseOwnDeviceAddress(groupOwner));
+
+ return result;
+ }
+
+ /**
+ * Erase the MAC address of our interface if it is present in a given device, to prevent
+ * apps from having access to persistent identifiers. If the requesting party holds the
+ * {@link Manifest.permission.LOCAL_MAC_ADDRESS} permission, the address is not erased.
+ *
+ * @param device a device possibly having the same physical address as the wlan interface.
+ * @param uid the user id of the app that requested the information.
+ * @return a copy of the input, possibly with the device address erased.
+ */
+ private WifiP2pDevice maybeEraseOwnDeviceAddress(WifiP2pDevice device, int uid) {
+ if (device == null) {
+ return null;
+ }
+ if (mWifiPermissionsUtil.checkLocalMacAddressPermission(uid)) {
+ // Calling app holds the LOCAL_MAC_ADDRESS permission, and is allowed to see this
+ // device's MAC.
+ return new WifiP2pDevice(device);
+ } else {
+ return eraseOwnDeviceAddress(device);
+ }
+ }
+
+ /**
+ * Erase the MAC address of our interface if it is set as the device address for any of the
+ * devices in a group. If the requesting party holds the
+ * {@link Manifest.permission.LOCAL_MAC_ADDRESS} permission, the address is not erased.
+ *
+ * @param group a p2p group containing p2p devices.
+ * @param uid the user id of the app that requested the information.
+ * @return a copy of the input, with any devices corresponding to our wlan interface having
+ * their device address erased. If the requesting app holds the LOCAL_MAC_ADDRESS
+ * permission, this method returns a copy of the input.
+ */
+ private WifiP2pGroup maybeEraseOwnDeviceAddress(WifiP2pGroup group, int uid) {
+ if (group == null) {
+ return null;
+ }
+ if (mWifiPermissionsUtil.checkLocalMacAddressPermission(uid)) {
+ // Calling app holds the LOCAL_MAC_ADDRESS permission, and is allowed to see this
+ // device's MAC.
+ return new WifiP2pGroup(group);
+ } else {
+ return eraseOwnDeviceAddress(group);
+ }
+ }
+
+ /**
+ * Erase the MAC address of our interface if it is set as the device address for any of the
+ * devices in a list of groups. If the requesting party holds the
+ * {@link Manifest.permission.LOCAL_MAC_ADDRESS} permission, the address is not erased.
+ *
+ * @param groupList a list of p2p groups containing p2p devices.
+ * @param uid the user id of the app that requested the information.
+ * @return a copy of the input, with any devices corresponding to our wlan interface having
+ * their device address erased. If the requesting app holds the LOCAL_MAC_ADDRESS
+ * permission, this method returns a copy of the input.
+ */
+ private WifiP2pGroupList maybeEraseOwnDeviceAddress(WifiP2pGroupList groupList, int uid) {
+ if (groupList == null) {
+ return null;
+ }
+ WifiP2pGroupList result = new WifiP2pGroupList();
+ for (WifiP2pGroup group : groupList.getGroupList()) {
+ result.add(maybeEraseOwnDeviceAddress(group, uid));
+ }
+ return result;
+ }
+
+ /**
* Start a p2p group negotiation and display pin if necessary
* @param config for the peer
*/
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index eeacac044..7f743e8d8 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -448,6 +448,15 @@ public class WifiPermissionsUtil {
}
/**
+ * Returns true if the |uid| holds LOCAL_MAC_ADDRESS permission.
+ */
+ public boolean checkLocalMacAddressPermission(int uid) {
+ return mWifiPermissionsWrapper.getUidPermission(
+ android.Manifest.permission.LOCAL_MAC_ADDRESS, uid)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ /**
* Returns true if the |uid| holds NETWORK_SETUP_WIZARD permission.
*/
public boolean checkNetworkSetupWizardPermission(int uid) {