diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/permission/PermissionManagerService.java | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 81e8c2286755..241cea7a45a3 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -70,11 +70,16 @@ import android.app.ApplicationPackageManager; import android.app.IActivityManager; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; +import android.app.role.RoleManager; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.PermissionChecker; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.PermissionGroupInfoFlags; import android.content.pm.PackageManager.PermissionInfoFlags; @@ -84,6 +89,7 @@ import android.content.pm.PackageParser; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; +import android.content.pm.UserInfo; import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.permission.SplitPermissionInfoParcelable; @@ -177,6 +183,7 @@ import java.util.function.Consumer; */ public class PermissionManagerService extends IPermissionManager.Stub { private static final String TAG = "PackageManager"; + private static final String LOG_TAG = PermissionManagerService.class.getSimpleName(); private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60); @@ -420,6 +427,105 @@ public class PermissionManagerService extends IPermissionManager.Stub { new PermissionManagerServiceInternalImpl(); LocalServices.addService(PermissionManagerServiceInternal.class, localService); LocalServices.addService(PermissionManagerInternal.class, localService); + + context.getMainThreadHandler().post(() -> context.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (!Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { + return; + } + + try { + fixBgMicCamera(context); + } catch (Throwable t) { + // Don't crash the system if this fails for any reason. Any intermediate state + // this can leave the permissions in is okay and in the worst case the state is + // the same as before the user rebooted. + Log.e(LOG_TAG, "Unable to fix background permissions", t); + } + } + + + private void fixBgMicCamera(Context context) { + PackageManager pm = context.getPackageManager(); + for (UserInfo userInfo : context.getSystemService(UserManager.class).getUsers()) { + UserHandle user = userInfo.getUserHandle(); + List<String> assistants = context.getSystemService(RoleManager.class) + .getRoleHoldersAsUser(RoleManager.ROLE_ASSISTANT, user); + List<PackageInfo> packages = + pm.getInstalledPackagesAsUser(PackageManager.MATCH_SYSTEM_ONLY + | PackageManager.GET_PERMISSIONS, user.getIdentifier()); + for (PackageInfo packageInfo : packages) { + String[] requestedPermissions = packageInfo.requestedPermissions; + if (requestedPermissions == null) { + continue; + } + for (String permName : requestedPermissions) { + String pkg = packageInfo.packageName; + switch (permName) { + case Manifest.permission.BACKGROUND_CAMERA: + removeFromAllowlistsAndRevoke(pm, pkg, permName, user); + break; + case Manifest.permission.RECORD_BACKGROUND_AUDIO: + if (assistants.contains(pkg)) { + removeFromAllowlistsAndRevokeForAssistant(pm, pkg, permName, + user); + } else { + removeFromAllowlistsAndRevoke(pm, pkg, permName, user); + } + break; + } + } + } + } + } + + private void removeFromAllowlistsAndRevoke(PackageManager pm, String pkg, + String permName, UserHandle user) { + if ((pm.getPermissionFlags(permName, pkg, user) + & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0) { + Slog.i(LOG_TAG, "removing " + pkg + " " + permName + " from all allowlists"); + pm.removeWhitelistedRestrictedPermission(pkg, permName, + FLAG_PERMISSION_WHITELIST_UPGRADE); + pm.removeWhitelistedRestrictedPermission(pkg, permName, + FLAG_PERMISSION_WHITELIST_SYSTEM); + pm.removeWhitelistedRestrictedPermission(pkg, permName, + FLAG_PERMISSION_WHITELIST_INSTALLER); + pm.removeWhitelistedRestrictedPermission(pkg, permName, + FLAG_PERMISSION_ALLOWLIST_ROLE); + } + if (pm.checkPermission(permName, pkg) == PackageManager.PERMISSION_GRANTED) { + Slog.i(LOG_TAG, "revoking " + pkg + " " + permName); + pm.revokeRuntimePermission(pkg, permName, user); + } + } + + private void removeFromAllowlistsAndRevokeForAssistant(PackageManager pm, String pkg, + String permName, UserHandle user) { + int anyNonRoleExempt = + FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT + | FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT + | FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + + if ((pm.getPermissionFlags(permName, pkg, user) & anyNonRoleExempt) != 0) { + Slog.i(LOG_TAG, "removing " + pkg + " " + permName + + " from all allowlists except role"); + pm.removeWhitelistedRestrictedPermission(pkg, permName, + FLAG_PERMISSION_WHITELIST_UPGRADE); + pm.removeWhitelistedRestrictedPermission(pkg, permName, + FLAG_PERMISSION_WHITELIST_SYSTEM); + pm.removeWhitelistedRestrictedPermission(pkg, permName, + FLAG_PERMISSION_WHITELIST_INSTALLER); + } + if ((pm.getPermissionFlags(permName, pkg, user) + & FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT) == 0) { + Slog.i(LOG_TAG, "adding " + pkg + " " + permName + + " to role allowlist"); + pm.addWhitelistedRestrictedPermission(pkg, permName, + FLAG_PERMISSION_ALLOWLIST_ROLE); + } + } + }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED))); } @Override |