diff options
| author | Tao Bao <tbao@google.com> | 2016-12-17 17:10:04 -0800 |
|---|---|---|
| committer | Tao Bao <tbao@google.com> | 2016-12-28 14:29:48 -0800 |
| commit | d37ce8f0821758edc33ad9c42b0bf78ff29b365f (patch) | |
| tree | c4846f60c04bf4e2cae744844be8f734da288861 /applypatch/imgdiff.cpp | |
| parent | 344c8eb453f162745cde8f7ae9d7506c6a3ec0ca (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.cpp | 25 |
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; } } |
