Allow package verifier and uninstaller to do silent uninstalls.

am: bf6154a5ba

Change-Id: Iab55e58e02a2088c541406bc0b71aa14df7b028e
This commit is contained in:
Sudheer Shanka
2016-08-31 23:30:12 +00:00
committed by android-build-merger

View File

@@ -458,6 +458,8 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
private static final String PACKAGE_SCHEME = "package";
private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000; private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000;
@@ -1121,6 +1123,7 @@ public class PackageManagerService extends IPackageManager.Stub {
final @Nullable String mRequiredVerifierPackage; final @Nullable String mRequiredVerifierPackage;
final @NonNull String mRequiredInstallerPackage; final @NonNull String mRequiredInstallerPackage;
final @NonNull String mRequiredUninstallerPackage;
final @Nullable String mSetupWizardPackage; final @Nullable String mSetupWizardPackage;
final @NonNull String mServicesSystemSharedLibraryPackageName; final @NonNull String mServicesSystemSharedLibraryPackageName;
final @NonNull String mSharedSystemSharedLibraryPackageName; final @NonNull String mSharedSystemSharedLibraryPackageName;
@@ -2626,6 +2629,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (!mOnlyCore) { if (!mOnlyCore) {
mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
mRequiredInstallerPackage = getRequiredInstallerLPr(); mRequiredInstallerPackage = getRequiredInstallerLPr();
mRequiredUninstallerPackage = getRequiredUninstallerLPr();
mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
mIntentFilterVerifier = new IntentVerifierProxy(mContext, mIntentFilterVerifier = new IntentVerifierProxy(mContext,
mIntentFilterVerifierComponent); mIntentFilterVerifierComponent);
@@ -2636,6 +2640,7 @@ public class PackageManagerService extends IPackageManager.Stub {
} else { } else {
mRequiredVerifierPackage = null; mRequiredVerifierPackage = null;
mRequiredInstallerPackage = null; mRequiredInstallerPackage = null;
mRequiredUninstallerPackage = null;
mIntentFilterVerifierComponent = null; mIntentFilterVerifierComponent = null;
mIntentFilterVerifier = null; mIntentFilterVerifier = null;
mServicesSystemSharedLibraryPackageName = null; mServicesSystemSharedLibraryPackageName = null;
@@ -2749,6 +2754,22 @@ public class PackageManagerService extends IPackageManager.Stub {
} }
} }
private @NonNull String getRequiredUninstallerLPr() {
final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
final ResolveInfo resolveInfo = resolveIntent(intent, null,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
UserHandle.USER_SYSTEM);
if (resolveInfo == null ||
mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
throw new RuntimeException("There must be exactly one uninstaller; found "
+ resolveInfo);
}
return resolveInfo.getComponentInfo().packageName;
}
private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
@@ -11315,7 +11336,7 @@ public class PackageManagerService extends IPackageManager.Stub {
} }
for (int id : resolvedUserIds) { for (int id : resolvedUserIds) {
final Intent intent = new Intent(action, final Intent intent = new Intent(action,
pkg != null ? Uri.fromParts("package", pkg, null) : null); pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
if (extras != null) { if (extras != null) {
intent.putExtras(extras); intent.putExtras(extras);
} }
@@ -11811,6 +11832,12 @@ public class PackageManagerService extends IPackageManager.Stub {
return false; return false;
} }
if (packageName.equals(mRequiredUninstallerPackage)) {
Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ "\": required for package uninstallation");
return false;
}
if (packageName.equals(mRequiredVerifierPackage)) { if (packageName.equals(mRequiredVerifierPackage)) {
Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ "\": required for package verification"); + "\": required for package verification");
@@ -15375,13 +15402,11 @@ public class PackageManagerService extends IPackageManager.Stub {
Preconditions.checkNotNull(packageName); Preconditions.checkNotNull(packageName);
Preconditions.checkNotNull(observer); Preconditions.checkNotNull(observer);
final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid();
if (uid != Process.SHELL_UID && uid != Process.ROOT_UID && uid != Process.SYSTEM_UID if (!isOrphaned(packageName)
&& uid != getPackageUid(mRequiredInstallerPackage, 0, UserHandle.getUserId(uid)) && !isCallerAllowedToSilentlyUninstall(uid, packageName)) {
&& !isOrphaned(packageName)
&& !isCallerSameAsInstaller(uid, packageName)) {
try { try {
final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
intent.setData(Uri.fromParts("package", packageName, null)); intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
observer.onUserActionRequired(intent); observer.onUserActionRequired(intent);
} catch (RemoteException re) { } catch (RemoteException re) {
@@ -15456,10 +15481,29 @@ public class PackageManagerService extends IPackageManager.Stub {
}); });
} }
private boolean isCallerSameAsInstaller(int callingUid, String pkgName) { private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
final int installerPkgUid = getPackageUid(getInstallerPackageName(pkgName), if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
0 /* flags */, UserHandle.getUserId(callingUid)); || callingUid == Process.SYSTEM_UID) {
return installerPkgUid == callingUid; return true;
}
final int callingUserId = UserHandle.getUserId(callingUid);
// If the caller installed the pkgName, then allow it to silently uninstall.
if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
return true;
}
// Allow package verifier to silently uninstall.
if (mRequiredVerifierPackage != null &&
callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
return true;
}
// Allow package uninstaller to silently uninstall.
if (mRequiredUninstallerPackage != null &&
callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
return true;
}
return false;
} }
private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {