From 5a15b55107651968312f39a830ddb26909b9d362 Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Tue, 18 Dec 2018 10:40:04 -0800 Subject: [PATCH] Added a new "incidentReportApprover" permission protection flag. This gives the ONE app installed on the system the permission to authorize the sharing of incident and bug reports with an app. Currently that app is PermissionController. Package Manager enforces that there is only one installed, and refused to boot if that isn't the case. Bug: 123543706 Test: bit GooglePermissionControllerTest:* Change-Id: I76a7fad0ea36359bbb0ff09669df46202d059dab --- api/system-current.txt | 3 +++ api/test-current.txt | 3 +++ .../android/app/ApplicationPackageManager.java | 9 +++++++++ core/java/android/content/pm/IPackageManager.aidl | 2 ++ core/java/android/content/pm/PackageManager.java | 13 +++++++++++++ .../android/content/pm/PackageManagerInternal.java | 2 ++ core/java/android/content/pm/PermissionInfo.java | 14 ++++++++++++++ core/res/AndroidManifest.xml | 10 ++++++++++ core/res/res/values/attrs_manifest.xml | 3 +++ core/res/res/values/config.xml | 7 +++++++ core/res/res/values/symbols.xml | 2 ++ data/etc/privapp-permissions-platform.xml | 1 + .../android/server/pm/PackageManagerService.java | 8 ++++++++ .../server/pm/permission/BasePermission.java | 3 +++ .../pm/permission/PermissionManagerService.java | 8 ++++++++ .../backup/testutils/IPackageManagerStub.java | 4 ++++ 16 files changed, 92 insertions(+) diff --git a/api/system-current.txt b/api/system-current.txt index da3b7f4239ed4..7214eb7112ab3 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -18,6 +18,7 @@ package android { field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE"; field public static final String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"; field public static final String AMBIENT_WALLPAPER = "android.permission.AMBIENT_WALLPAPER"; + field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS"; field public static final String BACKUP = "android.permission.BACKUP"; field public static final String BIND_ATTENTION_SERVICE = "android.permission.BIND_ATTENTION_SERVICE"; field public static final String BIND_AUGMENTED_AUTOFILL_SERVICE = "android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE"; @@ -1489,6 +1490,7 @@ package android.content.pm { method @NonNull public android.content.pm.dex.ArtManager getArtManager(); method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int); method @Nullable @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public CharSequence getHarmfulAppWarning(@NonNull String); + method public String getIncidentReportApproverPackageName(); method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract java.util.List getInstalledPackagesAsUser(int, int); method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_INSTANT_APPS) public abstract android.graphics.drawable.Drawable getInstantAppIcon(String); method public abstract android.content.ComponentName getInstantAppInstallerComponent(); @@ -1610,6 +1612,7 @@ package android.content.pm { field public static final int FLAG_REMOVED = 2; // 0x2 field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000 field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 + field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000 diff --git a/api/test-current.txt b/api/test-current.txt index 9c27535664fe4..2d654846aef02 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -4,6 +4,7 @@ package android { public static final class Manifest.permission { field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; + field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS"; field public static final String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE"; field public static final String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE"; field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA"; @@ -413,6 +414,7 @@ package android.content.pm { public abstract class PackageManager { method public abstract boolean arePermissionsIndividuallyControlled(); method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int); + method public String getIncidentReportApproverPackageName(); method public abstract int getInstallReason(String, @NonNull android.os.UserHandle); method public abstract java.util.List getInstalledApplicationsAsUser(int, int); method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List getInstalledPackagesAsUser(int, int); @@ -434,6 +436,7 @@ package android.content.pm { public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000 field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 + field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000 diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 4491b95f968a9..a937422733066 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -3025,6 +3025,15 @@ public class ApplicationPackageManager extends PackageManager { } } + @Override + public String getIncidentReportApproverPackageName() { + try { + return mPM.getIncidentReportApproverPackageName(); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + @Override public boolean isPackageStateProtected(String packageName, int userId) { try { diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 7bd8c4e244c71..a6a6f013839ae 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -688,6 +688,8 @@ interface IPackageManager { String getContentCaptureServicePackageName(); + String getIncidentReportApproverPackageName(); + boolean isPackageStateProtected(String packageName, int userId); void sendDeviceCustomizationReadyBroadcast(); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 0aa33c89f2de3..3a675c901a9f3 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -6743,6 +6743,19 @@ public abstract class PackageManager { "getContentCaptureServicePackageName not implemented in subclass"); } + /** + * @return the incident report approver app package name, or null if it's not defined + * by the OEM. + * + * @hide + */ + @SystemApi + @TestApi + public String getIncidentReportApproverPackageName() { + throw new UnsupportedOperationException( + "getIncidentReportApproverPackageName not implemented in subclass"); + } + /** * @return whether a given package's state is protected, e.g. package cannot be disabled, * suspended, hidden or force stopped. diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index c9a4c82703906..738730ec3f516 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -56,6 +56,7 @@ public abstract class PackageManagerInternal { public static final int PACKAGE_WELLBEING = 7; public static final int PACKAGE_DOCUMENTER = 8; public static final int PACKAGE_CONFIGURATOR = 9; + public static final int PACKAGE_INCIDENT_REPORT_APPROVER = 10; @IntDef(value = { PACKAGE_SYSTEM, PACKAGE_SETUP_WIZARD, @@ -67,6 +68,7 @@ public abstract class PackageManagerInternal { PACKAGE_WELLBEING, PACKAGE_DOCUMENTER, PACKAGE_CONFIGURATOR, + PACKAGE_INCIDENT_REPORT_APPROVER, }) @Retention(RetentionPolicy.SOURCE) public @interface KnownPackage {} diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 5d2cf0a7d101e..e7769849ccc3f 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -213,6 +213,16 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { @TestApi public static final int PROTECTION_FLAG_CONFIGURATOR = 0x80000; + /** + * Additional flag for {${link #protectionLevel}, corresponding + * to the incident_report_approver value of + * {@link android.R.attr#protectionLevel}. + * + * @hide + */ + @SystemApi + @TestApi + public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 0x100000; /** @hide */ @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { @@ -233,6 +243,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { PROTECTION_FLAG_WELLBEING, PROTECTION_FLAG_DOCUMENTER, PROTECTION_FLAG_CONFIGURATOR, + PROTECTION_FLAG_INCIDENT_REPORT_APPROVER, }) @Retention(RetentionPolicy.SOURCE) public @interface ProtectionFlags {} @@ -431,6 +442,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level & PROTECTION_FLAG_CONFIGURATOR) != 0) { protLevel += "|configurator"; } + if ((level & PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER) != 0) { + protLevel += "|incidentReportApprover"; + } return protLevel; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 7184c7a43da75..14143d857a580 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -115,6 +115,7 @@ + @@ -2798,6 +2799,15 @@ + + + diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index de6468dbb72a4..0abe456c82f92 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -277,6 +277,9 @@ + + diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 1db8135d31c7c..67b06525a7e40 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3493,6 +3493,13 @@ --> + + com.android.permissioncontroller + + + diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 1684138455e51..3331f3a88fc24 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -141,6 +141,7 @@ applications that come with the platform + diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 265d07a828873..d2547d92e8b92 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1350,6 +1350,7 @@ public class PackageManagerService extends IPackageManager.Stub final @Nullable String mDocumenterPackage; final @Nullable String mConfiguratorPackage; final @Nullable String mAppPredictionServicePackage; + final @Nullable String mIncidentReportApproverPackage; final @NonNull String mServicesSystemSharedLibraryPackageName; final @NonNull String mSharedSystemSharedLibraryPackageName; @@ -2879,6 +2880,7 @@ public class PackageManagerService extends IPackageManager.Stub mConfiguratorPackage = mContext.getString(R.string.config_deviceConfiguratorPackageName); mAppPredictionServicePackage = getAppPredictionServicePackageName(); + mIncidentReportApproverPackage = getIncidentReportApproverPackageName(); // Now that we know all of the shared libraries, update all clients to have // the correct library paths. @@ -20112,6 +20114,10 @@ public class PackageManagerService extends IPackageManager.Stub return contentCaptureServiceName.substring(0, separatorIndex); } + public String getIncidentReportApproverPackageName() { + return mContext.getString(R.string.config_incidentReportApproverPackage); + } + @Override public void setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage) { @@ -23275,6 +23281,8 @@ public class PackageManagerService extends IPackageManager.Stub return mDocumenterPackage; case PackageManagerInternal.PACKAGE_CONFIGURATOR: return mConfiguratorPackage; + case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER: + return mIncidentReportApproverPackage; } return null; } diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 17f83479a3b13..848cee06d40b7 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -251,6 +251,9 @@ public final class BasePermission { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_CONFIGURATOR) != 0; } + public boolean isIncidentReportApprover() { + return (protectionLevel & PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER) != 0; + } public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) { if (!origPackageName.equals(sourcePackageName)) { 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 3c89d78018521..22780e676f721 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1716,6 +1716,14 @@ public class PermissionManagerService { // this app is the documenter, then it gets the permission. allowed = true; } + if (!allowed && bp.isIncidentReportApprover() + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( + PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER, + UserHandle.USER_SYSTEM))) { + // If this permission is to be granted to the incident report approver and + // this app is the incident report approver, then it gets the permission. + allowed = true; + } } return allowed; } diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java index 5b02266837302..a01d589f25b3d 100644 --- a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java +++ b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java @@ -1151,6 +1151,10 @@ public class IPackageManagerStub implements IPackageManager { return null; } + public String getIncidentReportApproverPackageName() throws RemoteException { + return null; + } + @Override public boolean isPackageStateProtected(String packageName, int userId) throws RemoteException { return false;