summaryrefslogtreecommitdiffstats
path: root/applypatch
diff options
context:
space:
mode:
Diffstat (limited to 'applypatch')
-rw-r--r--applypatch/Android.bp30
-rw-r--r--applypatch/imgdiff.cpp59
-rw-r--r--applypatch/include/applypatch/imgdiff_image.h7
3 files changed, 70 insertions, 26 deletions
diff --git a/applypatch/Android.bp b/applypatch/Android.bp
index 13a962584..0d6d23b90 100644
--- a/applypatch/Android.bp
+++ b/applypatch/Android.bp
@@ -12,6 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["bootable_recovery_applypatch_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "bootable_recovery_applypatch_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
cc_defaults {
name: "applypatch_defaults",
@@ -54,7 +71,7 @@ cc_library_static {
"libbz",
"libedify",
"libotautil",
- "libz",
+ "libz_stable",
],
shared_libs: [
@@ -120,7 +137,7 @@ cc_binary {
"libbase",
"libcrypto",
"liblog",
- "libz",
+ "libz_stable",
"libziparchive",
],
@@ -129,9 +146,9 @@ cc_binary {
],
}
-cc_library_host_static {
+cc_library_static {
name: "libimgdiff",
-
+ host_supported: true,
defaults: [
"applypatch_defaults",
],
@@ -152,14 +169,13 @@ cc_library_host_static {
"liblog",
"libotautil",
"libutils",
- "libz",
+ "libz_stable",
"libziparchive",
],
}
cc_binary_host {
name: "imgdiff",
-
srcs: [
"imgdiff_main.cpp",
],
@@ -180,6 +196,6 @@ cc_binary_host {
"liblog",
"libbrotli",
"libbz",
- "libz",
+ "libz_stable",
],
}
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp
index 6ad4a6105..376c511c2 100644
--- a/applypatch/imgdiff.cpp
+++ b/applypatch/imgdiff.cpp
@@ -682,9 +682,9 @@ bool ZipModeImage::InitializeChunks(const std::string& filename, ZipArchiveHandl
}
// Create a list of deflated zip entries, sorted by offset.
- std::vector<std::pair<std::string, ZipEntry>> temp_entries;
+ std::vector<std::pair<std::string, ZipEntry64>> temp_entries;
std::string name;
- ZipEntry entry;
+ ZipEntry64 entry;
while ((ret = Next(cookie, &entry, &name)) == 0) {
if (entry.method == kCompressDeflated || limit_ > 0) {
temp_entries.emplace_back(name, entry);
@@ -712,8 +712,14 @@ bool ZipModeImage::InitializeChunks(const std::string& filename, ZipArchiveHandl
// Add the end of zip file (mainly central directory) as a normal chunk.
size_t entries_end = 0;
if (!temp_entries.empty()) {
- entries_end = static_cast<size_t>(temp_entries.back().second.offset +
- temp_entries.back().second.compressed_length);
+ CHECK_GE(temp_entries.back().second.offset, 0);
+ if (__builtin_add_overflow(temp_entries.back().second.offset,
+ temp_entries.back().second.compressed_length, &entries_end)) {
+ LOG(ERROR) << "`entries_end` overflows on entry with offset "
+ << temp_entries.back().second.offset << " and compressed_length "
+ << temp_entries.back().second.compressed_length;
+ return false;
+ }
}
CHECK_LT(entries_end, file_content_.size());
chunks_.emplace_back(CHUNK_NORMAL, entries_end, &file_content_,
@@ -735,8 +741,16 @@ bool ZipModeImage::InitializeChunks(const std::string& filename, ZipArchiveHandl
LOG(ERROR) << "Failed to add " << entry_name << " to target chunks";
return false;
}
-
- pos += temp_entries[nextentry].second.compressed_length;
+ if (temp_entries[nextentry].second.compressed_length > std::numeric_limits<size_t>::max()) {
+ LOG(ERROR) << "Entry " << name << " compressed size exceeds size of address space. "
+ << entry.compressed_length;
+ return false;
+ }
+ if (__builtin_add_overflow(pos, temp_entries[nextentry].second.compressed_length, &pos)) {
+ LOG(ERROR) << "`pos` overflows after adding "
+ << temp_entries[nextentry].second.compressed_length;
+ return false;
+ }
++nextentry;
continue;
}
@@ -757,7 +771,13 @@ bool ZipModeImage::InitializeChunks(const std::string& filename, ZipArchiveHandl
}
bool ZipModeImage::AddZipEntryToChunks(ZipArchiveHandle handle, const std::string& entry_name,
- ZipEntry* entry) {
+ ZipEntry64* entry) {
+ if (entry->compressed_length > std::numeric_limits<size_t>::max()) {
+ LOG(ERROR) << "Failed to add " << entry_name
+ << " because's compressed size exceeds size of address space. "
+ << entry->compressed_length;
+ return false;
+ }
size_t compressed_len = entry->compressed_length;
if (compressed_len == 0) return true;
@@ -775,6 +795,12 @@ bool ZipModeImage::AddZipEntryToChunks(ZipArchiveHandle handle, const std::strin
}
} else if (entry->method == kCompressDeflated) {
size_t uncompressed_len = entry->uncompressed_length;
+ if (uncompressed_len > std::numeric_limits<size_t>::max()) {
+ LOG(ERROR) << "Failed to add " << entry_name
+ << " because's compressed size exceeds size of address space. "
+ << uncompressed_len;
+ return false;
+ }
std::vector<uint8_t> uncompressed_data(uncompressed_len);
int ret = ExtractToMemory(handle, entry, uncompressed_data.data(), uncompressed_len);
if (ret != 0) {
@@ -965,7 +991,7 @@ bool ZipModeImage::SplitZipModeImageWithLimit(const ZipModeImage& tgt_image,
used_src_ranges.Insert(src_ranges);
split_src_ranges->push_back(std::move(src_ranges));
}
- src_ranges.Clear();
+ src_ranges = {};
// We don't have enough space for the current chunk; start a new split image and handle
// this chunk there.
@@ -1035,23 +1061,24 @@ bool ZipModeImage::AddSplitImageFromChunkList(const ZipModeImage& tgt_image,
}
ZipModeImage split_tgt_image(false);
- split_tgt_image.Initialize(std::move(aligned_tgt_chunks), {});
+ split_tgt_image.Initialize(aligned_tgt_chunks, {});
split_tgt_image.MergeAdjacentNormalChunks();
- // Construct the dummy source file based on the src_ranges.
- std::vector<uint8_t> src_content;
+ // Construct the split source file based on the split src ranges.
+ std::vector<uint8_t> split_src_content;
for (const auto& r : split_src_ranges) {
size_t end = std::min(src_image.file_content_.size(), r.second * BLOCK_SIZE);
- src_content.insert(src_content.end(), src_image.file_content_.begin() + r.first * BLOCK_SIZE,
- src_image.file_content_.begin() + end);
+ split_src_content.insert(split_src_content.end(),
+ src_image.file_content_.begin() + r.first * BLOCK_SIZE,
+ src_image.file_content_.begin() + end);
}
// We should not have an empty src in our design; otherwise we will encounter an error in
- // bsdiff since src_content.data() == nullptr.
- CHECK(!src_content.empty());
+ // bsdiff since split_src_content.data() == nullptr.
+ CHECK(!split_src_content.empty());
ZipModeImage split_src_image(true);
- split_src_image.Initialize(split_src_chunks, std::move(src_content));
+ split_src_image.Initialize(split_src_chunks, split_src_content);
split_tgt_images->push_back(std::move(split_tgt_image));
split_src_images->push_back(std::move(split_src_image));
diff --git a/applypatch/include/applypatch/imgdiff_image.h b/applypatch/include/applypatch/imgdiff_image.h
index 671605160..b579e56ae 100644
--- a/applypatch/include/applypatch/imgdiff_image.h
+++ b/applypatch/include/applypatch/imgdiff_image.h
@@ -211,7 +211,7 @@ class ZipModeImage : public Image {
bool Initialize(const std::string& filename) override;
- // Initialize a dummy ZipModeImage from an existing ImageChunk vector. For src img pieces, we
+ // Initialize a fake ZipModeImage from an existing ImageChunk vector. For src img pieces, we
// reconstruct a new file_content based on the source ranges; but it's not needed for the tgt img
// pieces; because for each chunk both the data and their offset within the file are unchanged.
void Initialize(const std::vector<ImageChunk>& chunks, const std::vector<uint8_t>& file_content) {
@@ -257,7 +257,8 @@ class ZipModeImage : public Image {
// Initialize image chunks based on the zip entries.
bool InitializeChunks(const std::string& filename, ZipArchiveHandle handle);
// Add the a zip entry to the list.
- bool AddZipEntryToChunks(ZipArchiveHandle handle, const std::string& entry_name, ZipEntry* entry);
+ bool AddZipEntryToChunks(ZipArchiveHandle handle, const std::string& entry_name,
+ ZipEntry64* entry);
// Return the real size of the zip file. (omit the trailing zeros that used for alignment)
bool GetZipFileSize(size_t* input_file_size);
@@ -265,7 +266,7 @@ class ZipModeImage : public Image {
const std::vector<ZipModeImage>& split_src_images,
std::vector<SortedRangeSet>& split_src_ranges,
size_t total_tgt_size);
- // Construct the dummy split images based on the chunks info and source ranges; and move them into
+ // Construct the fake split images based on the chunks info and source ranges; and move them into
// the given vectors. Return true if we add a new split image into |split_tgt_images|, and
// false otherwise.
static bool AddSplitImageFromChunkList(const ZipModeImage& tgt_image,