From fd0d0536f4ab4519f33c1ed0446d12551d6d729e Mon Sep 17 00:00:00 2001 From: Sergey Nikolaienkov Date: Thu, 30 Sep 2021 07:43:38 +0000 Subject: [PATCH] Validate device profiles in CdmService Make sure the device profiles CdmService receives from a companion application in an AssociationRequest are supported: null or android.app.role.COMPANION_DEVICE_WATCH. Bug: 201618687 Test: make Change-Id: I3139c8717b3e3ffe13492d2796a6093ad1146088 --- .../CompanionDeviceManagerService.java | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index e3b7fdd8ca7cb..7a38a02559c2b 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -145,6 +145,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.TimeZone; @@ -156,6 +157,15 @@ import java.util.function.Function; @SuppressLint("LongLogTag") public class CompanionDeviceManagerService extends SystemService implements Binder.DeathRecipient { + private static final Map DEVICE_PROFILE_TO_PERMISSION; + static { + final Map map = new ArrayMap<>(); + map.put(AssociationRequest.DEVICE_PROFILE_WATCH, + Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH); + + DEVICE_PROFILE_TO_PERMISSION = Collections.unmodifiableMap(map); + } + private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative( CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME, ".CompanionDeviceDiscoveryService"); @@ -429,7 +439,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind checkCallerIsSystemOr(callingPackage); int userId = getCallingUserId(); checkUsesFeature(callingPackage, userId); - checkProfilePermissions(request); + final String deviceProfile = request.getDeviceProfile(); + validateDeviceProfileAndCheckPermission(deviceProfile); mFindDeviceCallback = callback; mRequest = request; @@ -442,13 +453,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } callback.asBinder().linkToDeath(CompanionDeviceManagerService.this /* recipient */, 0); - AndroidFuture fetchProfileDescription = - request.getDeviceProfile() == null - ? AndroidFuture.completedFuture(null) - : getDeviceProfilePermissionDescription( - request.getDeviceProfile()); - - mOngoingDeviceDiscovery = fetchProfileDescription.thenComposeAsync(description -> { + mOngoingDeviceDiscovery = getDeviceProfilePermissionDescription(deviceProfile) + .thenComposeAsync(description -> { Slog.d(LOG_TAG, "fetchProfileDescription done: " + description); request.setDeviceProfilePrivilegesDescription(description); @@ -464,8 +470,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind }, FgThread.getExecutor()).whenComplete(uncheckExceptions((deviceAddress, err) -> { if (err == null) { Association association = new Association(userId, deviceAddress, callingPackage, - mRequest.getDeviceProfile(), false, - System.currentTimeMillis()); + deviceProfile, false, System.currentTimeMillis()); addAssociation(association, userId); } else { Slog.e(LOG_TAG, "Failed to discover device(s)", err); @@ -542,18 +547,18 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } } - private void checkProfilePermissions(AssociationRequest request) { - checkProfilePermission(request, - AssociationRequest.DEVICE_PROFILE_WATCH, - Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH); - } + private void validateDeviceProfileAndCheckPermission(@Nullable String deviceProfile) { + // Device profile can be null. + if (deviceProfile == null) return; - private void checkProfilePermission( - AssociationRequest request, String profile, String permission) { - if (profile.equals(request.getDeviceProfile()) - && getContext().checkCallingOrSelfPermission(permission) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Using " + profile + " requires " + permission); + if (!DEVICE_PROFILE_TO_PERMISSION.containsKey(deviceProfile)) { + throw new IllegalArgumentException("Unsupported device profile: " + deviceProfile); + } + + final String permission = DEVICE_PROFILE_TO_PERMISSION.get(deviceProfile); + if (getContext().checkCallingOrSelfPermission(permission) != PERMISSION_GRANTED) { + throw new SecurityException("Application must hold " + permission + " to associate " + + "with a device with " + deviceProfile + " profile."); } } @@ -1517,8 +1522,14 @@ public class CompanionDeviceManagerService extends SystemService implements Bind return result; } - private AndroidFuture getDeviceProfilePermissionDescription(String deviceProfile) { - AndroidFuture result = new AndroidFuture<>(); + @NonNull + private AndroidFuture getDeviceProfilePermissionDescription( + @Nullable String deviceProfile) { + if (deviceProfile == null) { + return AndroidFuture.completedFuture(null); + } + + final AndroidFuture result = new AndroidFuture<>(); mPermissionControllerManager.getPrivilegesDescriptionStringForProfile( deviceProfile, FgThread.getExecutor(), desc -> { try {