aboutsummaryrefslogtreecommitdiff
path: root/applypatch/imgdiff.cpp
diff options
context:
space:
mode:
authorTao Bao <tbao@google.com>2016-12-17 17:10:04 -0800
committerTao Bao <tbao@google.com>2016-12-28 14:29:48 -0800
commitd37ce8f0821758edc33ad9c42b0bf78ff29b365f (patch)
treec4846f60c04bf4e2cae744844be8f734da288861 /applypatch/imgdiff.cpp
parent344c8eb453f162745cde8f7ae9d7506c6a3ec0ca (diff)
imgdiff: Fix an edge case that leads to infinite loop.
When the input image ends with the magic value sequence of 0x1f, 0x8b, 0x0b (optionally with 0x00), the image parsing code will be stuck in an infinite loop. Test: recovery_component_test passes. Change-Id: Ie3629dfdc41360387b19cc3e0359c95ae4fb998e
Diffstat (limited to 'applypatch/imgdiff.cpp')
-rw-r--r--applypatch/imgdiff.cpp25
1 files changed, 10 insertions, 15 deletions
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp
index 18a15a16..62de726a 100644
--- a/applypatch/imgdiff.cpp
+++ b/applypatch/imgdiff.cpp
@@ -124,6 +124,7 @@
#include "applypatch/imgdiff.h"
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -131,6 +132,9 @@
#include <sys/types.h>
#include <unistd.h>
+#include <android-base/file.h>
+#include <android-base/unique_fd.h>
+
#include <bsdiff.h>
#include <zlib.h>
@@ -382,19 +386,12 @@ unsigned char* ReadImage(const char* filename, int* num_chunks, ImageChunk** chu
}
size_t sz = static_cast<size_t>(st.st_size);
- unsigned char* img = static_cast<unsigned char*>(malloc(sz + 4));
- FILE* f = fopen(filename, "rb");
- if (fread(img, 1, sz, f) != sz) {
+ unsigned char* img = static_cast<unsigned char*>(malloc(sz));
+ android::base::unique_fd fd(open(filename, O_RDONLY));
+ if (!android::base::ReadFully(fd, img, sz)) {
printf("failed to read \"%s\" %s\n", filename, strerror(errno));
- fclose(f);
- return NULL;
+ return nullptr;
}
- fclose(f);
-
- // append 4 zero bytes to the data so we can always search for the
- // four-byte string 1f8b0800 starting at any point in the actual
- // file data, without special-casing the end of the data.
- memset(img+sz, 0, 4);
size_t pos = 0;
@@ -518,10 +515,8 @@ unsigned char* ReadImage(const char* filename, int* num_chunks, ImageChunk** chu
curr->data = p;
for (curr->len = 0; curr->len < (sz - pos); ++curr->len) {
- if (p[curr->len] == 0x1f &&
- p[curr->len+1] == 0x8b &&
- p[curr->len+2] == 0x08 &&
- p[curr->len+3] == 0x00) {
+ if (sz - pos >= 4 && p[curr->len] == 0x1f && p[curr->len + 1] == 0x8b &&
+ p[curr->len + 2] == 0x08 && p[curr->len + 3] == 0x00) {
break;
}
}