Merge "Grant installer and verifier install permissions robustly" into mnc-dev

This commit is contained in:
Svetoslav
2015-07-07 23:44:24 +00:00
committed by Android (Google) Code Review
8 changed files with 98 additions and 116 deletions

View File

@@ -9439,10 +9439,12 @@ package android.content.pm {
field public static final int PROTECTION_DANGEROUS = 1; // 0x1 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_APPOP = 64; // 0x40
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20 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_PRE23 = 128; // 0x80
field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10 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_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_NORMAL = 0; // 0x0
field public static final int PROTECTION_SIGNATURE = 2; // 0x2 field public static final int PROTECTION_SIGNATURE = 2; // 0x2
field public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3 field public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3

View File

@@ -9774,10 +9774,12 @@ package android.content.pm {
field public static final int PROTECTION_DANGEROUS = 1; // 0x1 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_APPOP = 64; // 0x40
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20 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_PRE23 = 128; // 0x80
field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10 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_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_NORMAL = 0; // 0x0
field public static final int PROTECTION_SIGNATURE = 2; // 0x2 field public static final int PROTECTION_SIGNATURE = 2; // 0x2
field public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3 field public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3

View File

@@ -74,6 +74,8 @@ import java.util.List;
public class Am extends BaseCommand { public class Am extends BaseCommand {
private static final String SHELL_PACKAGE_NAME = "com.android.shell";
private IActivityManager mAm; private IActivityManager mAm;
private int mStartFlags = 0; private int mStartFlags = 0;
@@ -767,7 +769,8 @@ public class Am extends BaseCommand {
return; return;
} }
System.out.println("Starting service: " + intent); 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) { if (cn == null) {
System.err.println("Error: Not found; no service started."); System.err.println("Error: Not found; no service started.");
} else if (cn.getPackageName().equals("!")) { } else if (cn.getPackageName().equals("!")) {

View File

@@ -82,6 +82,20 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
*/ */
public static final int PROTECTION_FLAG_PRE23 = 0x80; 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. * 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. * 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 * The level of access this permission is protecting, as per

View File

@@ -1327,7 +1327,7 @@
that removes restrictions on where broadcasts can be sent and allows other that removes restrictions on where broadcasts can be sent and allows other
types of interactions. --> types of interactions. -->
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" <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 <!-- @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 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 <!-- @SystemApi Allows an application to update application operation statistics. Not for
use by third party apps. @hide --> use by third party apps. @hide -->
<permission android:name="android.permission.UPDATE_APP_OPS_STATS" <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 <!-- @SystemApi Allows an application to open windows that are for use by parts
of the system user interface. of the system user interface.
@@ -2016,7 +2016,7 @@
@hide @hide
--> -->
<permission android:name="android.permission.CLEAR_APP_USER_DATA" <permission android:name="android.permission.CLEAR_APP_USER_DATA"
android:protectionLevel="signature" /> android:protectionLevel="signature|installer" />
<!-- @SystemApi Allows an application to delete cache files. <!-- @SystemApi Allows an application to delete cache files.
<p>Not for use by third-party applications. --> <p>Not for use by third-party applications. -->
@@ -2041,7 +2041,7 @@
<!-- @hide Allows an application to grant or revoke specific permissions. --> <!-- @hide Allows an application to grant or revoke specific permissions. -->
<permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS" <permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS"
android:protectionLevel="signature" /> android:protectionLevel="signature|installer" />
<!-- @hide Allows an application to observe permission changes. --> <!-- @hide Allows an application to observe permission changes. -->
<permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
@@ -2552,7 +2552,7 @@
<p>Not for use by third-party applications. <p>Not for use by third-party applications.
@hide --> @hide -->
<permission android:name="android.permission.KILL_UID" <permission android:name="android.permission.KILL_UID"
android:protectionLevel="signature" /> android:protectionLevel="signature|installer" />
<!-- Allows applications to act as network scorers. @hide @SystemApi--> <!-- Allows applications to act as network scorers. @hide @SystemApi-->
<permission android:name="android.permission.LOCAL_MAC_ADDRESS" <permission android:name="android.permission.LOCAL_MAC_ADDRESS"

View File

@@ -220,6 +220,12 @@
{@link android.os.Build.VERSION_CODES#MNC} (before runtime permissions {@link android.os.Build.VERSION_CODES#MNC} (before runtime permissions
were introduced). --> were introduced). -->
<flag name="pre23" value="0x80" /> <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> </attr>
<!-- Flags indicating more context for a permission group. --> <!-- Flags indicating more context for a permission group. -->

View File

@@ -54,7 +54,6 @@ final class DefaultPermissionGrantPolicy {
private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars
private static final boolean DEBUG = false; 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 String AUDIO_MIME_TYPE = "audio/mpeg";
private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>(); private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>();
@@ -127,19 +126,6 @@ final class DefaultPermissionGrantPolicy {
SETTINGS_PERMISSIONS.add(Manifest.permission.WRITE_SETTINGS); 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 final PackageManagerService mService;
private PackagesProvider mImePackagesProvider; private PackagesProvider mImePackagesProvider;
@@ -250,30 +236,20 @@ final class DefaultPermissionGrantPolicy {
syncAdapterPackagesProvider.getPackages(CalendarContract.AUTHORITY, userId) : null; syncAdapterPackagesProvider.getPackages(CalendarContract.AUTHORITY, userId) : null;
synchronized (mService.mPackages) { synchronized (mService.mPackages) {
// Installers // Installer
Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE); PackageParser.Package installerPackage = getSystemPackageLPr(
installerIntent.addCategory(Intent.CATEGORY_DEFAULT); mService.mRequiredInstallerPackage);
installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), if (installerPackage != null
PACKAGE_MIME_TYPE); && doesPackageSupportRuntimePermissions(installerPackage)) {
List<PackageParser.Package> installerPackages = grantRuntimePermissionsLPw(installerPackage, STORAGE_PERMISSIONS, true, userId);
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);
} }
// Verifiers // Verifier
Intent verifierIntent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); PackageParser.Package verifierPackage = getSystemPackageLPr(
verifierIntent.setType(PACKAGE_MIME_TYPE); mService.mRequiredVerifierPackage);
List<PackageParser.Package> verifierPackages = if (verifierPackage != null
getPrivilegedHandlerReceiverPackagesLPr(verifierIntent, userId); && doesPackageSupportRuntimePermissions(verifierPackage)) {
final int verifierCount = verifierPackages.size(); grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, true, userId);
for (int i = 0; i < verifierCount; i++) {
PackageParser.Package verifierPackage = verifierPackages.get(i);
grantInstallPermissionsLPw(verifierPackage, VERIFIER_PERMISSIONS, userId);
grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, userId);
} }
// SetupWizard // 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( private PackageParser.Package getDefaultSystemHandlerActivityPackageLPr(
Intent intent, int userId) { 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(); final int handlerCount = handlers.size();
for (int i = 0; i < handlerCount; i++) { for (int i = 0; i < handlerCount; i++) {
ResolveInfo handler = handlers.get(i); ResolveInfo handler = handlers.get(i);
@@ -730,18 +677,9 @@ final class DefaultPermissionGrantPolicy {
return null; 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, private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
int userId) { int userId) {
grantRuntimePermissionsLPw(pkg, permissions, false, userId); grantRuntimePermissionsLPw(pkg, permissions, false, userId);
} }
private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions, 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) { private static boolean isSysComponentOrPersistentPrivApp(PackageParser.Package pkg) {
return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
|| ((pkg.applicationInfo.privateFlags || ((pkg.applicationInfo.privateFlags

View File

@@ -928,7 +928,8 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final String TAG_DEFAULT_APPS = "da"; private static final String TAG_DEFAULT_APPS = "da";
private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 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(); private final PackageUsage mPackageUsage = new PackageUsage();
@@ -2262,6 +2263,7 @@ public class PackageManagerService extends IPackageManager.Stub {
SystemClock.uptimeMillis()); SystemClock.uptimeMillis());
mRequiredVerifierPackage = getRequiredVerifierLPr(); mRequiredVerifierPackage = getRequiredVerifierLPr();
mRequiredInstallerPackage = getRequiredInstallerLPr();
mInstallerService = new PackageInstallerService(context, this); mInstallerService = new PackageInstallerService(context, this);
@@ -2328,6 +2330,39 @@ public class PackageManagerService extends IPackageManager.Stub {
return requiredVerifier; 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() { private ComponentName getIntentFilterVerifierComponentNameLPr() {
final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 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. // we still want to blindly grant it to old apps.
allowed = true; 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 if (!allowed && (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
// For development permissions, a development permission // For development permissions, a development permission