Allow package verifier and uninstaller to do silent uninstalls.
am: bf6154a5ba
Change-Id: Iab55e58e02a2088c541406bc0b71aa14df7b028e
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user