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

Commit edc84ee8 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Selective enforcement of READ_EXTERNAL_STORAGE.

Store enforcement state of specific permissions, allowing them to be
selectively enforced. Currently supports READ_EXTERNAL_STORAGE, which
by default isn't enforced, but enforcement can be enabled at runtime.

Bug: 6131916
Change-Id: I4bcc215a2eb5e6507d6257b577311cbd13c77acf
parent 80a6b33b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -370,4 +370,7 @@ interface IPackageManager {
    boolean isFirstBoot();

    List<UserInfo> getUsers();

    void setPermissionEnforcement(String permission, int enforcement);
    int getPermissionEnforcement(String permission);
}
+5 −0
Original line number Diff line number Diff line
@@ -1090,6 +1090,11 @@ public abstract class PackageManager {
    public static final String EXTRA_VERIFICATION_INSTALL_FLAGS
            = "android.content.pm.extra.VERIFICATION_INSTALL_FLAGS";

    /** {@hide} */
    public static final int ENFORCEMENT_DEFAULT = 0;
    /** {@hide} */
    public static final int ENFORCEMENT_YES = 1;

    /**
     * Retrieve overall information about an application package that is
     * installed on the system.
+50 −0
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.ENFORCEMENT_DEFAULT;
import static android.content.pm.PackageManager.ENFORCEMENT_YES;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
import static libcore.io.OsConstants.S_ISLNK;

import com.android.internal.app.IMediaContainerService;
@@ -1872,6 +1876,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                    return PackageManager.PERMISSION_GRANTED;
                }
            }
            if (!isPermissionEnforcedLocked(permName)) {
                return PackageManager.PERMISSION_GRANTED;
            }
        }
        return PackageManager.PERMISSION_DENIED;
    }
@@ -1890,6 +1897,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                    return PackageManager.PERMISSION_GRANTED;
                }
            }
            if (!isPermissionEnforcedLocked(permName)) {
                return PackageManager.PERMISSION_GRANTED;
            }
        }
        return PackageManager.PERMISSION_DENIED;
    }
@@ -8835,4 +8845,44 @@ public class PackageManagerService extends IPackageManager.Stub {
    public List<UserInfo> getUsers() {
        return mUserManager.getUsers();
    }

    @Override
    public void setPermissionEnforcement(String permission, int enforcement) {
        mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
        if (READ_EXTERNAL_STORAGE.equals(permission)) {
            synchronized (mPackages) {
                if (mSettings.mReadExternalStorageEnforcement != enforcement) {
                    mSettings.mReadExternalStorageEnforcement = enforcement;
                    mSettings.writeLPr();
                }
            }
        } else {
            throw new IllegalArgumentException("No selective enforcement for " + permission);
        }
    }

    @Override
    public int getPermissionEnforcement(String permission) {
        mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
        if (READ_EXTERNAL_STORAGE.equals(permission)) {
            synchronized (mPackages) {
                return mSettings.mReadExternalStorageEnforcement;
            }
        } else {
            throw new IllegalArgumentException("No selective enforcement for " + permission);
        }
    }

    private boolean isPermissionEnforcedLocked(String permission) {
        if (READ_EXTERNAL_STORAGE.equals(permission)) {
            switch (mSettings.mReadExternalStorageEnforcement) {
                case ENFORCEMENT_DEFAULT:
                    return false;
                case ENFORCEMENT_YES:
                    return true;
            }
        }

        return true;
    }
}
+20 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.ENFORCEMENT_DEFAULT;

import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
@@ -74,6 +75,9 @@ final class Settings {

    private static final boolean DEBUG_STOPPED = false;

    private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage";
    private static final String ATTR_ENFORCEMENT = "enforcement";

    private final File mSettingsFilename;
    private final File mBackupSettingsFilename;
    private final File mPackageListFilename;
@@ -91,6 +95,8 @@ final class Settings {
    int mInternalSdkPlatform;
    int mExternalSdkPlatform;

    int mReadExternalStorageEnforcement = ENFORCEMENT_DEFAULT;

    /** Device identity for the purpose of package verification. */
    private VerifierDeviceIdentity mVerifierDeviceIdentity;

@@ -871,6 +877,13 @@ final class Settings {
                serializer.endTag(null, "verifier");
            }

            if (mReadExternalStorageEnforcement != ENFORCEMENT_DEFAULT) {
                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
                serializer.attribute(
                        null, ATTR_ENFORCEMENT, Integer.toString(mReadExternalStorageEnforcement));
                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
            }

            serializer.startTag(null, "permission-trees");
            for (BasePermission bp : mPermissionTrees.values()) {
                writePermissionLPr(serializer, bp);
@@ -1291,6 +1304,12 @@ final class Settings {
                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
                                + e.getMessage());
                    }
                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
                    try {
                        mReadExternalStorageEnforcement = Integer.parseInt(enforcement);
                    } catch (NumberFormatException e) {
                    }
                } else {
                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
                            + parser.getName());