am 0ce19f8e: am 240f8e5f: am 3e07ee07: Merge "Grant installer and verifier install permissions robustly" into mnc-dev
* commit '0ce19f8e5306c81e16c7f34edf7289e0b31cccbf': Grant installer and verifier install permissions robustly
This commit is contained in:
@@ -9439,10 +9439,12 @@ package android.content.pm {
|
||||
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
|
||||
field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
|
||||
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
|
||||
field public static final int PROTECTION_FLAG_INSTALLER = 256; // 0x100
|
||||
field public static final int PROTECTION_FLAG_PRE23 = 128; // 0x80
|
||||
field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10
|
||||
field public static final int PROTECTION_FLAG_VERIFIER = 512; // 0x200
|
||||
field public static final int PROTECTION_MASK_BASE = 15; // 0xf
|
||||
field public static final int PROTECTION_MASK_FLAGS = 240; // 0xf0
|
||||
field public static final int PROTECTION_MASK_FLAGS = 4080; // 0xff0
|
||||
field public static final int PROTECTION_NORMAL = 0; // 0x0
|
||||
field public static final int PROTECTION_SIGNATURE = 2; // 0x2
|
||||
field public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3
|
||||
|
||||
@@ -9774,10 +9774,12 @@ package android.content.pm {
|
||||
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
|
||||
field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
|
||||
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
|
||||
field public static final int PROTECTION_FLAG_INSTALLER = 256; // 0x100
|
||||
field public static final int PROTECTION_FLAG_PRE23 = 128; // 0x80
|
||||
field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10
|
||||
field public static final int PROTECTION_FLAG_VERIFIER = 512; // 0x200
|
||||
field public static final int PROTECTION_MASK_BASE = 15; // 0xf
|
||||
field public static final int PROTECTION_MASK_FLAGS = 240; // 0xf0
|
||||
field public static final int PROTECTION_MASK_FLAGS = 4080; // 0xff0
|
||||
field public static final int PROTECTION_NORMAL = 0; // 0x0
|
||||
field public static final int PROTECTION_SIGNATURE = 2; // 0x2
|
||||
field public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3
|
||||
|
||||
@@ -74,6 +74,8 @@ import java.util.List;
|
||||
|
||||
public class Am extends BaseCommand {
|
||||
|
||||
private static final String SHELL_PACKAGE_NAME = "com.android.shell";
|
||||
|
||||
private IActivityManager mAm;
|
||||
|
||||
private int mStartFlags = 0;
|
||||
@@ -767,7 +769,8 @@ public class Am extends BaseCommand {
|
||||
return;
|
||||
}
|
||||
System.out.println("Starting service: " + intent);
|
||||
ComponentName cn = mAm.startService(null, intent, intent.getType(), null, mUserId);
|
||||
ComponentName cn = mAm.startService(null, intent, intent.getType(),
|
||||
SHELL_PACKAGE_NAME, mUserId);
|
||||
if (cn == null) {
|
||||
System.err.println("Error: Not found; no service started.");
|
||||
} else if (cn.getPackageName().equals("!")) {
|
||||
|
||||
@@ -82,6 +82,20 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
|
||||
*/
|
||||
public static final int PROTECTION_FLAG_PRE23 = 0x80;
|
||||
|
||||
/**
|
||||
* Additional flag for {@link #protectionLevel}, corresponding
|
||||
* to the <code>installer</code> value of
|
||||
* {@link android.R.attr#protectionLevel}.
|
||||
*/
|
||||
public static final int PROTECTION_FLAG_INSTALLER = 0x100;
|
||||
|
||||
/**
|
||||
* Additional flag for {@link #protectionLevel}, corresponding
|
||||
* to the <code>verifier</code> value of
|
||||
* {@link android.R.attr#protectionLevel}.
|
||||
*/
|
||||
public static final int PROTECTION_FLAG_VERIFIER = 0x200;
|
||||
|
||||
/**
|
||||
* Mask for {@link #protectionLevel}: the basic protection type.
|
||||
*/
|
||||
@@ -90,7 +104,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
|
||||
/**
|
||||
* Mask for {@link #protectionLevel}: additional flag bits.
|
||||
*/
|
||||
public static final int PROTECTION_MASK_FLAGS = 0xf0;
|
||||
public static final int PROTECTION_MASK_FLAGS = 0xff0;
|
||||
|
||||
/**
|
||||
* The level of access this permission is protecting, as per
|
||||
|
||||
@@ -1327,7 +1327,7 @@
|
||||
that removes restrictions on where broadcasts can be sent and allows other
|
||||
types of interactions. -->
|
||||
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
|
||||
android:protectionLevel="signature" />
|
||||
android:protectionLevel="signature|installer" />
|
||||
|
||||
<!-- @SystemApi @hide Allows an application to call APIs that allow it to query and manage
|
||||
users on the device. This permission is not available to
|
||||
@@ -1769,7 +1769,7 @@
|
||||
<!-- @SystemApi Allows an application to update application operation statistics. Not for
|
||||
use by third party apps. @hide -->
|
||||
<permission android:name="android.permission.UPDATE_APP_OPS_STATS"
|
||||
android:protectionLevel="signature|system" />
|
||||
android:protectionLevel="signature|system|installer" />
|
||||
|
||||
<!-- @SystemApi Allows an application to open windows that are for use by parts
|
||||
of the system user interface.
|
||||
@@ -2016,7 +2016,7 @@
|
||||
@hide
|
||||
-->
|
||||
<permission android:name="android.permission.CLEAR_APP_USER_DATA"
|
||||
android:protectionLevel="signature" />
|
||||
android:protectionLevel="signature|installer" />
|
||||
|
||||
<!-- @SystemApi Allows an application to delete cache files.
|
||||
<p>Not for use by third-party applications. -->
|
||||
@@ -2041,7 +2041,7 @@
|
||||
|
||||
<!-- @hide Allows an application to grant or revoke specific permissions. -->
|
||||
<permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS"
|
||||
android:protectionLevel="signature" />
|
||||
android:protectionLevel="signature|installer" />
|
||||
|
||||
<!-- @hide Allows an application to observe permission changes. -->
|
||||
<permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
|
||||
@@ -2552,7 +2552,7 @@
|
||||
<p>Not for use by third-party applications.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.KILL_UID"
|
||||
android:protectionLevel="signature" />
|
||||
android:protectionLevel="signature|installer" />
|
||||
|
||||
<!-- Allows applications to act as network scorers. @hide @SystemApi-->
|
||||
<permission android:name="android.permission.LOCAL_MAC_ADDRESS"
|
||||
|
||||
@@ -220,6 +220,12 @@
|
||||
{@link android.os.Build.VERSION_CODES#MNC} (before runtime permissions
|
||||
were introduced). -->
|
||||
<flag name="pre23" value="0x80" />
|
||||
<!-- Additional flag from base permission type: this permission can be automatically
|
||||
granted to system apps that install packages. -->
|
||||
<flag name="installer" value="0x100" />
|
||||
<!-- Additional flag from base permission type: this permission can be automatically
|
||||
granted to system apps that verify packages. -->
|
||||
<flag name="verifier" value="0x200" />
|
||||
</attr>
|
||||
|
||||
<!-- Flags indicating more context for a permission group. -->
|
||||
|
||||
@@ -54,7 +54,6 @@ final class DefaultPermissionGrantPolicy {
|
||||
private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
|
||||
private static final String AUDIO_MIME_TYPE = "audio/mpeg";
|
||||
|
||||
private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>();
|
||||
@@ -127,19 +126,6 @@ final class DefaultPermissionGrantPolicy {
|
||||
SETTINGS_PERMISSIONS.add(Manifest.permission.WRITE_SETTINGS);
|
||||
}
|
||||
|
||||
private static final Set<String> INSTALLER_PERMISSIONS = new ArraySet<>();
|
||||
static {
|
||||
INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS);
|
||||
INSTALLER_PERMISSIONS.add(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
|
||||
INSTALLER_PERMISSIONS.add(Manifest.permission.CLEAR_APP_USER_DATA);
|
||||
INSTALLER_PERMISSIONS.add(Manifest.permission.KILL_UID);
|
||||
}
|
||||
|
||||
private static final Set<String> VERIFIER_PERMISSIONS = new ArraySet<>();
|
||||
static {
|
||||
INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS);
|
||||
}
|
||||
|
||||
private final PackageManagerService mService;
|
||||
|
||||
private PackagesProvider mImePackagesProvider;
|
||||
@@ -250,30 +236,20 @@ final class DefaultPermissionGrantPolicy {
|
||||
syncAdapterPackagesProvider.getPackages(CalendarContract.AUTHORITY, userId) : null;
|
||||
|
||||
synchronized (mService.mPackages) {
|
||||
// Installers
|
||||
Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
|
||||
installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")),
|
||||
PACKAGE_MIME_TYPE);
|
||||
List<PackageParser.Package> installerPackages =
|
||||
getPrivilegedHandlerActivityPackagesLPr(installerIntent, userId);
|
||||
final int installerCount = installerPackages.size();
|
||||
for (int i = 0; i < installerCount; i++) {
|
||||
PackageParser.Package installPackage = installerPackages.get(i);
|
||||
grantInstallPermissionsLPw(installPackage, INSTALLER_PERMISSIONS, userId);
|
||||
grantRuntimePermissionsLPw(installPackage, STORAGE_PERMISSIONS, true, userId);
|
||||
// Installer
|
||||
PackageParser.Package installerPackage = getSystemPackageLPr(
|
||||
mService.mRequiredInstallerPackage);
|
||||
if (installerPackage != null
|
||||
&& doesPackageSupportRuntimePermissions(installerPackage)) {
|
||||
grantRuntimePermissionsLPw(installerPackage, STORAGE_PERMISSIONS, true, userId);
|
||||
}
|
||||
|
||||
// Verifiers
|
||||
Intent verifierIntent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
|
||||
verifierIntent.setType(PACKAGE_MIME_TYPE);
|
||||
List<PackageParser.Package> verifierPackages =
|
||||
getPrivilegedHandlerReceiverPackagesLPr(verifierIntent, userId);
|
||||
final int verifierCount = verifierPackages.size();
|
||||
for (int i = 0; i < verifierCount; i++) {
|
||||
PackageParser.Package verifierPackage = verifierPackages.get(i);
|
||||
grantInstallPermissionsLPw(verifierPackage, VERIFIER_PERMISSIONS, userId);
|
||||
grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, userId);
|
||||
// Verifier
|
||||
PackageParser.Package verifierPackage = getSystemPackageLPr(
|
||||
mService.mRequiredVerifierPackage);
|
||||
if (verifierPackage != null
|
||||
&& doesPackageSupportRuntimePermissions(verifierPackage)) {
|
||||
grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, true, userId);
|
||||
}
|
||||
|
||||
// SetupWizard
|
||||
@@ -638,39 +614,10 @@ final class DefaultPermissionGrantPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
private List<PackageParser.Package> getPrivilegedHandlerReceiverPackagesLPr(
|
||||
Intent intent, int userId) {
|
||||
List<ResolveInfo> handlers = mService.queryIntentReceivers(
|
||||
intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()),
|
||||
0, userId);
|
||||
return getPrivilegedPackages(handlers);
|
||||
}
|
||||
|
||||
private List<PackageParser.Package> getPrivilegedHandlerActivityPackagesLPr(
|
||||
Intent intent, int userId) {
|
||||
List<ResolveInfo> handlers = mService.queryIntentActivities(
|
||||
intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()),
|
||||
0, userId);
|
||||
return getPrivilegedPackages(handlers);
|
||||
}
|
||||
|
||||
private List<PackageParser.Package> getPrivilegedPackages(List<ResolveInfo> resolveInfos) {
|
||||
List<PackageParser.Package> handlerPackages = new ArrayList<>();
|
||||
final int handlerCount = resolveInfos.size();
|
||||
for (int i = 0; i < handlerCount; i++) {
|
||||
ResolveInfo handler = resolveInfos.get(i);
|
||||
PackageParser.Package handlerPackage = getPrivilegedPackageLPr(
|
||||
handler.activityInfo.packageName);
|
||||
if (handlerPackage != null) {
|
||||
handlerPackages.add(handlerPackage);
|
||||
}
|
||||
}
|
||||
return handlerPackages;
|
||||
}
|
||||
|
||||
private PackageParser.Package getDefaultSystemHandlerActivityPackageLPr(
|
||||
Intent intent, int userId) {
|
||||
List<ResolveInfo> handlers = mService.queryIntentActivities(intent, null, 0, userId);
|
||||
List<ResolveInfo> handlers = mService.queryIntentActivities(intent,
|
||||
intent.resolveType(mService.mContext.getContentResolver()), 0, userId);
|
||||
final int handlerCount = handlers.size();
|
||||
for (int i = 0; i < handlerCount; i++) {
|
||||
ResolveInfo handler = handlers.get(i);
|
||||
@@ -730,18 +677,9 @@ final class DefaultPermissionGrantPolicy {
|
||||
return null;
|
||||
}
|
||||
|
||||
private PackageParser.Package getPrivilegedPackageLPr(String packageName) {
|
||||
PackageParser.Package pkg = mService.mPackages.get(packageName);
|
||||
if (pkg != null && pkg.applicationInfo.isPrivilegedApp()) {
|
||||
return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
|
||||
int userId) {
|
||||
grantRuntimePermissionsLPw(pkg, permissions, false, userId);
|
||||
|
||||
}
|
||||
|
||||
private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
|
||||
@@ -783,36 +721,6 @@ final class DefaultPermissionGrantPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
private void grantInstallPermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
|
||||
int userId) {
|
||||
List<String> requestedPermissions = pkg.requestedPermissions;
|
||||
|
||||
if (pkg.isUpdatedSystemApp()) {
|
||||
PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName);
|
||||
if (sysPs != null) {
|
||||
requestedPermissions = sysPs.pkg.requestedPermissions;
|
||||
}
|
||||
}
|
||||
|
||||
final int permissionCount = requestedPermissions.size();
|
||||
for (int i = 0; i < permissionCount; i++) {
|
||||
String permission = requestedPermissions.get(i);
|
||||
if (permissions.contains(permission)) {
|
||||
final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId);
|
||||
|
||||
// If any flags are set to the permission, then it is either set in
|
||||
// its current state by the system or device/profile owner or the user.
|
||||
// In all these cases we do not want to clobber the current state.
|
||||
if (flags == 0) {
|
||||
mService.grantInstallPermissionLPw(permission, pkg);
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Granted install " + permission + " to " + pkg.packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSysComponentOrPersistentPrivApp(PackageParser.Package pkg) {
|
||||
return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
|
||||
|| ((pkg.applicationInfo.privateFlags
|
||||
|
||||
@@ -928,7 +928,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
private static final String TAG_DEFAULT_APPS = "da";
|
||||
private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
|
||||
|
||||
private final String mRequiredVerifierPackage;
|
||||
final String mRequiredVerifierPackage;
|
||||
final String mRequiredInstallerPackage;
|
||||
|
||||
private final PackageUsage mPackageUsage = new PackageUsage();
|
||||
|
||||
@@ -2262,6 +2263,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
SystemClock.uptimeMillis());
|
||||
|
||||
mRequiredVerifierPackage = getRequiredVerifierLPr();
|
||||
mRequiredInstallerPackage = getRequiredInstallerLPr();
|
||||
|
||||
mInstallerService = new PackageInstallerService(context, this);
|
||||
|
||||
@@ -2328,6 +2330,39 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return requiredVerifier;
|
||||
}
|
||||
|
||||
private String getRequiredInstallerLPr() {
|
||||
Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
|
||||
installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
|
||||
|
||||
final List<ResolveInfo> installers = queryIntentActivities(installerIntent,
|
||||
PACKAGE_MIME_TYPE, 0, 0);
|
||||
|
||||
String requiredInstaller = null;
|
||||
|
||||
final int N = installers.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final ResolveInfo info = installers.get(i);
|
||||
final String packageName = info.activityInfo.packageName;
|
||||
|
||||
if (!info.activityInfo.applicationInfo.isSystemApp()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (requiredInstaller != null) {
|
||||
throw new RuntimeException("There must be one required installer");
|
||||
}
|
||||
|
||||
requiredInstaller = packageName;
|
||||
}
|
||||
|
||||
if (requiredInstaller == null) {
|
||||
throw new RuntimeException("There must be one required installer");
|
||||
}
|
||||
|
||||
return requiredInstaller;
|
||||
}
|
||||
|
||||
private ComponentName getIntentFilterVerifierComponentNameLPr() {
|
||||
final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
|
||||
final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
|
||||
@@ -8440,6 +8475,18 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
// we still want to blindly grant it to old apps.
|
||||
allowed = true;
|
||||
}
|
||||
if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
|
||||
&& pkg.packageName.equals(mRequiredInstallerPackage)) {
|
||||
// If this permission is to be granted to the system installer and
|
||||
// this app is an installer, then it gets the permission.
|
||||
allowed = true;
|
||||
}
|
||||
if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
|
||||
&& pkg.packageName.equals(mRequiredVerifierPackage)) {
|
||||
// If this permission is to be granted to the system verifier and
|
||||
// this app is a verifier, then it gets the permission.
|
||||
allowed = true;
|
||||
}
|
||||
if (!allowed && (bp.protectionLevel
|
||||
& PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
|
||||
// For development permissions, a development permission
|
||||
|
||||
Reference in New Issue
Block a user