diff options
author | Jeff Sharkey <jsharkey@android.com> | 2014-09-11 21:15:37 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2014-09-11 21:24:00 -0700 |
commit | e980804df16c968c14a56b8853886bf5f049f46e (patch) | |
tree | 7b86eadba1751dd5d3c23f33770f9acdfc8ca1d5 /services | |
parent | d6adcef917aac893fd82e7628781145693d6187f (diff) | |
download | frameworks_base-e980804df16c968c14a56b8853886bf5f049f46e.zip frameworks_base-e980804df16c968c14a56b8853886bf5f049f46e.tar.gz frameworks_base-e980804df16c968c14a56b8853886bf5f049f46e.tar.bz2 |
Bring install and install-multiple into parity.
This ensures that both are using (almost) identical logic when
deciding what installs to proceed with. Installs from "pm" for all
users now run as OWNER, and rely solely on INSTALL_ALL_USERS to
express intent. This keeps install session notifications simple.
Since installer UID can vary from installer package name, start
persisting the UID. Also parse some missing flags for install
sessions.
Bug: 17469392
Change-Id: I6d89b1a787aa2024cc4bebf6b9c29317c358e147
Diffstat (limited to 'services')
3 files changed, 48 insertions, 54 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index ed678d2..fa09d48 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -16,9 +16,6 @@ package com.android.server.pm; -import static android.content.pm.PackageManager.INSTALL_ALL_USERS; -import static android.content.pm.PackageManager.INSTALL_FROM_ADB; -import static android.content.pm.PackageManager.INSTALL_REPLACE_EXISTING; import static com.android.internal.util.XmlUtils.readBitmapAttribute; import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; @@ -105,7 +102,7 @@ import java.util.Random; public class PackageInstallerService extends IPackageInstaller.Stub { private static final String TAG = "PackageInstaller"; - private static final boolean LOGD = true; + private static final boolean LOGD = false; // TODO: remove outstanding sessions when installer package goes away // TODO: notify listeners in other users when package has been installed there @@ -117,6 +114,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private static final String ATTR_SESSION_ID = "sessionId"; private static final String ATTR_USER_ID = "userId"; private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName"; + private static final String ATTR_INSTALLER_UID = "installerUid"; private static final String ATTR_CREATED_MILLIS = "createdMillis"; private static final String ATTR_SESSION_STAGE_DIR = "sessionStageDir"; private static final String ATTR_SESSION_STAGE_CID = "sessionStageCid"; @@ -336,6 +334,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { final int sessionId = readIntAttribute(in, ATTR_SESSION_ID); final int userId = readIntAttribute(in, ATTR_USER_ID); final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME); + final int installerUid = readIntAttribute(in, ATTR_INSTALLER_UID, + mPm.getPackageUid(installerPackageName, userId)); final long createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS); final String stageDirRaw = readStringAttribute(in, ATTR_SESSION_STAGE_DIR); final File stageDir = (stageDirRaw != null) ? new File(stageDirRaw) : null; @@ -357,8 +357,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { params.abiOverride = readStringAttribute(in, ATTR_ABI_OVERRIDE); return new PackageInstallerSession(mInternalCallback, mContext, mPm, - mInstallThread.getLooper(), sessionId, userId, installerPackageName, params, - createdMillis, stageDir, stageCid, prepared, sealed); + mInstallThread.getLooper(), sessionId, userId, installerPackageName, installerUid, + params, createdMillis, stageDir, stageCid, prepared, sealed); } private void writeSessionsLocked() { @@ -398,6 +398,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { writeIntAttribute(out, ATTR_USER_ID, session.userId); writeStringAttribute(out, ATTR_INSTALLER_PACKAGE_NAME, session.installerPackageName); + writeIntAttribute(out, ATTR_INSTALLER_UID, session.installerUid); writeLongAttribute(out, ATTR_CREATED_MILLIS, session.createdMillis); if (session.stageDir != null) { writeStringAttribute(out, ATTR_SESSION_STAGE_DIR, @@ -446,26 +447,21 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private int createSessionInternal(SessionParams params, String installerPackageName, int userId) throws IOException { final int callingUid = Binder.getCallingUid(); - mPm.enforceCrossUserPermission(callingUid, userId, true, false, "createSession"); + mPm.enforceCrossUserPermission(callingUid, userId, true, true, "createSession"); - if (mPm.isUserRestricted(UserHandle.getUserId(callingUid), - UserManager.DISALLOW_INSTALL_APPS)) { + if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { throw new SecurityException("User restriction prevents installing"); } - // TODO: double check all possible install flags - if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { - installerPackageName = "com.android.shell"; - - params.installFlags |= INSTALL_FROM_ADB; + params.installFlags |= PackageManager.INSTALL_FROM_ADB; } else { mAppOps.checkPackage(callingUid, installerPackageName); - params.installFlags &= ~INSTALL_FROM_ADB; - params.installFlags &= ~INSTALL_ALL_USERS; - params.installFlags |= INSTALL_REPLACE_EXISTING; + params.installFlags &= ~PackageManager.INSTALL_FROM_ADB; + params.installFlags &= ~PackageManager.INSTALL_ALL_USERS; + params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; } // Defensively resize giant app icons @@ -532,8 +528,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } session = new PackageInstallerSession(mInternalCallback, mContext, mPm, - mInstallThread.getLooper(), sessionId, userId, installerPackageName, params, - createdMillis, stageDir, stageCid, false, false); + mInstallThread.getLooper(), sessionId, userId, installerPackageName, callingUid, + params, createdMillis, stageDir, stageCid, false, false); mSessions.put(sessionId, session); } @@ -688,7 +684,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { @Override public void uninstall(String packageName, int flags, IntentSender statusReceiver, int userId) { - mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "uninstall"); + mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, true, "uninstall"); final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext, statusReceiver, packageName); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 06f550d..4cbc1c4 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -96,6 +96,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final int sessionId; final int userId; final String installerPackageName; + final int installerUid; final SessionParams params; final long createdMillis; @@ -103,9 +104,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final File stageDir; final String stageCid; - /** Note that UID is not persisted; it's always derived at runtime. */ - final int installerUid; - private final AtomicInteger mActiveCount = new AtomicInteger(); private final Object mLock = new Object(); @@ -186,7 +184,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { public PackageInstallerSession(PackageInstallerService.InternalCallback callback, Context context, PackageManagerService pm, Looper looper, int sessionId, int userId, - String installerPackageName, SessionParams params, long createdMillis, + String installerPackageName, int installerUid, SessionParams params, long createdMillis, File stageDir, String stageCid, boolean prepared, boolean sealed) { mCallback = callback; mContext = context; @@ -196,6 +194,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { this.sessionId = sessionId; this.userId = userId; this.installerPackageName = installerPackageName; + this.installerUid = installerUid; this.params = params; this.createdMillis = createdMillis; this.stageDir = stageDir; @@ -209,11 +208,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mPrepared = prepared; mSealed = sealed; - // Always derived at runtime - installerUid = mPm.getPackageUid(installerPackageName, userId); - - if (mPm.checkPermission(android.Manifest.permission.INSTALL_PACKAGES, - installerPackageName) == PackageManager.PERMISSION_GRANTED) { + if ((mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid) + == PackageManager.PERMISSION_GRANTED) || (installerUid == Process.ROOT_UID)) { mPermissionsAccepted = true; } else { mPermissionsAccepted = false; @@ -537,8 +533,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } }; - mPm.installStage(mPackageName, stageDir, stageCid, localObserver, - params, installerPackageName, installerUid, new UserHandle(userId)); + final UserHandle user; + if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { + user = UserHandle.ALL; + } else { + user = new UserHandle(userId); + } + + mPm.installStage(mPackageName, stageDir, stageCid, localObserver, params, + installerPackageName, installerUid, user); } /** @@ -764,8 +767,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static void extractNativeLibraries(File packageDir, String abiOverride) throws PackageManagerException { - if (LOGD) Slog.v(TAG, "extractNativeLibraries()"); - // Always start from a clean slate final File libDir = new File(packageDir, NativeLibraryHelper.LIB_DIR_NAME); NativeLibraryHelper.removeNativeBinariesFromDirLI(libDir, true); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 3e5d514..33d7898 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -7668,16 +7668,11 @@ public class PackageManagerService extends IPackageManager.Stub { public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride, int userId) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, - null); - if (UserHandle.getCallingUserId() != userId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, - "installPackage " + userId); - } + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); + + final int callingUid = Binder.getCallingUid(); + enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); - final File originFile = new File(originPath); - final int uid = Binder.getCallingUid(); if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { try { if (observer != null) { @@ -7688,6 +7683,17 @@ public class PackageManagerService extends IPackageManager.Stub { return; } + if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { + installFlags |= PackageManager.INSTALL_FROM_ADB; + + } else { + // Caller holds INSTALL_PACKAGES permission, so we're less strict + // about installerPackageName. + + installFlags &= ~PackageManager.INSTALL_FROM_ADB; + installFlags &= ~PackageManager.INSTALL_ALL_USERS; + } + UserHandle user; if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { user = UserHandle.ALL; @@ -7695,22 +7701,13 @@ public class PackageManagerService extends IPackageManager.Stub { user = new UserHandle(userId); } - final int filteredInstallFlags; - if (uid == Process.SHELL_UID || uid == 0) { - if (DEBUG_INSTALL) { - Slog.v(TAG, "Install from ADB"); - } - filteredInstallFlags = installFlags | PackageManager.INSTALL_FROM_ADB; - } else { - filteredInstallFlags = installFlags & ~PackageManager.INSTALL_FROM_ADB; - } - - verificationParams.setInstallerUid(uid); + verificationParams.setInstallerUid(callingUid); + final File originFile = new File(originPath); final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); final Message msg = mHandler.obtainMessage(INIT_COPY); - msg.obj = new InstallParams(origin, observer, filteredInstallFlags, + msg.obj = new InstallParams(origin, observer, installFlags, installerPackageName, verificationParams, user, packageAbiOverride); mHandler.sendMessage(msg); } |