Add packageName argument in preparation for per-package lock.

Bug: 201090222
Test: presubmit
Change-Id: Iacee77bf52ed9bb96b425c42de2432ade7c79797
This commit is contained in:
Alex Buynytskyy
2021-11-19 10:01:28 -08:00
parent d7c142e153
commit 39b4943332
7 changed files with 69 additions and 38 deletions

View File

@@ -2050,6 +2050,7 @@ final class InstallPackageHelper {
}
}
final String packageName = pkg.getPackageName();
for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
final String filePath = entry.getKey();
final String signaturePath = entry.getValue();
@@ -2077,10 +2078,13 @@ final class InstallPackageHelper {
try {
// A file may already have fs-verity, e.g. when reused during a split
// install. If the measurement succeeds, no need to attempt to set up.
mPm.mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
mPm.mInstaller.assertFsverityRootHashMatches(packageName, filePath,
rootHash);
} catch (Installer.InstallerException e) {
mPm.mInstaller.installApkVerity(filePath, fd, result.getContentSize());
mPm.mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
mPm.mInstaller.installApkVerity(packageName, filePath, fd,
result.getContentSize());
mPm.mInstaller.assertFsverityRootHashMatches(packageName, filePath,
rootHash);
}
} finally {
IoUtils.closeQuietly(fd);

View File

@@ -497,7 +497,7 @@ public class Installer extends SystemService {
*
* @throws InstallerException if {@code dexopt} fails.
*/
public boolean dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet,
public boolean dexopt(String apkPath, int uid, String pkgName, String instructionSet,
int dexoptNeeded, @Nullable String outputPath, int dexFlags,
String compilerFilter, @Nullable String volumeUuid, @Nullable String classLoaderContext,
@Nullable String seInfo, boolean downgrade, int targetSdkVersion,
@@ -585,11 +585,14 @@ public class Installer extends SystemService {
}
}
public void rmPackageDir(String packageDir) throws InstallerException {
/**
* Remove a directory belonging to a package.
*/
public void rmPackageDir(String packageName, String packageDir) throws InstallerException {
if (!checkBeforeRemote()) return;
BlockGuard.getVmPolicy().onPathAccess(packageDir);
try {
mInstalld.rmPackageDir(packageDir);
mInstalld.rmPackageDir(packageName, packageDir);
} catch (Exception e) {
throw InstallerException.from(e);
}
@@ -662,35 +665,44 @@ public class Installer extends SystemService {
}
}
public void createOatDir(String oatDir, String dexInstructionSet)
/**
* Creates an oat dir for given package and instruction set.
*/
public void createOatDir(String packageName, String oatDir, String dexInstructionSet)
throws InstallerException {
if (!checkBeforeRemote()) return;
try {
mInstalld.createOatDir(oatDir, dexInstructionSet);
mInstalld.createOatDir(packageName, oatDir, dexInstructionSet);
} catch (Exception e) {
throw InstallerException.from(e);
}
}
public void linkFile(String relativePath, String fromBase, String toBase)
/**
* Creates a hardlink for a path.
*/
public void linkFile(String packageName, String relativePath, String fromBase, String toBase)
throws InstallerException {
if (!checkBeforeRemote()) return;
BlockGuard.getVmPolicy().onPathAccess(fromBase);
BlockGuard.getVmPolicy().onPathAccess(toBase);
try {
mInstalld.linkFile(relativePath, fromBase, toBase);
mInstalld.linkFile(packageName, relativePath, fromBase, toBase);
} catch (Exception e) {
throw InstallerException.from(e);
}
}
public void moveAb(String apkPath, String instructionSet, String outputPath)
/**
* Moves oat/vdex/art from "B" set defined by ro.boot.slot_suffix to the default set.
*/
public void moveAb(String packageName, String apkPath, String instructionSet, String outputPath)
throws InstallerException {
if (!checkBeforeRemote()) return;
BlockGuard.getVmPolicy().onPathAccess(apkPath);
BlockGuard.getVmPolicy().onPathAccess(outputPath);
try {
mInstalld.moveAb(apkPath, instructionSet, outputPath);
mInstalld.moveAb(packageName, apkPath, instructionSet, outputPath);
} catch (Exception e) {
throw InstallerException.from(e);
}
@@ -700,35 +712,41 @@ public class Installer extends SystemService {
* Deletes the optimized artifacts generated by ART and returns the number
* of freed bytes.
*/
public long deleteOdex(String apkPath, String instructionSet, String outputPath)
throws InstallerException {
public long deleteOdex(String packageName, String apkPath, String instructionSet,
String outputPath) throws InstallerException {
if (!checkBeforeRemote()) return -1;
BlockGuard.getVmPolicy().onPathAccess(apkPath);
BlockGuard.getVmPolicy().onPathAccess(outputPath);
try {
return mInstalld.deleteOdex(apkPath, instructionSet, outputPath);
return mInstalld.deleteOdex(packageName, apkPath, instructionSet, outputPath);
} catch (Exception e) {
throw InstallerException.from(e);
}
}
public void installApkVerity(String filePath, FileDescriptor verityInput, int contentSize)
throws InstallerException {
/**
* Enables legacy apk-verity for an apk.
*/
public void installApkVerity(String packageName, String filePath, FileDescriptor verityInput,
int contentSize) throws InstallerException {
if (!checkBeforeRemote()) return;
BlockGuard.getVmPolicy().onPathAccess(filePath);
try {
mInstalld.installApkVerity(filePath, verityInput, contentSize);
mInstalld.installApkVerity(packageName, filePath, verityInput, contentSize);
} catch (Exception e) {
throw InstallerException.from(e);
}
}
public void assertFsverityRootHashMatches(String filePath, @NonNull byte[] expectedHash)
throws InstallerException {
/**
* Checks if provided hash matches the file's fs-verity merkle tree root hash.
*/
public void assertFsverityRootHashMatches(String packageName, String filePath,
@NonNull byte[] expectedHash) throws InstallerException {
if (!checkBeforeRemote()) return;
BlockGuard.getVmPolicy().onPathAccess(filePath);
try {
mInstalld.assertFsverityRootHashMatches(filePath, expectedHash);
mInstalld.assertFsverityRootHashMatches(packageName, filePath, expectedHash);
} catch (Exception e) {
throw InstallerException.from(e);
}

View File

@@ -411,6 +411,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
final List<String> paths =
AndroidPackageUtils.getAllCodePathsExcludingResourceOnly(pkg);
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
final String packageName = pkg.getPackageName();
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
for (String path : paths) {
String oatDir = PackageDexOptimizer.getOatDir(
@@ -420,7 +421,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
packagePaths++;
try {
installer.moveAb(path, dexCodeInstructionSet, oatDir);
installer.moveAb(packageName, path, dexCodeInstructionSet, oatDir);
pathsSuccessful++;
} catch (InstallerException e) {
}

View File

@@ -2402,6 +2402,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final List<File> fromFiles = mResolvedInheritedFiles;
final File toDir = stageDir;
final String tempPackageName = toDir.getName();
if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles);
if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) {
@@ -2411,7 +2412,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (isLinkPossible(fromFiles, toDir)) {
if (!mResolvedInstructionSets.isEmpty()) {
final File oatDir = new File(toDir, "oat");
createOatDirs(mResolvedInstructionSets, oatDir);
createOatDirs(tempPackageName, mResolvedInstructionSets, oatDir);
}
// pre-create lib dirs for linking if necessary
if (!mResolvedNativeLibPaths.isEmpty()) {
@@ -2434,7 +2435,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
new File(libDir, archDirPath));
}
}
linkFiles(fromFiles, toDir, mInheritedFilesBase);
linkFiles(tempPackageName, fromFiles, toDir, mInheritedFilesBase);
} else {
// TODO: this should delegate to DCS so the system process
// avoids holding open FDs into containers.
@@ -3529,18 +3530,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new IOException("File: " + pathStr + " outside base: " + baseStr);
}
private void createOatDirs(List<String> instructionSets, File fromDir)
private void createOatDirs(String packageName, List<String> instructionSets, File fromDir)
throws PackageManagerException {
for (String instructionSet : instructionSets) {
try {
mInstaller.createOatDir(fromDir.getAbsolutePath(), instructionSet);
mInstaller.createOatDir(packageName, fromDir.getAbsolutePath(), instructionSet);
} catch (InstallerException e) {
throw PackageManagerException.from(e);
}
}
}
private void linkFile(String relativePath, String fromBase, String toBase) throws IOException {
private void linkFile(String packageName, String relativePath, String fromBase, String toBase)
throws IOException {
try {
// Try
final IncrementalFileStorages incrementalFileStorages = getIncrementalFileStorages();
@@ -3548,21 +3550,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
fromBase, toBase)) {
return;
}
mInstaller.linkFile(relativePath, fromBase, toBase);
mInstaller.linkFile(packageName, relativePath, fromBase, toBase);
} catch (InstallerException | IOException e) {
throw new IOException("failed linkOrCreateDir(" + relativePath + ", "
+ fromBase + ", " + toBase + ")", e);
}
}
private void linkFiles(List<File> fromFiles, File toDir, File fromDir)
private void linkFiles(String packageName, List<File> fromFiles, File toDir, File fromDir)
throws IOException {
for (File fromFile : fromFiles) {
final String relativePath = getRelativePath(fromFile, fromDir);
final String fromBase = fromDir.getAbsolutePath();
final String toBase = toDir.getAbsolutePath();
linkFile(relativePath, fromBase, toBase);
linkFile(packageName, relativePath, fromBase, toBase);
}
Slog.d(TAG, "Linked " + fromFiles.size() + " files into " + toDir);
@@ -4299,7 +4301,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
incrementalFileStorages.cleanUpAndMarkComplete();
}
if (stageDir != null) {
mInstaller.rmPackageDir(stageDir.getAbsolutePath());
final String tempPackageName = stageDir.getName();
mInstaller.rmPackageDir(tempPackageName, stageDir.getAbsolutePath());
}
} catch (InstallerException ignored) {
}

View File

@@ -94,9 +94,10 @@ final class RemovePackageHelper {
}
}
mInstaller.rmPackageDir(codePath.getAbsolutePath());
final String packageName = codePath.getName();
mInstaller.rmPackageDir(packageName, codePath.getAbsolutePath());
if (needRemoveParent) {
mInstaller.rmPackageDir(codePathParent.getAbsolutePath());
mInstaller.rmPackageDir(packageName, codePathParent.getAbsolutePath());
removeCachedResult(codePathParent);
}
} catch (Installer.InstallerException e) {

View File

@@ -894,14 +894,15 @@ final class ScanPackageHelper {
* Returns if forced apk verification can be skipped for the whole package, including splits.
*/
private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
if (!canSkipForcedApkVerification(pkg.getBaseApkPath())) {
final String packageName = pkg.getPackageName();
if (!canSkipForcedApkVerification(packageName, pkg.getBaseApkPath())) {
return false;
}
// TODO: Allow base and splits to be verified individually.
String[] splitCodePaths = pkg.getSplitCodePaths();
if (!ArrayUtils.isEmpty(splitCodePaths)) {
for (int i = 0; i < splitCodePaths.length; i++) {
if (!canSkipForcedApkVerification(splitCodePaths[i])) {
if (!canSkipForcedApkVerification(packageName, splitCodePaths[i])) {
return false;
}
}
@@ -914,7 +915,7 @@ final class ScanPackageHelper {
* whether the apk contains signed root hash. Note that the signer's certificate still needs to
* match one in a trusted source, and should be done separately.
*/
private boolean canSkipForcedApkVerification(String apkPath) {
private boolean canSkipForcedApkVerification(String packageName, String apkPath) {
if (!PackageManagerServiceUtils.isLegacyApkVerityEnabled()) {
return VerityUtils.hasFsverity(apkPath);
}
@@ -926,7 +927,8 @@ final class ScanPackageHelper {
}
synchronized (mPm.mInstallLock) {
// Returns whether the observed root hash matches what kernel has.
mPm.mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
mPm.mInstaller.assertFsverityRootHashMatches(packageName, apkPath,
rootHashObserved);
return true;
}
} catch (Installer.InstallerException | IOException | DigestException

View File

@@ -1043,10 +1043,12 @@ public class DexManager {
public long deleteOptimizedFiles(ArtPackageInfo packageInfo) {
long freedBytes = 0;
boolean hadErrors = false;
final String packageName = packageInfo.getPackageName();
for (String codePath : packageInfo.getCodePaths()) {
for (String isa : packageInfo.getInstructionSets()) {
try {
freedBytes += mInstaller.deleteOdex(codePath, isa, packageInfo.getOatDir());
freedBytes += mInstaller.deleteOdex(packageName, codePath, isa,
packageInfo.getOatDir());
} catch (InstallerException e) {
Log.e(TAG, "Failed deleting oat files for " + codePath, e);
hadErrors = true;