From d58f150060e9300038ff86eeeffc86c2440303c8 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Thu, 27 Sep 2012 12:58:33 -0700 Subject: Determine the originating uid for an install Bug: 6923241 Change-Id: I281301ca0bece2cb2395cde1d7652be168ffa202 --- .../packageinstaller/InstallAppProgress.java | 4 +- .../packageinstaller/PackageInstallerActivity.java | 82 +++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/InstallAppProgress.java b/src/com/android/packageinstaller/InstallAppProgress.java index e281fd3..fc82078 100755 --- a/src/com/android/packageinstaller/InstallAppProgress.java +++ b/src/com/android/packageinstaller/InstallAppProgress.java @@ -252,8 +252,10 @@ public class InstallAppProgress extends Activity implements View.OnClickListener Intent.EXTRA_INSTALLER_PACKAGE_NAME); Uri originatingURI = getIntent().getParcelableExtra(Intent.EXTRA_ORIGINATING_URI); Uri referrer = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER); + int originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID, + VerificationParams.NO_UID); VerificationParams verificationParams = new VerificationParams(null, originatingURI, - referrer, null); + referrer, originatingUid, null); PackageInstallObserver observer = new PackageInstallObserver(); if ("package".equals(mPackageURI.getScheme())) { diff --git a/src/com/android/packageinstaller/PackageInstallerActivity.java b/src/com/android/packageinstaller/PackageInstallerActivity.java index d3b2a94..a0546a2 100644 --- a/src/com/android/packageinstaller/PackageInstallerActivity.java +++ b/src/com/android/packageinstaller/PackageInstallerActivity.java @@ -17,6 +17,7 @@ package com.android.packageinstaller; import android.app.Activity; +import android.app.ActivityManagerNative; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; @@ -30,6 +31,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageUserState; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageParser; +import android.content.pm.VerificationParams; import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; @@ -66,6 +68,8 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen private Uri mPackageURI; private Uri mOriginatingURI; private Uri mReferrerURI; + private int mOriginatingUid = VerificationParams.NO_UID; + private boolean localLOGV = false; PackageManager mPm; PackageInfo mPkgInfo; @@ -523,6 +527,8 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen mInstallConfirm.setVisibility(View.INVISIBLE); PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); + mOriginatingUid = getOriginatingUid(intent); + // Deal with install source. String callerPackage = getCallingPackage(); if (callerPackage != null && intent.getBooleanExtra( @@ -562,7 +568,78 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen } initiateInstall(); } - + + /** Get the ApplicationInfo for the calling package, if available */ + private ApplicationInfo getSourceInfo() { + String callingPackage = getCallingPackage(); + if (callingPackage != null) { + try { + return mPm.getApplicationInfo(callingPackage, 0); + } catch (NameNotFoundException ex) { + // ignore + } + } + return null; + } + + + /** Get the originating uid if possible, or VerificationParams.NO_UID if not available */ + private int getOriginatingUid(Intent intent) { + // The originating uid from the intent. We only trust/use this if it comes from a + // system application + int uidFromIntent = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID, + VerificationParams.NO_UID); + + // Get the source info from the calling package, if available. This will be the + // definitive calling package, but it only works if the intent was started using + // startActivityForResult, + ApplicationInfo sourceInfo = getSourceInfo(); + if (sourceInfo != null) { + if (uidFromIntent != VerificationParams.NO_UID && + (mSourceInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + return uidFromIntent; + + } + // We either didn't get a uid in the intent, or we don't trust it. Use the + // uid of the calling package instead. + return sourceInfo.uid; + } + + // We couldn't get the specific calling package. Let's get the uid instead + int callingUid; + try { + callingUid = ActivityManagerNative.getDefault() + .getLaunchedFromUid(getActivityToken()); + } catch (android.os.RemoteException ex) { + Log.w(TAG, "Could not determine the launching uid."); + // nothing else we can do + return VerificationParams.NO_UID; + } + + // If we got a uid from the intent, we need to verify that the caller is a + // system package before we use it + if (uidFromIntent != VerificationParams.NO_UID) { + String[] callingPackages = mPm.getPackagesForUid(callingUid); + if (callingPackages != null) { + for (String packageName: callingPackages) { + try { + ApplicationInfo applicationInfo = + mPm.getApplicationInfo(packageName, 0); + + if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + return uidFromIntent; + } + } catch (NameNotFoundException ex) { + // ignore it, and try the next package + } + } + } + } + // We either didn't get a uid from the intent, or we don't trust it. Use the + // calling uid instead. + return callingUid; + } + // Generic handling when pressing back key public void onCancel(DialogInterface dialog) { finish(); @@ -585,6 +662,9 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen if (mReferrerURI != null) { newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI); } + if (mOriginatingUid != VerificationParams.NO_UID) { + newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid); + } if (installerPackageName != null) { newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName); -- cgit v1.1