Loading core/java/android/content/pm/PackageParser.java +5 −4 Original line number Diff line number Diff line Loading @@ -954,6 +954,10 @@ public class PackageParser { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, "No packages found in split"); } // Apk directory is directly nested under the current directory if (files.length == 1 && files[0].isDirectory()) { return parseClusterPackageLite(files[0], flags); } String packageName = null; int versionCode = 0; Loading Loading @@ -1327,12 +1331,9 @@ public class PackageParser { } } pkg.setCodePath(packageDir.getCanonicalPath()); pkg.setCodePath(lite.codePath); pkg.setUse32bitAbi(lite.use32bitAbi); return pkg; } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, "Failed to get path: " + lite.baseCodePath, e); } finally { IoUtils.closeQuietly(assetLoader); } Loading core/java/android/content/pm/parsing/ApkLiteParseUtils.java +4 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,10 @@ public class ApkLiteParseUtils { throw new PackageParser.PackageParserException( PackageManager.INSTALL_PARSE_FAILED_NOT_APK, "No packages found in split"); } // Apk directory is directly nested under the current directory if (files.length == 1 && files[0].isDirectory()) { return parseClusterPackageLite(files[0], flags); } String packageName = null; int versionCode = 0; Loading core/java/android/content/pm/parsing/ApkParseUtils.java +1 −4 Original line number Diff line number Diff line Loading @@ -205,11 +205,8 @@ public class ApkParseUtils { } } return parsingPackage.setCodePath(packageDir.getCanonicalPath()) return parsingPackage.setCodePath(lite.codePath) .setUse32BitAbi(lite.use32bitAbi); } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, "Failed to get path: " + lite.baseCodePath, e); } finally { IoUtils.closeQuietly(assetLoader); } Loading services/core/java/com/android/server/pm/PackageManagerService.java +29 −18 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo; import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles; import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime; import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo; import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive; import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures; import android.Manifest; Loading Loading @@ -361,7 +362,6 @@ import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.PrintWriter; import java.lang.annotation.Retention; Loading Loading @@ -651,6 +651,8 @@ public class PackageManagerService extends IPackageManager.Stub private static final String[] INSTANT_APP_BROADCAST_PERMISSION = new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS }; private static final String RANDOM_DIR_PREFIX = "~~"; final ServiceThread mHandlerThread; final PackageHandler mHandler; Loading Loading @@ -2996,9 +2998,6 @@ public class PackageManagerService extends IPackageManager.Stub } } //delete tmp files deleteTempPackageFiles(); final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get(); // Remove any shared userIDs that have no associated packages Loading Loading @@ -3591,8 +3590,7 @@ public class PackageManagerService extends IPackageManager.Stub getNextCodePath(Environment.getDataAppDirectory(null), packageName); int ret = PackageManager.INSTALL_SUCCEEDED; try { Os.mkdir(dstCodePath.getAbsolutePath(), 0755); Os.chmod(dstCodePath.getAbsolutePath(), 0755); makeDirRecursive(dstCodePath, 0755); for (File srcFile : compressedFiles) { final String srcFileName = srcFile.getName(); final String dstFileName = srcFileName.substring( Loading Loading @@ -9852,8 +9850,12 @@ public class PackageManagerService extends IPackageManager.Stub @GuardedBy("mInstallLock") void removeCodePathLI(File codePath) { if (codePath.isDirectory()) { File codePathParent = codePath.getParentFile(); try { mInstaller.rmPackageDir(codePath.getAbsolutePath()); if (codePathParent.getName().startsWith(RANDOM_DIR_PREFIX)) { mInstaller.rmPackageDir(codePathParent.getAbsolutePath()); } } catch (InstallerException e) { Slog.w(TAG, "Failed to remove code path", e); } Loading Loading @@ -14926,7 +14928,9 @@ public class PackageManagerService extends IPackageManager.Stub final boolean onIncremental = mIncrementalManager != null && isIncrementalPath(beforeCodeFile.getAbsolutePath()); try { makeDirRecursive(afterCodeFile.getParentFile(), 0775); if (onIncremental) { // TODO(b/147371381): fix incremental installation mIncrementalManager.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); } else { Loading Loading @@ -15138,16 +15142,29 @@ public class PackageManagerService extends IPackageManager.Stub } } /** * Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].} * Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist. * Notice that this method doesn't actually create any directory. * * @param targetDir Directory that is two-levels up from the result directory. * @param packageName Name of the package whose code files are to be installed under the result * directory. * @return File object for the directory that should hold the code files of {@code packageName}. */ private File getNextCodePath(File targetDir, String packageName) { File result; SecureRandom random = new SecureRandom(); byte[] bytes = new byte[16]; File firstLevelDir; do { random.nextBytes(bytes); String dirName = RANDOM_DIR_PREFIX + Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP); firstLevelDir = new File(targetDir, dirName); } while (firstLevelDir.exists()); random.nextBytes(bytes); String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP); result = new File(targetDir, packageName + "-" + suffix); } while (result.exists()); return result; return new File(firstLevelDir, packageName + "-" + suffix); } static class PackageInstalledInfo { Loading Loading @@ -17142,12 +17159,6 @@ public class PackageManagerService extends IPackageManager.Stub } } private void deleteTempPackageFiles() { // TODO: Is this used? final FilenameFilter filter = (dir, name) -> name.startsWith("vmdl") && name.endsWith(".tmp"); } @Override public void deletePackageAsUser(String packageName, int versionCode, IPackageDeleteObserver observer, int userId, int flags) { Loading Loading @@ -21477,7 +21488,7 @@ public class PackageManagerService extends IPackageManager.Stub final int absoluteCodePathCount = absoluteCodePaths.size(); for (int i = 0; i < absoluteCodePathCount; i++) { String absoluteCodePath = absoluteCodePaths.get(i); if (absolutePath.startsWith(absoluteCodePath)) { if (absoluteCodePath.startsWith(absolutePath)) { pathValid = true; break; } services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +18 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.nio.file.Path; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.text.SimpleDateFormat; Loading Loading @@ -918,4 +919,21 @@ public class PackageManagerServiceUtils { } return packageSetting.getPermissionsState(); } /** * Recursively create target directory */ public static void makeDirRecursive(File targetDir, int mode) throws ErrnoException { final Path targetDirPath = targetDir.toPath(); final int directoriesCount = targetDirPath.getNameCount(); File currentDir; for (int i = 1; i <= directoriesCount; i++) { currentDir = targetDirPath.subpath(0, i).toFile(); if (currentDir.exists()) { continue; } Os.mkdir(currentDir.getAbsolutePath(), mode); Os.chmod(currentDir.getAbsolutePath(), mode); } } } Loading
core/java/android/content/pm/PackageParser.java +5 −4 Original line number Diff line number Diff line Loading @@ -954,6 +954,10 @@ public class PackageParser { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, "No packages found in split"); } // Apk directory is directly nested under the current directory if (files.length == 1 && files[0].isDirectory()) { return parseClusterPackageLite(files[0], flags); } String packageName = null; int versionCode = 0; Loading Loading @@ -1327,12 +1331,9 @@ public class PackageParser { } } pkg.setCodePath(packageDir.getCanonicalPath()); pkg.setCodePath(lite.codePath); pkg.setUse32bitAbi(lite.use32bitAbi); return pkg; } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, "Failed to get path: " + lite.baseCodePath, e); } finally { IoUtils.closeQuietly(assetLoader); } Loading
core/java/android/content/pm/parsing/ApkLiteParseUtils.java +4 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,10 @@ public class ApkLiteParseUtils { throw new PackageParser.PackageParserException( PackageManager.INSTALL_PARSE_FAILED_NOT_APK, "No packages found in split"); } // Apk directory is directly nested under the current directory if (files.length == 1 && files[0].isDirectory()) { return parseClusterPackageLite(files[0], flags); } String packageName = null; int versionCode = 0; Loading
core/java/android/content/pm/parsing/ApkParseUtils.java +1 −4 Original line number Diff line number Diff line Loading @@ -205,11 +205,8 @@ public class ApkParseUtils { } } return parsingPackage.setCodePath(packageDir.getCanonicalPath()) return parsingPackage.setCodePath(lite.codePath) .setUse32BitAbi(lite.use32bitAbi); } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, "Failed to get path: " + lite.baseCodePath, e); } finally { IoUtils.closeQuietly(assetLoader); } Loading
services/core/java/com/android/server/pm/PackageManagerService.java +29 −18 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo; import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles; import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime; import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo; import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive; import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures; import android.Manifest; Loading Loading @@ -361,7 +362,6 @@ import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.PrintWriter; import java.lang.annotation.Retention; Loading Loading @@ -651,6 +651,8 @@ public class PackageManagerService extends IPackageManager.Stub private static final String[] INSTANT_APP_BROADCAST_PERMISSION = new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS }; private static final String RANDOM_DIR_PREFIX = "~~"; final ServiceThread mHandlerThread; final PackageHandler mHandler; Loading Loading @@ -2996,9 +2998,6 @@ public class PackageManagerService extends IPackageManager.Stub } } //delete tmp files deleteTempPackageFiles(); final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get(); // Remove any shared userIDs that have no associated packages Loading Loading @@ -3591,8 +3590,7 @@ public class PackageManagerService extends IPackageManager.Stub getNextCodePath(Environment.getDataAppDirectory(null), packageName); int ret = PackageManager.INSTALL_SUCCEEDED; try { Os.mkdir(dstCodePath.getAbsolutePath(), 0755); Os.chmod(dstCodePath.getAbsolutePath(), 0755); makeDirRecursive(dstCodePath, 0755); for (File srcFile : compressedFiles) { final String srcFileName = srcFile.getName(); final String dstFileName = srcFileName.substring( Loading Loading @@ -9852,8 +9850,12 @@ public class PackageManagerService extends IPackageManager.Stub @GuardedBy("mInstallLock") void removeCodePathLI(File codePath) { if (codePath.isDirectory()) { File codePathParent = codePath.getParentFile(); try { mInstaller.rmPackageDir(codePath.getAbsolutePath()); if (codePathParent.getName().startsWith(RANDOM_DIR_PREFIX)) { mInstaller.rmPackageDir(codePathParent.getAbsolutePath()); } } catch (InstallerException e) { Slog.w(TAG, "Failed to remove code path", e); } Loading Loading @@ -14926,7 +14928,9 @@ public class PackageManagerService extends IPackageManager.Stub final boolean onIncremental = mIncrementalManager != null && isIncrementalPath(beforeCodeFile.getAbsolutePath()); try { makeDirRecursive(afterCodeFile.getParentFile(), 0775); if (onIncremental) { // TODO(b/147371381): fix incremental installation mIncrementalManager.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); } else { Loading Loading @@ -15138,16 +15142,29 @@ public class PackageManagerService extends IPackageManager.Stub } } /** * Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].} * Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist. * Notice that this method doesn't actually create any directory. * * @param targetDir Directory that is two-levels up from the result directory. * @param packageName Name of the package whose code files are to be installed under the result * directory. * @return File object for the directory that should hold the code files of {@code packageName}. */ private File getNextCodePath(File targetDir, String packageName) { File result; SecureRandom random = new SecureRandom(); byte[] bytes = new byte[16]; File firstLevelDir; do { random.nextBytes(bytes); String dirName = RANDOM_DIR_PREFIX + Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP); firstLevelDir = new File(targetDir, dirName); } while (firstLevelDir.exists()); random.nextBytes(bytes); String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP); result = new File(targetDir, packageName + "-" + suffix); } while (result.exists()); return result; return new File(firstLevelDir, packageName + "-" + suffix); } static class PackageInstalledInfo { Loading Loading @@ -17142,12 +17159,6 @@ public class PackageManagerService extends IPackageManager.Stub } } private void deleteTempPackageFiles() { // TODO: Is this used? final FilenameFilter filter = (dir, name) -> name.startsWith("vmdl") && name.endsWith(".tmp"); } @Override public void deletePackageAsUser(String packageName, int versionCode, IPackageDeleteObserver observer, int userId, int flags) { Loading Loading @@ -21477,7 +21488,7 @@ public class PackageManagerService extends IPackageManager.Stub final int absoluteCodePathCount = absoluteCodePaths.size(); for (int i = 0; i < absoluteCodePathCount; i++) { String absoluteCodePath = absoluteCodePaths.get(i); if (absolutePath.startsWith(absoluteCodePath)) { if (absoluteCodePath.startsWith(absolutePath)) { pathValid = true; break; }
services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +18 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.nio.file.Path; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.text.SimpleDateFormat; Loading Loading @@ -918,4 +919,21 @@ public class PackageManagerServiceUtils { } return packageSetting.getPermissionsState(); } /** * Recursively create target directory */ public static void makeDirRecursive(File targetDir, int mode) throws ErrnoException { final Path targetDirPath = targetDir.toPath(); final int directoriesCount = targetDirPath.getNameCount(); File currentDir; for (int i = 1; i <= directoriesCount; i++) { currentDir = targetDirPath.subpath(0, i).toFile(); if (currentDir.exists()) { continue; } Os.mkdir(currentDir.getAbsolutePath(), mode); Os.chmod(currentDir.getAbsolutePath(), mode); } } }