Merge "Build adbd apex with different linkages"
diff --git a/apexd/Android.bp b/apexd/Android.bp
index 66b546f..5c6abc4 100644
--- a/apexd/Android.bp
+++ b/apexd/Android.bp
@@ -378,6 +378,7 @@
":gen_corrupt_superblock_apex",
":gen_corrupt_apex",
":gen_capex_without_apex",
+ ":gen_key_mismatch_with_original_capex",
":com.android.apex.cts.shim.v1_prebuilt",
":com.android.apex.cts.shim.v2_prebuilt",
":com.android.apex.cts.shim.v2_wrong_sha_prebuilt",
diff --git a/apexd/apex_file.cpp b/apexd/apex_file.cpp
index 6169ad5..d65d426 100644
--- a/apexd/apex_file.cpp
+++ b/apexd/apex_file.cpp
@@ -39,6 +39,7 @@
using android::base::borrowed_fd;
using android::base::Error;
using android::base::ReadFullyAtOffset;
+using android::base::RemoveFileIfExists;
using android::base::Result;
using android::base::unique_fd;
@@ -426,13 +427,33 @@
return ErrnoError() << "Failed to open decompression destination "
<< GetPath();
}
+
+ // Prepare a guard that deletes the extracted file if anything goes wrong
+ auto decompressed_guard = android::base::make_scope_guard(
+ [&dest_path] { RemoveFileIfExists(dest_path); });
+
+ // Extract the original_apex to dest_path
ret = ExtractEntryToFile(handle, &entry, dest_fd.get());
if (ret < 0) {
return Error() << "Could not decompress to file " << dest_path
<< ErrorCodeString(ret);
}
+ // Post decompression verification
+ auto decompressed_apex = ApexFile::Open(dest_path);
+ if (!decompressed_apex.ok()) {
+ return Error() << "Could not open decompressed APEX: "
+ << decompressed_apex.error();
+ }
+ if (GetBundledPublicKey() != decompressed_apex->GetBundledPublicKey()) {
+ return Error()
+ << "Public key of compressed APEX is different than original APEX";
+ }
+
+ // Verification complete. Accept the decompressed file
+ decompressed_guard.Disable();
LOG(VERBOSE) << "Decompressed " << src_path << " to " << dest_path;
+
return {};
}
diff --git a/apexd/apex_file_test.cpp b/apexd/apex_file_test.cpp
index 98f5a1b..39d664d 100644
--- a/apexd/apex_file_test.cpp
+++ b/apexd/apex_file_test.cpp
@@ -30,6 +30,7 @@
#include "apexd_utils.h"
using android::base::GetExecutableDirectory;
+using android::base::RemoveFileIfExists;
using android::base::Result;
static const std::string kTestDataDir = GetExecutableDirectory() + "/";
@@ -267,6 +268,31 @@
::testing::HasSubstr("Cannot decompress an uncompressed APEX"));
}
+TEST(ApexFileTest, DecompressFailIfPublicKeyNotSameAsOriginal) {
+ const std::string compressed_file_path =
+ kTestDataDir +
+ "com.android.apex.compressed_key_mismatch_with_original.capex";
+ Result<ApexFile> compressed_apex_file = ApexFile::Open(compressed_file_path);
+ ASSERT_RESULT_OK(compressed_apex_file);
+
+ TemporaryFile decompression_file;
+ RemoveFileIfExists(decompression_file.path);
+
+ // Compressed APEX should fail to decompress if public key is different than
+ // original APEX
+ auto result = compressed_apex_file->Decompress(decompression_file.path);
+ ASSERT_FALSE(result.ok());
+ ASSERT_THAT(
+ result.error().message(),
+ ::testing::HasSubstr(
+ "Public key of compressed APEX is different than original APEX"));
+
+ // The decompressed_file should not exist
+ auto exist = PathExists(decompression_file.path);
+ ASSERT_RESULT_OK(exist);
+ ASSERT_FALSE(*exist);
+}
+
} // namespace
} // namespace apex
} // namespace android
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index 0c53cf9..e3733d8 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -119,6 +119,7 @@
static constexpr size_t kLoopDeviceSetupAttempts = 3u;
+// Please DO NOT add new modules to this list without contacting mainline-modularization@ first.
static const std::vector<std::string> kBootstrapApexes = ([]() {
std::vector<std::string> ret = {
"com.android.art",
diff --git a/apexd/apexd_testdata/Android.bp b/apexd/apexd_testdata/Android.bp
index e8e4808..302c13e 100644
--- a/apexd/apexd_testdata/Android.bp
+++ b/apexd/apexd_testdata/Android.bp
@@ -80,6 +80,17 @@
"--output=$(genDir)/com.android.apex.compressed_different_key.capex"
}
+genrule {
+ // Generates a capex which has a different public key than original_apex
+ name: "gen_key_mismatch_with_original_capex",
+ out: ["com.android.apex.compressed_key_mismatch_with_original.capex"],
+ srcs: [":com.android.apex.compressed.v1"],
+ tools: ["soong_zip"],
+ cmd: "unzip -q $(in) -d $(genDir) && " + // unzip input
+ "echo 'different-key' >> $(genDir)/apex_pubkey && " + // modify the public key
+ "$(location soong_zip) -d -C $(genDir) -D $(genDir) -L 9 " +// repack the compressed APEX
+ "-o $(genDir)/com.android.apex.compressed_key_mismatch_with_original.capex",
+}
apex {
name: "com.android.apex.compressed.v1_original",