Loading core/java/android/app/admin/DevicePolicyManager.java +9 −8 Original line number Diff line number Diff line Loading @@ -5001,14 +5001,15 @@ public class DevicePolicyManager { * <p>Device owner, profile owner and their delegated certificate installer can use * {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device information * including manufacturer, model, brand, device and product in the attestation record. * Only device owner and their delegated certificate installer can use * {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and {@link #ID_TYPE_MEID} to request * unique device identifiers to be attested (the serial number, IMEI and MEID correspondingly), * if supported by the device (see {@link #isDeviceIdAttestationSupported()}). * Additionally, device owner and their delegated certificate installer can also request the * attestation record to be signed using an individual attestation certificate by specifying * the {@link #ID_TYPE_INDIVIDUAL_ATTESTATION} flag (if supported by the device, see * {@link #isUniqueDeviceAttestationSupported()}). * Only device owner, profile owner on an organization-owned device and their delegated * certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and * {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial number, * IMEI and MEID correspondingly), if supported by the device * (see {@link #isDeviceIdAttestationSupported()}). * Additionally, device owner, profile owner on an organization-owned device and their delegated * certificate installers can also request the attestation record to be signed using an * individual attestation certificate by specifying the {@link #ID_TYPE_INDIVIDUAL_ATTESTATION} * flag (if supported by the device, see {@link #isUniqueDeviceAttestationSupported()}). * <p> * If any of {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and {@link #ID_TYPE_MEID} * is set, it is implicitly assumed that {@link #ID_TYPE_BASE_INFO} is also set. Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +49 −34 Original line number Diff line number Diff line Loading @@ -8636,39 +8636,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) { // If the caller is not a system app then it should only be able to check its own device // identifier access. int callingUid = mInjector.binderGetCallingUid(); int callingPid = mInjector.binderGetCallingPid(); if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID && (callingUid != uid || callingPid != pid)) { String message = String.format( "Calling uid %d, pid %d cannot check device identifier access for package %s " + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid); Log.w(LOG_TAG, message); throw new SecurityException(message); } ensureCallerIdentityMatchesIfNotSystem(packageName, pid, uid); // Verify that the specified packages matches the provided uid. int userId = UserHandle.getUserId(uid); try { ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(packageName, 0, userId); // Since this call goes directly to PackageManagerService a NameNotFoundException is not // thrown but null data can be returned; if the appInfo for the specified package cannot // be found then return false to prevent crashing the app. if (appInfo == null) { Log.w(LOG_TAG, String.format("appInfo could not be found for package %s", packageName)); return false; } else if (uid != appInfo.uid) { String message = String.format("Package %s (uid=%d) does not match provided uid %d", packageName, appInfo.uid, uid); Log.w(LOG_TAG, message); throw new SecurityException(message); } } catch (RemoteException e) { // If an exception is caught obtaining the appInfo just return false to prevent crashing // apps due to an internal error. Log.e(LOG_TAG, "Exception caught obtaining appInfo for package " + packageName, e); if (!doesPackageMatchUid(packageName, uid)) { return false; } // A device or profile owner must also have the READ_PHONE_STATE permission to access device Loading @@ -8684,9 +8655,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) { return true; } final int userId = UserHandle.getUserId(uid); // Allow access to the profile owner for the specified user, or delegate cert installer // But only if this is an organization-owned device. ComponentName profileOwner = getProfileOwnerAsUser(userId); if (profileOwner != null && (profileOwner.getPackageName().equals(packageName) if (profileOwner != null && canProfileOwnerAccessDeviceIds(userId) && (profileOwner.getPackageName().equals(packageName) || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) { return true; } Loading @@ -8696,6 +8670,47 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } private boolean doesPackageMatchUid(String packageName, int uid) { final int userId = UserHandle.getUserId(uid); try { ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(packageName, 0, userId); // Since this call goes directly to PackageManagerService a NameNotFoundException is not // thrown but null data can be returned; if the appInfo for the specified package cannot // be found then return false to prevent crashing the app. if (appInfo == null) { Log.w(LOG_TAG, String.format("appInfo could not be found for package %s", packageName)); return false; } else if (uid != appInfo.uid) { String message = String.format("Package %s (uid=%d) does not match provided uid %d", packageName, appInfo.uid, uid); Log.w(LOG_TAG, message); throw new SecurityException(message); } } catch (RemoteException e) { // If an exception is caught obtaining the appInfo just return false to prevent crashing // apps due to an internal error. Log.e(LOG_TAG, "Exception caught obtaining appInfo for package " + packageName, e); return false; } return true; } private void ensureCallerIdentityMatchesIfNotSystem(String packageName, int pid, int uid) { // If the caller is not a system app then it should only be able to check its own device // identifier access. int callingUid = mInjector.binderGetCallingUid(); int callingPid = mInjector.binderGetCallingPid(); if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID && (callingUid != uid || callingPid != pid)) { String message = String.format( "Calling uid %d, pid %d cannot check device identifier access for package %s " + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid); Log.w(LOG_TAG, message); throw new SecurityException(message); } } /** * Canonical name for a given package. */ Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +9 −8 Original line number Diff line number Diff line Loading @@ -5001,14 +5001,15 @@ public class DevicePolicyManager { * <p>Device owner, profile owner and their delegated certificate installer can use * {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device information * including manufacturer, model, brand, device and product in the attestation record. * Only device owner and their delegated certificate installer can use * {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and {@link #ID_TYPE_MEID} to request * unique device identifiers to be attested (the serial number, IMEI and MEID correspondingly), * if supported by the device (see {@link #isDeviceIdAttestationSupported()}). * Additionally, device owner and their delegated certificate installer can also request the * attestation record to be signed using an individual attestation certificate by specifying * the {@link #ID_TYPE_INDIVIDUAL_ATTESTATION} flag (if supported by the device, see * {@link #isUniqueDeviceAttestationSupported()}). * Only device owner, profile owner on an organization-owned device and their delegated * certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and * {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial number, * IMEI and MEID correspondingly), if supported by the device * (see {@link #isDeviceIdAttestationSupported()}). * Additionally, device owner, profile owner on an organization-owned device and their delegated * certificate installers can also request the attestation record to be signed using an * individual attestation certificate by specifying the {@link #ID_TYPE_INDIVIDUAL_ATTESTATION} * flag (if supported by the device, see {@link #isUniqueDeviceAttestationSupported()}). * <p> * If any of {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and {@link #ID_TYPE_MEID} * is set, it is implicitly assumed that {@link #ID_TYPE_BASE_INFO} is also set. Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +49 −34 Original line number Diff line number Diff line Loading @@ -8636,39 +8636,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) { // If the caller is not a system app then it should only be able to check its own device // identifier access. int callingUid = mInjector.binderGetCallingUid(); int callingPid = mInjector.binderGetCallingPid(); if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID && (callingUid != uid || callingPid != pid)) { String message = String.format( "Calling uid %d, pid %d cannot check device identifier access for package %s " + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid); Log.w(LOG_TAG, message); throw new SecurityException(message); } ensureCallerIdentityMatchesIfNotSystem(packageName, pid, uid); // Verify that the specified packages matches the provided uid. int userId = UserHandle.getUserId(uid); try { ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(packageName, 0, userId); // Since this call goes directly to PackageManagerService a NameNotFoundException is not // thrown but null data can be returned; if the appInfo for the specified package cannot // be found then return false to prevent crashing the app. if (appInfo == null) { Log.w(LOG_TAG, String.format("appInfo could not be found for package %s", packageName)); return false; } else if (uid != appInfo.uid) { String message = String.format("Package %s (uid=%d) does not match provided uid %d", packageName, appInfo.uid, uid); Log.w(LOG_TAG, message); throw new SecurityException(message); } } catch (RemoteException e) { // If an exception is caught obtaining the appInfo just return false to prevent crashing // apps due to an internal error. Log.e(LOG_TAG, "Exception caught obtaining appInfo for package " + packageName, e); if (!doesPackageMatchUid(packageName, uid)) { return false; } // A device or profile owner must also have the READ_PHONE_STATE permission to access device Loading @@ -8684,9 +8655,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) { return true; } final int userId = UserHandle.getUserId(uid); // Allow access to the profile owner for the specified user, or delegate cert installer // But only if this is an organization-owned device. ComponentName profileOwner = getProfileOwnerAsUser(userId); if (profileOwner != null && (profileOwner.getPackageName().equals(packageName) if (profileOwner != null && canProfileOwnerAccessDeviceIds(userId) && (profileOwner.getPackageName().equals(packageName) || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) { return true; } Loading @@ -8696,6 +8670,47 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } private boolean doesPackageMatchUid(String packageName, int uid) { final int userId = UserHandle.getUserId(uid); try { ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(packageName, 0, userId); // Since this call goes directly to PackageManagerService a NameNotFoundException is not // thrown but null data can be returned; if the appInfo for the specified package cannot // be found then return false to prevent crashing the app. if (appInfo == null) { Log.w(LOG_TAG, String.format("appInfo could not be found for package %s", packageName)); return false; } else if (uid != appInfo.uid) { String message = String.format("Package %s (uid=%d) does not match provided uid %d", packageName, appInfo.uid, uid); Log.w(LOG_TAG, message); throw new SecurityException(message); } } catch (RemoteException e) { // If an exception is caught obtaining the appInfo just return false to prevent crashing // apps due to an internal error. Log.e(LOG_TAG, "Exception caught obtaining appInfo for package " + packageName, e); return false; } return true; } private void ensureCallerIdentityMatchesIfNotSystem(String packageName, int pid, int uid) { // If the caller is not a system app then it should only be able to check its own device // identifier access. int callingUid = mInjector.binderGetCallingUid(); int callingPid = mInjector.binderGetCallingPid(); if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID && (callingUid != uid || callingPid != pid)) { String message = String.format( "Calling uid %d, pid %d cannot check device identifier access for package %s " + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid); Log.w(LOG_TAG, message); throw new SecurityException(message); } } /** * Canonical name for a given package. */ Loading