Loading services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java +2 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import static com.android.internal.util.CollectionUtils.filter; import static com.android.internal.util.FunctionalUtils.uncheckExceptions; import static com.android.server.companion.CompanionDeviceManagerService.DEBUG; import static com.android.server.companion.CompanionDeviceManagerService.LOG_TAG; import static com.android.server.companion.PermissionsUtils.enforceCallerPermissionsToRequest; import static com.android.server.companion.PermissionsUtils.enforcePermissionsForAssociation; import static com.android.server.companion.RolesUtils.isRoleHolder; import static java.util.Objects.requireNonNull; Loading Loading @@ -110,7 +110,7 @@ class AssociationRequestsProcessor { } // 1. Enforce permissions and other requirements. enforceCallerPermissionsToRequest(mContext, request, packageName, userId); enforcePermissionsForAssociation(mContext, request, packageName, userId); mService.checkUsesFeature(packageName, userId); // 2. Check if association can be created without launching UI (i.e. CDM needs NEITHER Loading services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +10 −8 Original line number Diff line number Diff line Loading @@ -39,7 +39,8 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainRunna import static com.android.server.companion.PermissionsUtils.checkCallerCanManageAssociationsForPackage; import static com.android.server.companion.PermissionsUtils.checkCallerCanManageCompanionDevice; import static com.android.server.companion.PermissionsUtils.enforceCallerCanInteractWithUserId; import static com.android.server.companion.PermissionsUtils.enforceCallerCanManagerCompanionDevice; import static com.android.server.companion.PermissionsUtils.enforceCallerCanManageAssociationsForPackage; import static com.android.server.companion.PermissionsUtils.enforceCallerCanManageCompanionDevice; import static com.android.server.companion.PermissionsUtils.enforceCallerIsSystemOr; import static com.android.server.companion.RolesUtils.addRoleHolderForAssociation; import static com.android.server.companion.RolesUtils.removeRoleHolderForAssociation; Loading Loading @@ -401,15 +402,16 @@ public class CompanionDeviceManagerService extends SystemService { Slog.i(LOG_TAG, "associate() " + "request=" + request + ", " + "package=u" + userId + "/" + packageName); enforceCallerCanManageAssociationsForPackage(getContext(), userId, packageName, "create associations"); mAssociationRequestsProcessor.process(request, packageName, userId, callback); } @Override public List<AssociationInfo> getAssociations(String packageName, int userId) { if (!checkCallerCanManageAssociationsForPackage(getContext(), userId, packageName)) { throw new SecurityException("Caller (uid=" + getCallingUid() + ") does not have " + "permissions to get associations for u" + userId + "/" + packageName); } enforceCallerCanManageAssociationsForPackage(getContext(), userId, packageName, "get associations"); if (!checkCallerCanManageCompanionDevice(getContext())) { // If the caller neither is system nor holds MANAGE_COMPANION_DEVICES: it needs to Loading @@ -424,7 +426,7 @@ public class CompanionDeviceManagerService extends SystemService { @Override public List<AssociationInfo> getAllAssociationsForUser(int userId) throws RemoteException { enforceCallerCanInteractWithUserId(getContext(), userId); enforceCallerCanManagerCompanionDevice(getContext(), "getAllAssociationsForUser"); enforceCallerCanManageCompanionDevice(getContext(), "getAllAssociationsForUser"); return new ArrayList<>( CompanionDeviceManagerService.this.getAllAssociationsForUser(userId)); Loading @@ -434,7 +436,7 @@ public class CompanionDeviceManagerService extends SystemService { public void addOnAssociationsChangedListener(IOnAssociationsChangedListener listener, int userId) { enforceCallerCanInteractWithUserId(getContext(), userId); enforceCallerCanManagerCompanionDevice(getContext(), enforceCallerCanManageCompanionDevice(getContext(), "addOnAssociationsChangedListener"); //TODO: Implement. Loading Loading @@ -621,7 +623,7 @@ public class CompanionDeviceManagerService extends SystemService { public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException { enforceCallerCanManagerCompanionDevice(getContext(), "onShellCommand"); enforceCallerCanManageCompanionDevice(getContext(), "onShellCommand"); new CompanionDeviceShellCommand(CompanionDeviceManagerService.this) .exec(this, in, out, err, args, callback, resultReceiver); } Loading services/companion/java/com/android/server/companion/PermissionsUtils.java +39 −11 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING; import static android.companion.AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION; import static android.companion.AssociationRequest.DEVICE_PROFILE_WATCH; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Binder.getCallingPid; import static android.os.Binder.getCallingUid; import static android.os.Process.SYSTEM_UID; import static android.os.UserHandle.getCallingUserId; Loading @@ -37,11 +38,13 @@ import android.annotation.UserIdInt; import android.companion.AssociationRequest; import android.companion.CompanionDeviceManager; import android.content.Context; import android.content.pm.PackageManagerInternal; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import com.android.internal.app.IAppOpsService; import com.android.server.LocalServices; import java.util.Map; Loading @@ -65,21 +68,19 @@ final class PermissionsUtils { DEVICE_PROFILE_TO_PERMISSION = unmodifiableMap(map); } static void enforceCallerPermissionsToRequest(@NonNull Context context, static void enforcePermissionsForAssociation(@NonNull Context context, @NonNull AssociationRequest request, @NonNull String packageName, @UserIdInt int userId) { enforceCallerCanInteractWithUserId(context, userId); enforceCallerIsSystemOr(userId, packageName); enforceRequestDeviceProfilePermissions(context, request.getDeviceProfile()); final int packageUid = getPackageUid(userId, packageName); enforceRequestDeviceProfilePermissions(context, request.getDeviceProfile(), packageUid); if (request.isSelfManaged()) { enforceRequestSelfManagedPermission(context); enforceRequestSelfManagedPermission(context, packageUid); } } static void enforceRequestDeviceProfilePermissions( @NonNull Context context, @Nullable String deviceProfile) { @NonNull Context context, @Nullable String deviceProfile, int packageUid) { // Device profile can be null. if (deviceProfile == null) return; Loading @@ -100,14 +101,15 @@ final class PermissionsUtils { } final String permission = DEVICE_PROFILE_TO_PERMISSION.get(deviceProfile); if (context.checkCallingOrSelfPermission(permission) != PERMISSION_GRANTED) { if (context.checkPermission(permission, getCallingPid(), packageUid) != PERMISSION_GRANTED) { throw new SecurityException("Application must hold " + permission + " to associate " + "with a device with " + deviceProfile + " profile."); } } static void enforceRequestSelfManagedPermission(@NonNull Context context) { if (context.checkCallingOrSelfPermission(REQUEST_COMPANION_SELF_MANAGED) static void enforceRequestSelfManagedPermission(@NonNull Context context, int packageUid) { if (context.checkPermission(REQUEST_COMPANION_SELF_MANAGED, getCallingPid(), packageUid) != PERMISSION_GRANTED) { throw new SecurityException("Application does not hold " + REQUEST_COMPANION_SELF_MANAGED); Loading Loading @@ -159,13 +161,34 @@ final class PermissionsUtils { return context.checkCallingPermission(MANAGE_COMPANION_DEVICES) == PERMISSION_GRANTED; } static void enforceCallerCanManagerCompanionDevice(@NonNull Context context, static void enforceCallerCanManageCompanionDevice(@NonNull Context context, @Nullable String message) { if (getCallingUid() == SYSTEM_UID) return; context.enforceCallingPermission(MANAGE_COMPANION_DEVICES, message); } static void enforceCallerCanManageAssociationsForPackage(@NonNull Context context, @UserIdInt int userId, @NonNull String packageName, @Nullable String actionDescription) { if (checkCallerCanManageAssociationsForPackage(context, userId, packageName)) return; throw new SecurityException("Caller (uid=" + getCallingUid() + ") does not have " + "permissions to " + (actionDescription != null ? actionDescription : "manage associations") + " for u" + userId + "/" + packageName); } /** * Check if the caller is either: * <ul> * <li> the package itself * <li> the System ({@link android.os.Process#SYSTEM_UID}) * <li> holds {@link Manifest.permission#MANAGE_COMPANION_DEVICES} and, if belongs to a * different user, also holds {@link Manifest.permission#INTERACT_ACROSS_USERS}. * </ul> * @return whether the caller is one of the above. */ static boolean checkCallerCanManageAssociationsForPackage(@NonNull Context context, @UserIdInt int userId, @NonNull String packageName) { if (checkCallerIsSystemOr(userId, packageName)) return true; Loading @@ -184,6 +207,11 @@ final class PermissionsUtils { } } private static int getPackageUid(@UserIdInt int userId, @NonNull String packageName) { return LocalServices.getService(PackageManagerInternal.class) .getPackageUid(packageName, 0, userId); } private static IAppOpsService getAppOpsService() { if (sAppOpsService == null) { synchronized (PermissionsUtils.class) { Loading Loading
services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java +2 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import static com.android.internal.util.CollectionUtils.filter; import static com.android.internal.util.FunctionalUtils.uncheckExceptions; import static com.android.server.companion.CompanionDeviceManagerService.DEBUG; import static com.android.server.companion.CompanionDeviceManagerService.LOG_TAG; import static com.android.server.companion.PermissionsUtils.enforceCallerPermissionsToRequest; import static com.android.server.companion.PermissionsUtils.enforcePermissionsForAssociation; import static com.android.server.companion.RolesUtils.isRoleHolder; import static java.util.Objects.requireNonNull; Loading Loading @@ -110,7 +110,7 @@ class AssociationRequestsProcessor { } // 1. Enforce permissions and other requirements. enforceCallerPermissionsToRequest(mContext, request, packageName, userId); enforcePermissionsForAssociation(mContext, request, packageName, userId); mService.checkUsesFeature(packageName, userId); // 2. Check if association can be created without launching UI (i.e. CDM needs NEITHER Loading
services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +10 −8 Original line number Diff line number Diff line Loading @@ -39,7 +39,8 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainRunna import static com.android.server.companion.PermissionsUtils.checkCallerCanManageAssociationsForPackage; import static com.android.server.companion.PermissionsUtils.checkCallerCanManageCompanionDevice; import static com.android.server.companion.PermissionsUtils.enforceCallerCanInteractWithUserId; import static com.android.server.companion.PermissionsUtils.enforceCallerCanManagerCompanionDevice; import static com.android.server.companion.PermissionsUtils.enforceCallerCanManageAssociationsForPackage; import static com.android.server.companion.PermissionsUtils.enforceCallerCanManageCompanionDevice; import static com.android.server.companion.PermissionsUtils.enforceCallerIsSystemOr; import static com.android.server.companion.RolesUtils.addRoleHolderForAssociation; import static com.android.server.companion.RolesUtils.removeRoleHolderForAssociation; Loading Loading @@ -401,15 +402,16 @@ public class CompanionDeviceManagerService extends SystemService { Slog.i(LOG_TAG, "associate() " + "request=" + request + ", " + "package=u" + userId + "/" + packageName); enforceCallerCanManageAssociationsForPackage(getContext(), userId, packageName, "create associations"); mAssociationRequestsProcessor.process(request, packageName, userId, callback); } @Override public List<AssociationInfo> getAssociations(String packageName, int userId) { if (!checkCallerCanManageAssociationsForPackage(getContext(), userId, packageName)) { throw new SecurityException("Caller (uid=" + getCallingUid() + ") does not have " + "permissions to get associations for u" + userId + "/" + packageName); } enforceCallerCanManageAssociationsForPackage(getContext(), userId, packageName, "get associations"); if (!checkCallerCanManageCompanionDevice(getContext())) { // If the caller neither is system nor holds MANAGE_COMPANION_DEVICES: it needs to Loading @@ -424,7 +426,7 @@ public class CompanionDeviceManagerService extends SystemService { @Override public List<AssociationInfo> getAllAssociationsForUser(int userId) throws RemoteException { enforceCallerCanInteractWithUserId(getContext(), userId); enforceCallerCanManagerCompanionDevice(getContext(), "getAllAssociationsForUser"); enforceCallerCanManageCompanionDevice(getContext(), "getAllAssociationsForUser"); return new ArrayList<>( CompanionDeviceManagerService.this.getAllAssociationsForUser(userId)); Loading @@ -434,7 +436,7 @@ public class CompanionDeviceManagerService extends SystemService { public void addOnAssociationsChangedListener(IOnAssociationsChangedListener listener, int userId) { enforceCallerCanInteractWithUserId(getContext(), userId); enforceCallerCanManagerCompanionDevice(getContext(), enforceCallerCanManageCompanionDevice(getContext(), "addOnAssociationsChangedListener"); //TODO: Implement. Loading Loading @@ -621,7 +623,7 @@ public class CompanionDeviceManagerService extends SystemService { public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException { enforceCallerCanManagerCompanionDevice(getContext(), "onShellCommand"); enforceCallerCanManageCompanionDevice(getContext(), "onShellCommand"); new CompanionDeviceShellCommand(CompanionDeviceManagerService.this) .exec(this, in, out, err, args, callback, resultReceiver); } Loading
services/companion/java/com/android/server/companion/PermissionsUtils.java +39 −11 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING; import static android.companion.AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION; import static android.companion.AssociationRequest.DEVICE_PROFILE_WATCH; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Binder.getCallingPid; import static android.os.Binder.getCallingUid; import static android.os.Process.SYSTEM_UID; import static android.os.UserHandle.getCallingUserId; Loading @@ -37,11 +38,13 @@ import android.annotation.UserIdInt; import android.companion.AssociationRequest; import android.companion.CompanionDeviceManager; import android.content.Context; import android.content.pm.PackageManagerInternal; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import com.android.internal.app.IAppOpsService; import com.android.server.LocalServices; import java.util.Map; Loading @@ -65,21 +68,19 @@ final class PermissionsUtils { DEVICE_PROFILE_TO_PERMISSION = unmodifiableMap(map); } static void enforceCallerPermissionsToRequest(@NonNull Context context, static void enforcePermissionsForAssociation(@NonNull Context context, @NonNull AssociationRequest request, @NonNull String packageName, @UserIdInt int userId) { enforceCallerCanInteractWithUserId(context, userId); enforceCallerIsSystemOr(userId, packageName); enforceRequestDeviceProfilePermissions(context, request.getDeviceProfile()); final int packageUid = getPackageUid(userId, packageName); enforceRequestDeviceProfilePermissions(context, request.getDeviceProfile(), packageUid); if (request.isSelfManaged()) { enforceRequestSelfManagedPermission(context); enforceRequestSelfManagedPermission(context, packageUid); } } static void enforceRequestDeviceProfilePermissions( @NonNull Context context, @Nullable String deviceProfile) { @NonNull Context context, @Nullable String deviceProfile, int packageUid) { // Device profile can be null. if (deviceProfile == null) return; Loading @@ -100,14 +101,15 @@ final class PermissionsUtils { } final String permission = DEVICE_PROFILE_TO_PERMISSION.get(deviceProfile); if (context.checkCallingOrSelfPermission(permission) != PERMISSION_GRANTED) { if (context.checkPermission(permission, getCallingPid(), packageUid) != PERMISSION_GRANTED) { throw new SecurityException("Application must hold " + permission + " to associate " + "with a device with " + deviceProfile + " profile."); } } static void enforceRequestSelfManagedPermission(@NonNull Context context) { if (context.checkCallingOrSelfPermission(REQUEST_COMPANION_SELF_MANAGED) static void enforceRequestSelfManagedPermission(@NonNull Context context, int packageUid) { if (context.checkPermission(REQUEST_COMPANION_SELF_MANAGED, getCallingPid(), packageUid) != PERMISSION_GRANTED) { throw new SecurityException("Application does not hold " + REQUEST_COMPANION_SELF_MANAGED); Loading Loading @@ -159,13 +161,34 @@ final class PermissionsUtils { return context.checkCallingPermission(MANAGE_COMPANION_DEVICES) == PERMISSION_GRANTED; } static void enforceCallerCanManagerCompanionDevice(@NonNull Context context, static void enforceCallerCanManageCompanionDevice(@NonNull Context context, @Nullable String message) { if (getCallingUid() == SYSTEM_UID) return; context.enforceCallingPermission(MANAGE_COMPANION_DEVICES, message); } static void enforceCallerCanManageAssociationsForPackage(@NonNull Context context, @UserIdInt int userId, @NonNull String packageName, @Nullable String actionDescription) { if (checkCallerCanManageAssociationsForPackage(context, userId, packageName)) return; throw new SecurityException("Caller (uid=" + getCallingUid() + ") does not have " + "permissions to " + (actionDescription != null ? actionDescription : "manage associations") + " for u" + userId + "/" + packageName); } /** * Check if the caller is either: * <ul> * <li> the package itself * <li> the System ({@link android.os.Process#SYSTEM_UID}) * <li> holds {@link Manifest.permission#MANAGE_COMPANION_DEVICES} and, if belongs to a * different user, also holds {@link Manifest.permission#INTERACT_ACROSS_USERS}. * </ul> * @return whether the caller is one of the above. */ static boolean checkCallerCanManageAssociationsForPackage(@NonNull Context context, @UserIdInt int userId, @NonNull String packageName) { if (checkCallerIsSystemOr(userId, packageName)) return true; Loading @@ -184,6 +207,11 @@ final class PermissionsUtils { } } private static int getPackageUid(@UserIdInt int userId, @NonNull String packageName) { return LocalServices.getService(PackageManagerInternal.class) .getPackageUid(packageName, 0, userId); } private static IAppOpsService getAppOpsService() { if (sAppOpsService == null) { synchronized (PermissionsUtils.class) { Loading