diff options
author | Philip P. Moltmann <moltmann@google.com> | 2017-09-05 12:41:47 -0700 |
---|---|---|
committer | Philip P. Moltmann <moltmann@google.com> | 2017-11-14 12:52:27 -0800 |
commit | e5029e6141842215cca1f3732e416bece31d1793 (patch) | |
tree | 02339656ab14bdf169323cb385198c871013f75c /src | |
parent | 10f770c6b006c915b662658f2f08d590a0cbc198 (diff) | |
download | android_packages_apps_PackageInstaller-e5029e6141842215cca1f3732e416bece31d1793.tar.gz android_packages_apps_PackageInstaller-e5029e6141842215cca1f3732e416bece31d1793.tar.bz2 android_packages_apps_PackageInstaller-e5029e6141842215cca1f3732e416bece31d1793.zip |
Enforce REQUEST_DELETE_PACKAGES for intent uninstall.
Test: Uninstalled app from launcher and settings
Bug: 64576642
Change-Id: I2b78fae9065e97d51a13c5e9eea56c3d94565784
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/packageinstaller/InstallStart.java | 20 | ||||
-rw-r--r-- | src/com/android/packageinstaller/PackageUtil.java | 25 | ||||
-rwxr-xr-x | src/com/android/packageinstaller/UninstallerActivity.java | 34 |
3 files changed, 62 insertions, 17 deletions
diff --git a/src/com/android/packageinstaller/InstallStart.java b/src/com/android/packageinstaller/InstallStart.java index 12441b50..5c9ad85c 100644 --- a/src/com/android/packageinstaller/InstallStart.java +++ b/src/com/android/packageinstaller/InstallStart.java @@ -16,6 +16,8 @@ package com.android.packageinstaller; +import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid; + import android.Manifest; import android.app.Activity; import android.app.ActivityManager; @@ -73,7 +75,7 @@ public class InstallStart extends Activity { } if (!isTrustedSource && originatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) { - final int targetSdkVersion = getMaxTargetSdkVersionForUid(originatingUid); + final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, originatingUid); if (targetSdkVersion < 0) { Log.w(LOG_TAG, "Cannot get target sdk version for uid " + originatingUid); // Invalid originating uid supplied. Abort install. @@ -149,22 +151,6 @@ public class InstallStart extends Activity { return false; } - private int getMaxTargetSdkVersionForUid(int uid) { - final String[] packages = getPackageManager().getPackagesForUid(uid); - int targetSdkVersion = -1; - if (packages != null) { - for (String packageName : packages) { - try { - ApplicationInfo info = getPackageManager().getApplicationInfo(packageName, 0); - targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion); - } catch (PackageManager.NameNotFoundException e) { - // Ignore and try the next package - } - } - } - return targetSdkVersion; - } - /** * @return the ApplicationInfo for the installation source (the calling package), if available */ diff --git a/src/com/android/packageinstaller/PackageUtil.java b/src/com/android/packageinstaller/PackageUtil.java index 0db09e88..693b3505 100644 --- a/src/com/android/packageinstaller/PackageUtil.java +++ b/src/com/android/packageinstaller/PackageUtil.java @@ -182,4 +182,29 @@ public class PackageUtil { } return new PackageUtil.AppSnippet(label, icon); } + + /** + * Get the maximum target sdk for a UID. + * + * @param context The context to use + * @param uid The UID requesting the install/uninstall + * + * @return The maximum target SDK or -1 if the uid does not match any packages. + */ + static int getMaxTargetSdkVersionForUid(@NonNull Context context, int uid) { + PackageManager pm = context.getPackageManager(); + final String[] packages = pm.getPackagesForUid(uid); + int targetSdkVersion = -1; + if (packages != null) { + for (String packageName : packages) { + try { + ApplicationInfo info = pm.getApplicationInfo(packageName, 0); + targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion); + } catch (PackageManager.NameNotFoundException e) { + // Ignore and try the next package + } + } + } + return targetSdkVersion; + } } diff --git a/src/com/android/packageinstaller/UninstallerActivity.java b/src/com/android/packageinstaller/UninstallerActivity.java index dbd7ac3d..bbd0155c 100755 --- a/src/com/android/packageinstaller/UninstallerActivity.java +++ b/src/com/android/packageinstaller/UninstallerActivity.java @@ -16,8 +16,13 @@ */ package com.android.packageinstaller; +import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid; + +import android.Manifest; import android.app.Activity; +import android.app.ActivityManager; import android.app.ActivityThread; +import android.app.AppGlobals; import android.app.DialogFragment; import android.app.Fragment; import android.app.FragmentTransaction; @@ -37,6 +42,7 @@ import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; import android.content.res.Configuration; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; @@ -79,6 +85,34 @@ public class UninstallerActivity extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + + try { + int callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken()); + + if (getMaxTargetSdkVersionForUid(this, callingUid) + >= Build.VERSION_CODES.P && AppGlobals.getPackageManager().checkUidPermission( + Manifest.permission.REQUEST_DELETE_PACKAGES, callingUid) + != PackageManager.PERMISSION_GRANTED + && AppGlobals.getPackageManager().checkUidPermission( + Manifest.permission.DELETE_PACKAGES, callingUid) + != PackageManager.PERMISSION_GRANTED) { + Log.e(TAG, "Uid " + callingUid + " does not have " + + Manifest.permission.REQUEST_DELETE_PACKAGES + " or " + + Manifest.permission.DELETE_PACKAGES); + + setResult(Activity.RESULT_FIRST_USER); + finish(); + return; + } + } catch (RemoteException ex) { + // Cannot reach Package/ActivityManager. Aborting uninstall. + Log.e(TAG, "Could not determine the launching uid."); + + setResult(Activity.RESULT_FIRST_USER); + finish(); + return; + } + // Get intent information. // We expect an intent with URI of the form package://<packageName>#<className> // className is optional; if specified, it is the activity the user chose to uninstall |