Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7081085d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "(P) Revoke permision when group changed" into pi-dev

parents 7091b5a8 fae8a528
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -8696,7 +8697,7 @@ public class PackageManagerService extends IPackageManager.Stub
                        }
                    }
                    // we're updating the disabled package, so, scan it as the package setting
                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, null,
                            disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
                            null /* originalPkgSetting */, null, parseFlags, scanFlags,
                            (pkg == mPlatformPackage), user);
@@ -9874,6 +9875,8 @@ public class PackageManagerService extends IPackageManager.Stub
    private static class ScanRequest {
        /** The parsed package */
        @NonNull public final PackageParser.Package pkg;
        /** The package this package replaces */
        @Nullable public final PackageParser.Package oldPkg;
        /** Shared user settings, if the package has a shared user */
        @Nullable public final SharedUserSetting sharedUserSetting;
        /**
@@ -9899,6 +9902,7 @@ public class PackageManagerService extends IPackageManager.Stub
        public ScanRequest(
                @NonNull PackageParser.Package pkg,
                @Nullable SharedUserSetting sharedUserSetting,
                @Nullable PackageParser.Package oldPkg,
                @Nullable PackageSetting pkgSetting,
                @Nullable PackageSetting disabledPkgSetting,
                @Nullable PackageSetting originalPkgSetting,
@@ -9908,6 +9912,7 @@ public class PackageManagerService extends IPackageManager.Stub
                boolean isPlatformPackage,
                @Nullable UserHandle user) {
            this.pkg = pkg;
            this.oldPkg = oldPkg;
            this.pkgSetting = pkgSetting;
            this.sharedUserSetting = sharedUserSetting;
            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
@@ -10037,8 +10042,9 @@ public class PackageManagerService extends IPackageManager.Stub
            boolean scanSucceeded = false;
            try {
                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting,
                        disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags,
                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
                        pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
                        originalPkgSetting, realPkgName, parseFlags, scanFlags,
                        (pkg == mPlatformPackage), user);
                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
                if (result.success) {
@@ -10068,6 +10074,7 @@ public class PackageManagerService extends IPackageManager.Stub
    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
            throws PackageManagerException {
        final PackageParser.Package pkg = request.pkg;
        final PackageParser.Package oldPkg = request.oldPkg;
        final @ParseFlags int parseFlags = request.parseFlags;
        final @ScanFlags int scanFlags = request.scanFlags;
        final PackageSetting oldPkgSetting = request.oldPkgSetting;
@@ -10237,7 +10244,7 @@ public class PackageManagerService extends IPackageManager.Stub
        } else {
            final int userId = user == null ? 0 : user.getIdentifier();
            // Modify state for the given package setting
            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
            commitPackageSettings(pkg, oldPkg, pkgSetting, user, scanFlags,
                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
            if (pkgSetting.getInstantApp(userId)) {
                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
@@ -11163,8 +11170,9 @@ public class PackageManagerService extends IPackageManager.Stub
     * Adds a scanned package to the system. When this method is finished, the package will
     * be available for query, resolution, etc...
     */
    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
            UserHandle user, final @ScanFlags int scanFlags, boolean chatty) {
    private void commitPackageSettings(PackageParser.Package pkg,
            @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting, UserHandle user,
            final @ScanFlags int scanFlags, boolean chatty) {
        final String pkgName = pkg.packageName;
        if (mCustomResolverComponentName != null &&
                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
@@ -11504,6 +11512,22 @@ public class PackageManagerService extends IPackageManager.Stub
                    }
                }
            }
            if (oldPkg != null) {
                // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
                // revoke callbacks from this method might need to kill apps which need the
                // mPackages lock on a different thread. This would dead lock.
                //
                // Hence create a copy of all package names and pass it into
                // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
                // revoked. If a new package is added before the async code runs the permission
                // won't be granted yet, hence new packages are no problem.
                final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
                AsyncTask.execute(() ->
                        mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
                                allPackageNames, mPermissionCallback));
            }
        }
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+17 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.PackageParser.Permission;
import com.android.server.pm.SharedUserSetting;
import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -90,6 +91,22 @@ public abstract class PermissionManagerInternal {
    public abstract void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
            @NonNull Collection<PackageParser.Package> allPacakges, PermissionCallback callback);

    /**
     * We might auto-grant permissions if any permission of the group is already granted. Hence if
     * the group of a granted permission changes we need to revoke it to avoid having permissions of
     * the new group auto-granted.
     *
     * @param newPackage The new package that was installed
     * @param oldPackage The old package that was updated
     * @param allPackageNames All packages
     * @param permissionCallback Callback for permission changed
     */
    public abstract void revokeRuntimePermissionsIfGroupChanged(
            @NonNull PackageParser.Package newPackage,
            @NonNull PackageParser.Package oldPackage,
            @NonNull ArrayList<String> allPackageNames,
            @NonNull PermissionCallback permissionCallback);

    /**
     * Add all permissions in the given package.
     * <p>
+86 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.os.storage.StorageManagerInternal;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -391,6 +392,82 @@ public class PermissionManagerService {
        return protectionLevel;
    }

    /**
     * We might auto-grant permissions if any permission of the group is already granted. Hence if
     * the group of a granted permission changes we need to revoke it to avoid having permissions of
     * the new group auto-granted.
     *
     * @param newPackage The new package that was installed
     * @param oldPackage The old package that was updated
     * @param allPackageNames All package names
     * @param permissionCallback Callback for permission changed
     */
    private void revokeRuntimePermissionsIfGroupChanged(
            @NonNull PackageParser.Package newPackage,
            @NonNull PackageParser.Package oldPackage,
            @NonNull ArrayList<String> allPackageNames,
            @NonNull PermissionCallback permissionCallback) {
        final int numOldPackagePermissions = oldPackage.permissions.size();
        final ArrayMap<String, String> oldPermissionNameToGroupName
                = new ArrayMap<>(numOldPackagePermissions);

        for (int i = 0; i < numOldPackagePermissions; i++) {
            final PackageParser.Permission permission = oldPackage.permissions.get(i);

            if (permission.group != null) {
                oldPermissionNameToGroupName.put(permission.info.name,
                        permission.group.info.name);
            }
        }

        final int numNewPackagePermissions = newPackage.permissions.size();
        for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
                newPermissionNum++) {
            final PackageParser.Permission newPermission =
                    newPackage.permissions.get(newPermissionNum);
            final int newProtection = newPermission.info.getProtection();

            if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
                final String permissionName = newPermission.info.name;
                final String newPermissionGroupName =
                        newPermission.group == null ? null : newPermission.group.info.name;
                final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
                        permissionName);

                if (newPermissionGroupName != null
                        && !newPermissionGroupName.equals(oldPermissionGroupName)) {
                    final int[] userIds = mUserManagerInt.getUserIds();
                    final int numUserIds = userIds.length;
                    for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
                        final int userId = userIds[userIdNum];

                        final int numPackages = allPackageNames.size();
                        for (int packageNum = 0; packageNum < numPackages; packageNum++) {
                            final String packageName = allPackageNames.get(packageNum);

                            if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
                                    userId) == PackageManager.PERMISSION_GRANTED) {
                                EventLog.writeEvent(0x534e4554, "72710897",
                                        newPackage.applicationInfo.uid,
                                        "Revoking permission", permissionName, "from package",
                                        packageName, "as the group changed from",
                                        oldPermissionGroupName, "to", newPermissionGroupName);

                                try {
                                    revokeRuntimePermission(permissionName, packageName, false,
                                            Process.SYSTEM_UID, userId, permissionCallback);
                                } catch (IllegalArgumentException e) {
                                    Slog.e(TAG, "Could not revoke " + permissionName + " from "
                                            + packageName, e);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
        final int N = pkg.permissions.size();
        for (int i=0; i<N; i++) {
@@ -1968,6 +2045,15 @@ public class PermissionManagerService {
            return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
        }
        @Override
        public void revokeRuntimePermissionsIfGroupChanged(
                @NonNull PackageParser.Package newPackage,
                @NonNull PackageParser.Package oldPackage,
                @NonNull ArrayList<String> allPackageNames,
                @NonNull PermissionCallback permissionCallback) {
            PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
                    oldPackage, allPackageNames, permissionCallback);
        }
        @Override
        public void addAllPermissions(Package pkg, boolean chatty) {
            PermissionManagerService.this.addAllPermissions(pkg, chatty);
        }