From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Buynytskyy Date: Thu, 2 Nov 2023 15:15:48 -0700 Subject: [PATCH] Validate package names passed to the installer. Bug: 308989388 Bug: 307532206 Test: atest android.content.pm.cts.PackageManagerTest (cherry picked from commit 1f445474cd1b902b2e7292a0d24e58f020fd51e7) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a7e48c8d7e00962d335b0076266a5df98d41a21c) Merged-In: I840c9c9af5752b3901d4719a13e7908faa43ab04 Change-Id: I840c9c9af5752b3901d4719a13e7908faa43ab04 --- .../android/content/pm/PackageParser.java | 2 +- .../server/pm/PackageInstallerService.java | 30 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 7f728febe5d9..3da6255ff7e0 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1644,7 +1644,7 @@ public class PackageParser { } } - private static String validateName(String name, boolean requireSeparator, + public static String validateName(String name, boolean requireSeparator, boolean requireFilename) { final int N = name.length(); boolean hasSep = false; diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 7ab0c243ac58..8715b183d142 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -20,6 +20,7 @@ import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; import android.Manifest; +import android.annotation.NonNull; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; @@ -44,6 +45,7 @@ import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageParser; import android.content.pm.ParceledListSlice; import android.content.pm.VersionedPackage; import android.graphics.Bitmap; @@ -540,17 +542,22 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements // App package name and label length is restricted so that really long strings aren't // written to disk. - if (params.appPackageName != null - && params.appPackageName.length() > SessionParams.MAX_PACKAGE_NAME_LENGTH) { + if (params.appPackageName != null && !isValidPackageName(params.appPackageName)) { params.appPackageName = null; } params.appLabel = TextUtils.trimToSize(params.appLabel, PackageItemInfo.MAX_SAFE_LABEL_LENGTH); - String requestedInstallerPackageName = (params.installerPackageName != null - && params.installerPackageName.length() < SessionParams.MAX_PACKAGE_NAME_LENGTH) - ? params.installerPackageName : installerPackageName; + // Validate installer package name. + if (params.installerPackageName != null && !isValidPackageName( + params.installerPackageName)) { + params.installerPackageName = null; + } + + String requestedInstallerPackageName = + params.installerPackageName != null ? params.installerPackageName + : installerPackageName; if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { params.installFlags |= PackageManager.INSTALL_FROM_ADB; @@ -804,6 +811,19 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements throw new IllegalStateException("Failed to allocate session ID"); } + private static boolean isValidPackageName(@NonNull String packageName) { + if (packageName.length() > SessionParams.MAX_PACKAGE_NAME_LENGTH) { + return false; + } + // "android" is a valid package name + String errorMessage = PackageParser.validateName( + packageName, /* requireSeparator= */ false, /* requireFilename */ true); + if (errorMessage != null) { + return false; + } + return true; + } + private File getTmpSessionDir(String volumeUuid) { return Environment.getDataAppDirectory(volumeUuid); }