Merge changes from topic "inc-dis" into sc-dev am: 488522c9c5
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14505818 Change-Id: Ib829e6e00bc843081f8e18ddb6d573c58b541cbc
This commit is contained in:
@@ -323,7 +323,7 @@ ApkResourceContainer::ApkResourceContainer(std::unique_ptr<ZipAssetsProvider> zi
|
||||
|
||||
Result<std::unique_ptr<ApkResourceContainer>> ApkResourceContainer::FromPath(
|
||||
const std::string& path) {
|
||||
auto zip_assets = ZipAssetsProvider::Create(path);
|
||||
auto zip_assets = ZipAssetsProvider::Create(path, 0 /* flags */);
|
||||
if (zip_assets == nullptr) {
|
||||
return Error("failed to load zip assets");
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
namespace android::idmap2 {
|
||||
|
||||
Result<XmlParser> CreateTestParser(const std::string& test_file) {
|
||||
auto zip = ZipAssetsProvider::Create(GetTestDataPath() + "/target/target.apk");
|
||||
auto zip = ZipAssetsProvider::Create(GetTestDataPath() + "/target/target.apk", 0 /* flags */);
|
||||
if (zip == nullptr) {
|
||||
return Error("Failed to open zip file");
|
||||
}
|
||||
|
||||
@@ -1289,6 +1289,10 @@ public final class LoadedApk {
|
||||
throw new AssertionError("null split not found");
|
||||
}
|
||||
|
||||
if (Process.myUid() == mApplicationInfo.uid) {
|
||||
ResourcesManager.getInstance().initializeApplicationPaths(mResDir, splitPaths);
|
||||
}
|
||||
|
||||
mResources = ResourcesManager.getInstance().getResources(null, mResDir,
|
||||
splitPaths, mLegacyOverlayDirs, mOverlayPaths,
|
||||
mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(),
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
import android.os.Trace;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
@@ -260,6 +261,12 @@ public class ResourcesManager {
|
||||
*/
|
||||
private final UpdateHandler mUpdateCallbacks = new UpdateHandler();
|
||||
|
||||
/**
|
||||
* The set of APK paths belonging to this process. This is used to disable incremental
|
||||
* installation crash protections on these APKs so the app either behaves as expects or crashes.
|
||||
*/
|
||||
private final ArraySet<String> mApplicationOwnedApks = new ArraySet<>();
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public ResourcesManager() {
|
||||
}
|
||||
@@ -424,6 +431,32 @@ public class ResourcesManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the set of APKs owned by the application running in this process.
|
||||
*/
|
||||
public void initializeApplicationPaths(@NonNull String sourceDir,
|
||||
@Nullable String[] splitDirs) {
|
||||
synchronized (mLock) {
|
||||
if (mApplicationOwnedApks.isEmpty()) {
|
||||
addApplicationPathsLocked(sourceDir, splitDirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the set of APKs owned by the application running in this process.
|
||||
*
|
||||
* This method only appends to the set of APKs owned by this process because the previous APKs
|
||||
* paths still belong to the application running in this process.
|
||||
*/
|
||||
private void addApplicationPathsLocked(@NonNull String sourceDir,
|
||||
@Nullable String[] splitDirs) {
|
||||
mApplicationOwnedApks.add(sourceDir);
|
||||
if (splitDirs != null) {
|
||||
mApplicationOwnedApks.addAll(Arrays.asList(splitDirs));
|
||||
}
|
||||
}
|
||||
|
||||
private static String overlayPathToIdmapPath(String path) {
|
||||
return "/data/resource-cache/" + path.substring(1).replace('/', '@') + "@idmap";
|
||||
}
|
||||
@@ -445,13 +478,17 @@ public class ResourcesManager {
|
||||
}
|
||||
}
|
||||
|
||||
// We must load this from disk.
|
||||
int flags = 0;
|
||||
if (key.sharedLib) {
|
||||
flags |= ApkAssets.PROPERTY_DYNAMIC;
|
||||
}
|
||||
if (mApplicationOwnedApks.contains(key.path)) {
|
||||
flags |= ApkAssets.PROPERTY_DISABLE_INCREMENTAL_HARDENING;
|
||||
}
|
||||
if (key.overlay) {
|
||||
apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(key.path),
|
||||
0 /*flags*/);
|
||||
apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(key.path), flags);
|
||||
} else {
|
||||
apkAssets = ApkAssets.loadFromPath(key.path,
|
||||
key.sharedLib ? ApkAssets.PROPERTY_DYNAMIC : 0);
|
||||
apkAssets = ApkAssets.loadFromPath(key.path, flags);
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
@@ -1437,6 +1474,10 @@ public class ResourcesManager {
|
||||
String[] copiedResourceDirs = combinedOverlayPaths(appInfo.resourceDirs,
|
||||
appInfo.overlayPaths);
|
||||
|
||||
if (appInfo.uid == myUid) {
|
||||
addApplicationPathsLocked(baseCodePath, copiedSplitDirs);
|
||||
}
|
||||
|
||||
final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
|
||||
final int implCount = mResourceImpls.size();
|
||||
for (int i = 0; i < implCount; i++) {
|
||||
|
||||
@@ -69,6 +69,12 @@ public final class ApkAssets {
|
||||
*/
|
||||
private static final int PROPERTY_OVERLAY = 1 << 3;
|
||||
|
||||
/**
|
||||
* The apk assets is owned by the application running in this process and incremental crash
|
||||
* protections for this APK must be disabled.
|
||||
*/
|
||||
public static final int PROPERTY_DISABLE_INCREMENTAL_HARDENING = 1 << 4;
|
||||
|
||||
/** Flags that change the behavior of loaded apk assets. */
|
||||
@IntDef(prefix = { "PROPERTY_" }, value = {
|
||||
PROPERTY_SYSTEM,
|
||||
|
||||
@@ -212,10 +212,11 @@ static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, const format_type_t forma
|
||||
std::unique_ptr<ApkAssets> apk_assets;
|
||||
switch (format) {
|
||||
case FORMAT_APK: {
|
||||
auto assets = MultiAssetsProvider::Create(std::move(loader_assets),
|
||||
ZipAssetsProvider::Create(path.c_str()));
|
||||
apk_assets = ApkAssets::Load(std::move(assets), property_flags);
|
||||
break;
|
||||
auto assets = MultiAssetsProvider::Create(std::move(loader_assets),
|
||||
ZipAssetsProvider::Create(path.c_str(),
|
||||
property_flags));
|
||||
apk_assets = ApkAssets::Load(std::move(assets), property_flags);
|
||||
break;
|
||||
}
|
||||
case FORMAT_IDMAP:
|
||||
apk_assets = ApkAssets::LoadOverlay(path.c_str(), property_flags);
|
||||
@@ -271,11 +272,13 @@ static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, const format_type_t
|
||||
std::unique_ptr<const ApkAssets> apk_assets;
|
||||
switch (format) {
|
||||
case FORMAT_APK: {
|
||||
auto assets = MultiAssetsProvider::Create(
|
||||
std::move(loader_assets),
|
||||
ZipAssetsProvider::Create(std::move(dup_fd), friendly_name_utf8.c_str()));
|
||||
apk_assets = ApkAssets::Load(std::move(assets), property_flags);
|
||||
break;
|
||||
auto assets =
|
||||
MultiAssetsProvider::Create(std::move(loader_assets),
|
||||
ZipAssetsProvider::Create(std::move(dup_fd),
|
||||
friendly_name_utf8.c_str(),
|
||||
property_flags));
|
||||
apk_assets = ApkAssets::Load(std::move(assets), property_flags);
|
||||
break;
|
||||
}
|
||||
case FORMAT_ARSC:
|
||||
apk_assets = ApkAssets::LoadTable(
|
||||
@@ -336,12 +339,16 @@ static jlong NativeLoadFromFdOffset(JNIEnv* env, jclass /*clazz*/, const format_
|
||||
std::unique_ptr<const ApkAssets> apk_assets;
|
||||
switch (format) {
|
||||
case FORMAT_APK: {
|
||||
auto assets = MultiAssetsProvider::Create(
|
||||
std::move(loader_assets),
|
||||
ZipAssetsProvider::Create(std::move(dup_fd), friendly_name_utf8.c_str(),
|
||||
static_cast<off64_t>(offset), static_cast<off64_t>(length)));
|
||||
apk_assets = ApkAssets::Load(std::move(assets), property_flags);
|
||||
break;
|
||||
auto assets =
|
||||
MultiAssetsProvider::Create(std::move(loader_assets),
|
||||
ZipAssetsProvider::Create(std::move(dup_fd),
|
||||
friendly_name_utf8.c_str(),
|
||||
property_flags,
|
||||
static_cast<off64_t>(offset),
|
||||
static_cast<off64_t>(
|
||||
length)));
|
||||
apk_assets = ApkAssets::Load(std::move(assets), property_flags);
|
||||
break;
|
||||
}
|
||||
case FORMAT_ARSC:
|
||||
apk_assets = ApkAssets::LoadTable(
|
||||
|
||||
@@ -40,7 +40,7 @@ ApkAssets::ApkAssets(std::unique_ptr<Asset> resources_asset,
|
||||
loaded_idmap_(std::move(loaded_idmap)) {}
|
||||
|
||||
std::unique_ptr<ApkAssets> ApkAssets::Load(const std::string& path, package_property_t flags) {
|
||||
return Load(ZipAssetsProvider::Create(path), flags);
|
||||
return Load(ZipAssetsProvider::Create(path, flags), flags);
|
||||
}
|
||||
|
||||
std::unique_ptr<ApkAssets> ApkAssets::LoadFromFd(base::unique_fd fd,
|
||||
@@ -91,7 +91,7 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap_path,
|
||||
overlay_assets = EmptyAssetsProvider::Create(overlay_path);
|
||||
} else {
|
||||
// The overlay should be an APK.
|
||||
overlay_assets = ZipAssetsProvider::Create(overlay_path);
|
||||
overlay_assets = ZipAssetsProvider::Create(overlay_path, flags);
|
||||
}
|
||||
if (overlay_assets == nullptr) {
|
||||
return {};
|
||||
|
||||
@@ -85,12 +85,14 @@ const std::string& ZipAssetsProvider::PathOrDebugName::GetDebugName() const {
|
||||
}
|
||||
|
||||
ZipAssetsProvider::ZipAssetsProvider(ZipArchiveHandle handle, PathOrDebugName&& path,
|
||||
time_t last_mod_time)
|
||||
package_property_t flags, time_t last_mod_time)
|
||||
: zip_handle_(handle, ::CloseArchive),
|
||||
name_(std::forward<PathOrDebugName>(path)),
|
||||
flags_(flags),
|
||||
last_mod_time_(last_mod_time) {}
|
||||
|
||||
std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(std::string path) {
|
||||
std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(std::string path,
|
||||
package_property_t flags) {
|
||||
ZipArchiveHandle handle;
|
||||
if (int32_t result = OpenArchive(path.c_str(), &handle); result != 0) {
|
||||
LOG(ERROR) << "Failed to open APK '" << path << "': " << ::ErrorCodeString(result);
|
||||
@@ -109,11 +111,12 @@ std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(std::string path) {
|
||||
|
||||
return std::unique_ptr<ZipAssetsProvider>(
|
||||
new ZipAssetsProvider(handle, PathOrDebugName{std::move(path),
|
||||
true /* is_path */}, sb.st_mtime));
|
||||
true /* is_path */}, flags, sb.st_mtime));
|
||||
}
|
||||
|
||||
std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(base::unique_fd fd,
|
||||
std::string friendly_name,
|
||||
package_property_t flags,
|
||||
off64_t offset,
|
||||
off64_t len) {
|
||||
ZipArchiveHandle handle;
|
||||
@@ -140,7 +143,7 @@ std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(base::unique_fd fd,
|
||||
|
||||
return std::unique_ptr<ZipAssetsProvider>(
|
||||
new ZipAssetsProvider(handle, PathOrDebugName{std::move(friendly_name),
|
||||
false /* is_path */}, sb.st_mtime));
|
||||
false /* is_path */}, flags, sb.st_mtime));
|
||||
}
|
||||
|
||||
std::unique_ptr<Asset> ZipAssetsProvider::OpenInternal(const std::string& path,
|
||||
@@ -161,10 +164,11 @@ std::unique_ptr<Asset> ZipAssetsProvider::OpenInternal(const std::string& path,
|
||||
|
||||
const int fd = GetFileDescriptor(zip_handle_.get());
|
||||
const off64_t fd_offset = GetFileDescriptorOffset(zip_handle_.get());
|
||||
const bool incremental_hardening = (flags_ & PROPERTY_DISABLE_INCREMENTAL_HARDENING) == 0U;
|
||||
incfs::IncFsFileMap asset_map;
|
||||
if (entry.method == kCompressDeflated) {
|
||||
if (!asset_map.Create(fd, entry.offset + fd_offset, entry.compressed_length,
|
||||
name_.GetDebugName().c_str())) {
|
||||
name_.GetDebugName().c_str(), incremental_hardening)) {
|
||||
LOG(ERROR) << "Failed to mmap file '" << path << "' in APK '" << name_.GetDebugName()
|
||||
<< "'";
|
||||
return {};
|
||||
@@ -181,7 +185,7 @@ std::unique_ptr<Asset> ZipAssetsProvider::OpenInternal(const std::string& path,
|
||||
}
|
||||
|
||||
if (!asset_map.Create(fd, entry.offset + fd_offset, entry.uncompressed_length,
|
||||
name_.GetDebugName().c_str())) {
|
||||
name_.GetDebugName().c_str(), incremental_hardening)) {
|
||||
LOG(ERROR) << "Failed to mmap file '" << path << "' in APK '" << name_.GetDebugName() << "'";
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "CtsResourcesLoaderTests"
|
||||
},
|
||||
{
|
||||
"name": "ResourcesHardeningTest"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -80,9 +80,12 @@ struct AssetsProvider {
|
||||
|
||||
// Supplies assets from a zip archive.
|
||||
struct ZipAssetsProvider : public AssetsProvider {
|
||||
static std::unique_ptr<ZipAssetsProvider> Create(std::string path);
|
||||
static std::unique_ptr<ZipAssetsProvider> Create(std::string path,
|
||||
package_property_t flags);
|
||||
|
||||
static std::unique_ptr<ZipAssetsProvider> Create(base::unique_fd fd,
|
||||
std::string friendly_name,
|
||||
package_property_t flags,
|
||||
off64_t offset = 0,
|
||||
off64_t len = kUnknownLength);
|
||||
|
||||
@@ -101,7 +104,8 @@ struct ZipAssetsProvider : public AssetsProvider {
|
||||
|
||||
private:
|
||||
struct PathOrDebugName;
|
||||
ZipAssetsProvider(ZipArchive* handle, PathOrDebugName&& path, time_t last_mod_time);
|
||||
ZipAssetsProvider(ZipArchive* handle, PathOrDebugName&& path, package_property_t flags,
|
||||
time_t last_mod_time);
|
||||
|
||||
struct PathOrDebugName {
|
||||
PathOrDebugName(std::string&& value, bool is_path);
|
||||
@@ -119,6 +123,7 @@ struct ZipAssetsProvider : public AssetsProvider {
|
||||
|
||||
std::unique_ptr<ZipArchive, void (*)(ZipArchive*)> zip_handle_;
|
||||
PathOrDebugName name_;
|
||||
package_property_t flags_;
|
||||
time_t last_mod_time_;
|
||||
};
|
||||
|
||||
|
||||
@@ -92,6 +92,10 @@ enum : package_property_t {
|
||||
|
||||
// The package is a RRO.
|
||||
PROPERTY_OVERLAY = 1U << 3U,
|
||||
|
||||
// The apk assets is owned by the application running in this process and incremental crash
|
||||
// protections for this APK must be disabled.
|
||||
PROPERTY_DISABLE_INCREMENTAL_HARDENING = 1U << 4U,
|
||||
};
|
||||
|
||||
struct OverlayableInfo {
|
||||
|
||||
Reference in New Issue
Block a user