Loading packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java +34 −13 Original line number Original line Diff line number Diff line Loading @@ -114,12 +114,13 @@ public class InstallStart extends Activity { final int sessionId = (isSessionInstall final int sessionId = (isSessionInstall ? intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, SessionInfo.INVALID_ID) ? intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, SessionInfo.INVALID_ID) : SessionInfo.INVALID_ID); : SessionInfo.INVALID_ID); int originatingUidFromSession = callingUid; if (sessionId != SessionInfo.INVALID_ID) { if (sessionId != SessionInfo.INVALID_ID) { PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId); PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId); if (sessionInfo != null) { if (sessionInfo != null) { callingAttributionTag = sessionInfo.getInstallerAttributionTag(); callingAttributionTag = sessionInfo.getInstallerAttributionTag(); if (sessionInfo.getOriginatingUid() != Process.INVALID_UID) { if (sessionInfo.getOriginatingUid() != Process.INVALID_UID) { originatingUid = sessionInfo.getOriginatingUid(); originatingUidFromSession = sessionInfo.getOriginatingUid(); } } } } } } Loading @@ -136,24 +137,40 @@ public class InstallStart extends Activity { boolean isSystemDownloadsProvider = PackageUtil.getSystemDownloadsProviderInfo( boolean isSystemDownloadsProvider = PackageUtil.getSystemDownloadsProviderInfo( mPackageManager, callingUid) != null; mPackageManager, callingUid) != null; // By default, the originatingUid is callingUid. If the caller is the system download // provider or the documents manager, we parse the originatingUid from the // Intent.EXTRA_ORIGINATING_UID. And we check the appOps permission for the originatingUid // later. if (isDocumentsManager || isSystemDownloadsProvider) { // The originating uid from the intent. We only trust/use this if it comes from either // the document manager app or the downloads provider. It may be Process.INVALID_UID if // the original owner App is not installed on the device now. originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID, Process.INVALID_UID); } boolean isPrivilegedAndKnown = (sourceInfo != null && sourceInfo.isPrivilegedApp()) && boolean isPrivilegedAndKnown = (sourceInfo != null && sourceInfo.isPrivilegedApp()) && intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false); intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false); boolean isInstallPkgPermissionGranted = boolean isInstallPkgPermissionGranted = originatingUid != Process.INVALID_UID checkPermission(Manifest.permission.INSTALL_PACKAGES, /* pid= */ -1, callingUid) && checkPermission(Manifest.permission.INSTALL_PACKAGES, /* pid= */ -1, == PackageManager.PERMISSION_GRANTED; originatingUid) == PackageManager.PERMISSION_GRANTED; boolean isTrustedSource = isPrivilegedAndKnown || isInstallPkgPermissionGranted; boolean isTrustedSource = isPrivilegedAndKnown || isInstallPkgPermissionGranted; if (!isTrustedSource && !isSystemDownloadsProvider && !isDocumentsManager // In general case, the originatingUid is callingUid. If callingUid is INVALID_UID, return && callingUid != Process.INVALID_UID) { // InstallAborted in the check above. When the originatingUid is INVALID_UID here, it means final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, callingUid); // the originatingUid is from the system download manager or the system documents manager, // and the package doesn't exist on the device. For this case, we don't need to check the // permission for the originatingUid. The package doesn't exist. if (!isTrustedSource && originatingUid != Process.INVALID_UID) { final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, originatingUid); if (targetSdkVersion < 0) { if (targetSdkVersion < 0) { Log.e(TAG, "Cannot get target sdk version for uid " + callingUid); Log.e(TAG, "Cannot get target sdk version for uid " + originatingUid); // Invalid originating uid supplied. Abort install. // Invalid originating uid supplied. Abort install. mAbortInstall = true; mAbortInstall = true; } else if (targetSdkVersion >= Build.VERSION_CODES.O && !isUidRequestingPermission( } else if (targetSdkVersion >= Build.VERSION_CODES.O && !isUidRequestingPermission( callingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES)) { originatingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES)) { Log.e(TAG, "Requesting uid " + callingUid + " needs to declare permission " Log.e(TAG, "Requesting uid " + originatingUid + " needs to declare permission " + Manifest.permission.REQUEST_INSTALL_PACKAGES); + Manifest.permission.REQUEST_INSTALL_PACKAGES); mAbortInstall = true; mAbortInstall = true; } } Loading Loading @@ -182,6 +199,7 @@ public class InstallStart extends Activity { } } if (mAbortInstall) { if (mAbortInstall) { android.util.Log.d(TAG, "Abort the installation"); setResult(RESULT_CANCELED); setResult(RESULT_CANCELED); if (mShouldFinish) { if (mShouldFinish) { finish(); finish(); Loading @@ -200,6 +218,8 @@ public class InstallStart extends Activity { callingAttributionTag); callingAttributionTag); nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINAL_SOURCE_INFO, sourceInfo); nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINAL_SOURCE_INFO, sourceInfo); nextActivity.putExtra(Intent.EXTRA_ORIGINATING_UID, originatingUid); nextActivity.putExtra(Intent.EXTRA_ORIGINATING_UID, originatingUid); nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINATING_UID_FROM_SESSION_INFO, originatingUidFromSession); nextActivity.putExtra(PackageInstallerActivity.EXTRA_IS_TRUSTED_SOURCE, isTrustedSource); nextActivity.putExtra(PackageInstallerActivity.EXTRA_IS_TRUSTED_SOURCE, isTrustedSource); if (isSessionInstall) { if (isSessionInstall) { Loading @@ -208,9 +228,9 @@ public class InstallStart extends Activity { } else { } else { Uri packageUri = intent.getData(); Uri packageUri = intent.getData(); if (packageUri != null if (packageUri != null && packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT) && packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT) && (originatingUid == Process.INVALID_UID && canPackageQuery(callingUid, packageUri)) { || canPackageQuery(originatingUid, packageUri))) { // [IMPORTANT] This path is deprecated, but should still work. Only necessary // [IMPORTANT] This path is deprecated, but should still work. Only necessary // features should be added. // features should be added. Loading @@ -230,6 +250,7 @@ public class InstallStart extends Activity { } } } } android.util.Log.d(TAG, "nextActivity = " + nextActivity); if (nextActivity != null) { if (nextActivity != null) { try { try { startActivity(nextActivity); startActivity(nextActivity); Loading packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java +12 −1 Original line number Original line Diff line number Diff line Loading @@ -84,6 +84,8 @@ public class PackageInstallerActivity extends Activity { static final String EXTRA_ORIGINAL_SOURCE_INFO = "EXTRA_ORIGINAL_SOURCE_INFO"; static final String EXTRA_ORIGINAL_SOURCE_INFO = "EXTRA_ORIGINAL_SOURCE_INFO"; static final String EXTRA_STAGED_SESSION_ID = "EXTRA_STAGED_SESSION_ID"; static final String EXTRA_STAGED_SESSION_ID = "EXTRA_STAGED_SESSION_ID"; static final String EXTRA_APP_SNIPPET = "EXTRA_APP_SNIPPET"; static final String EXTRA_APP_SNIPPET = "EXTRA_APP_SNIPPET"; static final String EXTRA_ORIGINATING_UID_FROM_SESSION_INFO = "EXTRA_ORIGINATING_UID_FROM_SESSION_INFO"; static final String EXTRA_IS_TRUSTED_SOURCE = "EXTRA_IS_TRUSTED_SOURCE"; static final String EXTRA_IS_TRUSTED_SOURCE = "EXTRA_IS_TRUSTED_SOURCE"; private static final String ALLOW_UNKNOWN_SOURCES_KEY = private static final String ALLOW_UNKNOWN_SOURCES_KEY = PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY"; PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY"; Loading @@ -97,6 +99,10 @@ public class PackageInstallerActivity extends Activity { * The package name corresponding to #mOriginatingUid * The package name corresponding to #mOriginatingUid */ */ private String mOriginatingPackage; private String mOriginatingPackage; /** * The package name corresponding to the app updater in the update-ownership confirmation dialog */ private String mOriginatingPackageFromSessionInfo; private int mActivityResultCode = Activity.RESULT_CANCELED; private int mActivityResultCode = Activity.RESULT_CANCELED; private int mPendingUserActionReason = -1; private int mPendingUserActionReason = -1; Loading Loading @@ -149,7 +155,8 @@ public class PackageInstallerActivity extends Activity { viewToEnable = mDialog.requireViewById(R.id.install_confirm_question_update); viewToEnable = mDialog.requireViewById(R.id.install_confirm_question_update); final CharSequence existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(); final CharSequence existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(); final CharSequence requestedUpdateOwnerLabel = getApplicationLabel(mOriginatingPackage); final CharSequence requestedUpdateOwnerLabel = getApplicationLabel(mOriginatingPackageFromSessionInfo); if (!TextUtils.isEmpty(existingUpdateOwnerLabel) if (!TextUtils.isEmpty(existingUpdateOwnerLabel) && mPendingUserActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP) { && mPendingUserActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP) { String updateOwnerString = String updateOwnerString = Loading Loading @@ -382,6 +389,10 @@ public class PackageInstallerActivity extends Activity { mOriginatingUid = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID, Process.INVALID_UID); mOriginatingUid = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID, Process.INVALID_UID); mOriginatingPackage = (mOriginatingUid != Process.INVALID_UID) mOriginatingPackage = (mOriginatingUid != Process.INVALID_UID) ? getPackageNameForUid(mOriginatingUid) : null; ? getPackageNameForUid(mOriginatingUid) : null; int originatingUidFromSessionInfo = intent.getIntExtra(EXTRA_ORIGINATING_UID_FROM_SESSION_INFO, Process.INVALID_UID); mOriginatingPackageFromSessionInfo = (originatingUidFromSessionInfo != Process.INVALID_UID) ? getPackageNameForUid(originatingUidFromSessionInfo) : mCallingPackage; final Object packageSource; final Object packageSource; if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(action)) { if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(action)) { Loading Loading
packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java +34 −13 Original line number Original line Diff line number Diff line Loading @@ -114,12 +114,13 @@ public class InstallStart extends Activity { final int sessionId = (isSessionInstall final int sessionId = (isSessionInstall ? intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, SessionInfo.INVALID_ID) ? intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, SessionInfo.INVALID_ID) : SessionInfo.INVALID_ID); : SessionInfo.INVALID_ID); int originatingUidFromSession = callingUid; if (sessionId != SessionInfo.INVALID_ID) { if (sessionId != SessionInfo.INVALID_ID) { PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId); PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId); if (sessionInfo != null) { if (sessionInfo != null) { callingAttributionTag = sessionInfo.getInstallerAttributionTag(); callingAttributionTag = sessionInfo.getInstallerAttributionTag(); if (sessionInfo.getOriginatingUid() != Process.INVALID_UID) { if (sessionInfo.getOriginatingUid() != Process.INVALID_UID) { originatingUid = sessionInfo.getOriginatingUid(); originatingUidFromSession = sessionInfo.getOriginatingUid(); } } } } } } Loading @@ -136,24 +137,40 @@ public class InstallStart extends Activity { boolean isSystemDownloadsProvider = PackageUtil.getSystemDownloadsProviderInfo( boolean isSystemDownloadsProvider = PackageUtil.getSystemDownloadsProviderInfo( mPackageManager, callingUid) != null; mPackageManager, callingUid) != null; // By default, the originatingUid is callingUid. If the caller is the system download // provider or the documents manager, we parse the originatingUid from the // Intent.EXTRA_ORIGINATING_UID. And we check the appOps permission for the originatingUid // later. if (isDocumentsManager || isSystemDownloadsProvider) { // The originating uid from the intent. We only trust/use this if it comes from either // the document manager app or the downloads provider. It may be Process.INVALID_UID if // the original owner App is not installed on the device now. originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID, Process.INVALID_UID); } boolean isPrivilegedAndKnown = (sourceInfo != null && sourceInfo.isPrivilegedApp()) && boolean isPrivilegedAndKnown = (sourceInfo != null && sourceInfo.isPrivilegedApp()) && intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false); intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false); boolean isInstallPkgPermissionGranted = boolean isInstallPkgPermissionGranted = originatingUid != Process.INVALID_UID checkPermission(Manifest.permission.INSTALL_PACKAGES, /* pid= */ -1, callingUid) && checkPermission(Manifest.permission.INSTALL_PACKAGES, /* pid= */ -1, == PackageManager.PERMISSION_GRANTED; originatingUid) == PackageManager.PERMISSION_GRANTED; boolean isTrustedSource = isPrivilegedAndKnown || isInstallPkgPermissionGranted; boolean isTrustedSource = isPrivilegedAndKnown || isInstallPkgPermissionGranted; if (!isTrustedSource && !isSystemDownloadsProvider && !isDocumentsManager // In general case, the originatingUid is callingUid. If callingUid is INVALID_UID, return && callingUid != Process.INVALID_UID) { // InstallAborted in the check above. When the originatingUid is INVALID_UID here, it means final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, callingUid); // the originatingUid is from the system download manager or the system documents manager, // and the package doesn't exist on the device. For this case, we don't need to check the // permission for the originatingUid. The package doesn't exist. if (!isTrustedSource && originatingUid != Process.INVALID_UID) { final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, originatingUid); if (targetSdkVersion < 0) { if (targetSdkVersion < 0) { Log.e(TAG, "Cannot get target sdk version for uid " + callingUid); Log.e(TAG, "Cannot get target sdk version for uid " + originatingUid); // Invalid originating uid supplied. Abort install. // Invalid originating uid supplied. Abort install. mAbortInstall = true; mAbortInstall = true; } else if (targetSdkVersion >= Build.VERSION_CODES.O && !isUidRequestingPermission( } else if (targetSdkVersion >= Build.VERSION_CODES.O && !isUidRequestingPermission( callingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES)) { originatingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES)) { Log.e(TAG, "Requesting uid " + callingUid + " needs to declare permission " Log.e(TAG, "Requesting uid " + originatingUid + " needs to declare permission " + Manifest.permission.REQUEST_INSTALL_PACKAGES); + Manifest.permission.REQUEST_INSTALL_PACKAGES); mAbortInstall = true; mAbortInstall = true; } } Loading Loading @@ -182,6 +199,7 @@ public class InstallStart extends Activity { } } if (mAbortInstall) { if (mAbortInstall) { android.util.Log.d(TAG, "Abort the installation"); setResult(RESULT_CANCELED); setResult(RESULT_CANCELED); if (mShouldFinish) { if (mShouldFinish) { finish(); finish(); Loading @@ -200,6 +218,8 @@ public class InstallStart extends Activity { callingAttributionTag); callingAttributionTag); nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINAL_SOURCE_INFO, sourceInfo); nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINAL_SOURCE_INFO, sourceInfo); nextActivity.putExtra(Intent.EXTRA_ORIGINATING_UID, originatingUid); nextActivity.putExtra(Intent.EXTRA_ORIGINATING_UID, originatingUid); nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINATING_UID_FROM_SESSION_INFO, originatingUidFromSession); nextActivity.putExtra(PackageInstallerActivity.EXTRA_IS_TRUSTED_SOURCE, isTrustedSource); nextActivity.putExtra(PackageInstallerActivity.EXTRA_IS_TRUSTED_SOURCE, isTrustedSource); if (isSessionInstall) { if (isSessionInstall) { Loading @@ -208,9 +228,9 @@ public class InstallStart extends Activity { } else { } else { Uri packageUri = intent.getData(); Uri packageUri = intent.getData(); if (packageUri != null if (packageUri != null && packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT) && packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT) && (originatingUid == Process.INVALID_UID && canPackageQuery(callingUid, packageUri)) { || canPackageQuery(originatingUid, packageUri))) { // [IMPORTANT] This path is deprecated, but should still work. Only necessary // [IMPORTANT] This path is deprecated, but should still work. Only necessary // features should be added. // features should be added. Loading @@ -230,6 +250,7 @@ public class InstallStart extends Activity { } } } } android.util.Log.d(TAG, "nextActivity = " + nextActivity); if (nextActivity != null) { if (nextActivity != null) { try { try { startActivity(nextActivity); startActivity(nextActivity); Loading
packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java +12 −1 Original line number Original line Diff line number Diff line Loading @@ -84,6 +84,8 @@ public class PackageInstallerActivity extends Activity { static final String EXTRA_ORIGINAL_SOURCE_INFO = "EXTRA_ORIGINAL_SOURCE_INFO"; static final String EXTRA_ORIGINAL_SOURCE_INFO = "EXTRA_ORIGINAL_SOURCE_INFO"; static final String EXTRA_STAGED_SESSION_ID = "EXTRA_STAGED_SESSION_ID"; static final String EXTRA_STAGED_SESSION_ID = "EXTRA_STAGED_SESSION_ID"; static final String EXTRA_APP_SNIPPET = "EXTRA_APP_SNIPPET"; static final String EXTRA_APP_SNIPPET = "EXTRA_APP_SNIPPET"; static final String EXTRA_ORIGINATING_UID_FROM_SESSION_INFO = "EXTRA_ORIGINATING_UID_FROM_SESSION_INFO"; static final String EXTRA_IS_TRUSTED_SOURCE = "EXTRA_IS_TRUSTED_SOURCE"; static final String EXTRA_IS_TRUSTED_SOURCE = "EXTRA_IS_TRUSTED_SOURCE"; private static final String ALLOW_UNKNOWN_SOURCES_KEY = private static final String ALLOW_UNKNOWN_SOURCES_KEY = PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY"; PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY"; Loading @@ -97,6 +99,10 @@ public class PackageInstallerActivity extends Activity { * The package name corresponding to #mOriginatingUid * The package name corresponding to #mOriginatingUid */ */ private String mOriginatingPackage; private String mOriginatingPackage; /** * The package name corresponding to the app updater in the update-ownership confirmation dialog */ private String mOriginatingPackageFromSessionInfo; private int mActivityResultCode = Activity.RESULT_CANCELED; private int mActivityResultCode = Activity.RESULT_CANCELED; private int mPendingUserActionReason = -1; private int mPendingUserActionReason = -1; Loading Loading @@ -149,7 +155,8 @@ public class PackageInstallerActivity extends Activity { viewToEnable = mDialog.requireViewById(R.id.install_confirm_question_update); viewToEnable = mDialog.requireViewById(R.id.install_confirm_question_update); final CharSequence existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(); final CharSequence existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(); final CharSequence requestedUpdateOwnerLabel = getApplicationLabel(mOriginatingPackage); final CharSequence requestedUpdateOwnerLabel = getApplicationLabel(mOriginatingPackageFromSessionInfo); if (!TextUtils.isEmpty(existingUpdateOwnerLabel) if (!TextUtils.isEmpty(existingUpdateOwnerLabel) && mPendingUserActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP) { && mPendingUserActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP) { String updateOwnerString = String updateOwnerString = Loading Loading @@ -382,6 +389,10 @@ public class PackageInstallerActivity extends Activity { mOriginatingUid = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID, Process.INVALID_UID); mOriginatingUid = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID, Process.INVALID_UID); mOriginatingPackage = (mOriginatingUid != Process.INVALID_UID) mOriginatingPackage = (mOriginatingUid != Process.INVALID_UID) ? getPackageNameForUid(mOriginatingUid) : null; ? getPackageNameForUid(mOriginatingUid) : null; int originatingUidFromSessionInfo = intent.getIntExtra(EXTRA_ORIGINATING_UID_FROM_SESSION_INFO, Process.INVALID_UID); mOriginatingPackageFromSessionInfo = (originatingUidFromSessionInfo != Process.INVALID_UID) ? getPackageNameForUid(originatingUidFromSessionInfo) : mCallingPackage; final Object packageSource; final Object packageSource; if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(action)) { if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(action)) { Loading