diff options
author | Bram Bonné <brambonne@google.com> | 2019-05-07 14:02:05 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-05-07 14:02:05 +0000 |
commit | 5e8961db0f7866b354c2c1a213267ee1d32185ea (patch) | |
tree | d2b4b12123bdd78d168a1a1dca07ff066cc031f0 /service | |
parent | 353e8733c58131f4f78e63f2adb6a4f6379a1d59 (diff) | |
parent | 6192d528888183b233f78977d2c974bbfb971d5f (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.java | 133 | ||||
-rw-r--r-- | service/java/com/android/server/wifi/util/WifiPermissionsUtil.java | 9 |
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) { |