summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java12
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java61
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerException.java5
3 files changed, 58 insertions, 20 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index c3b93b428cb5..1fa37b91b8e8 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -319,9 +319,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
if (type == START_TAG) {
final String tag = in.getName();
if (PackageInstallerSession.TAG_SESSION.equals(tag)) {
- final PackageInstallerSession session = PackageInstallerSession.
- readFromXml(in, mInternalCallback, mContext, mPm,
- mInstallThread.getLooper(), mSessionsDir);
+ final PackageInstallerSession session;
+ try {
+ session = PackageInstallerSession.readFromXml(in, mInternalCallback,
+ mContext, mPm, mInstallThread.getLooper(), mSessionsDir);
+ } catch (Exception e) {
+ Slog.e(TAG, "Could not read session", e);
+ continue;
+ }
+
final long age = System.currentTimeMillis() - session.createdMillis;
final boolean valid;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index fddbd670d1a2..810c399e9f8d 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -351,7 +351,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
mPrepared = prepared;
- mSealed = sealed;
+
+ if (sealed) {
+ synchronized (mLock) {
+ try {
+ sealAndValidateLocked();
+ } catch (PackageManagerException | IOException e) {
+ destroyInternal();
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
final long identity = Binder.clearCallingIdentity();
try {
@@ -667,11 +677,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
Preconditions.checkNotNull(statusReceiver);
- // Cache package manager data without the lock held
- final PackageInfo installedPkgInfo = mPm.getPackageInfo(
- params.appPackageName, PackageManager.GET_SIGNATURES
- | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
-
final boolean wasSealed;
synchronized (mLock) {
assertCallerIsOwnerOrRootLocked();
@@ -696,7 +701,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
wasSealed = mSealed;
if (!mSealed) {
try {
- sealAndValidateLocked(installedPkgInfo);
+ sealAndValidateLocked();
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
} catch (PackageManagerException e) {
// Do now throw an exception here to stay compatible with O and older
destroyInternal();
@@ -730,18 +737,33 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
*
* <p>The session will be sealed after calling this method even if it failed.
*
- * @param pkgInfo The package info for {@link #params}.packagename
+ * @throws PackageManagerException if the session was sealed but something went wrong. If the
+ * session was sealed this is the only possible exception.
*/
- private void sealAndValidateLocked(@Nullable PackageInfo pkgInfo)
- throws PackageManagerException {
+ private void sealAndValidateLocked() throws PackageManagerException, IOException {
assertNoWriteFileTransfersOpenLocked();
+ assertPreparedAndNotDestroyedLocked("sealing of session");
+
+ final PackageInfo pkgInfo = mPm.getPackageInfo(
+ params.appPackageName, PackageManager.GET_SIGNATURES
+ | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
+
+ resolveStageDirLocked();
mSealed = true;
// Verify that stage looks sane with respect to existing application.
// This currently only ensures packageName, versionCode, and certificate
// consistency.
- validateInstallLocked(pkgInfo);
+ try {
+ validateInstallLocked(pkgInfo);
+ } catch (PackageManagerException e) {
+ throw e;
+ } catch (Throwable e) {
+ // Convert all exceptions into package manager exceptions as only those are handled
+ // in the code above
+ throw new PackageManagerException(e);
+ }
// Read transfers from the original owner stay open, but as the session's data
// cannot be modified anymore, there is no leak of information.
@@ -762,11 +784,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
+ "the " + Manifest.permission.INSTALL_PACKAGES + " permission");
}
- // Cache package manager data without the lock held
- final PackageInfo installedPkgInfo = mPm.getPackageInfo(
- params.appPackageName, PackageManager.GET_SIGNATURES
- | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
-
// Only install flags that can be verified by the app the session is transferred to are
// allowed. The parameters can be read via PackageInstaller.SessionInfo.
if (!params.areHiddenOptionsSet()) {
@@ -778,8 +795,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
assertPreparedAndNotSealedLocked("transfer");
try {
- sealAndValidateLocked(installedPkgInfo);
+ sealAndValidateLocked();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
} catch (PackageManagerException e) {
+ // Session is sealed but could not be verified, we need to destroy it
+ destroyInternal();
+ dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
+
throw new IllegalArgumentException("Package is not valid", e);
}
@@ -1539,6 +1562,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
*/
void write(@NonNull XmlSerializer out, @NonNull File sessionsDir) throws IOException {
synchronized (mLock) {
+ if (mDestroyed) {
+ return;
+ }
+
out.startTag(null, TAG_SESSION);
writeIntAttribute(out, ATTR_SESSION_ID, sessionId);
diff --git a/services/core/java/com/android/server/pm/PackageManagerException.java b/services/core/java/com/android/server/pm/PackageManagerException.java
index 0e3f17360e7b..0793b091265e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerException.java
+++ b/services/core/java/com/android/server/pm/PackageManagerException.java
@@ -40,6 +40,11 @@ public class PackageManagerException extends Exception {
this.error = error;
}
+ public PackageManagerException(Throwable e) {
+ super(e);
+ this.error = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ }
+
public static PackageManagerException from(PackageParserException e)
throws PackageManagerException {
throw new PackageManagerException(e.error, e.getMessage(), e.getCause());