From 8fa8f0b16c0dc03c2d841405dfb02a707c08d5b0 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Thu, 27 Apr 2017 11:47:35 -0700 Subject: [PATCH] Fix potential OOM in update_verifier Limit the size of each read to 1024 * BLOCKSIZE. (Same as the I/O limit of each transfer command for block based OTA). Bug: 37729708 Test: U_V sets slot successfully on sailfish, and it takes about ~20s (no noticeable time increase) Change-Id: I7a6cdc744fe4c0760e09e0afed75b89c16d8eac3 --- update_verifier/update_verifier.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/update_verifier/update_verifier.cpp b/update_verifier/update_verifier.cpp index 1950cbd8..fdbcfde5 100644 --- a/update_verifier/update_verifier.cpp +++ b/update_verifier/update_verifier.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -142,17 +143,21 @@ static bool read_blocks(const std::string& partition, const std::string& range_s return false; } - static constexpr int BLOCKSIZE = 4096; + static constexpr size_t BLOCKSIZE = 4096; if (lseek64(fd.get(), static_cast(range_start) * BLOCKSIZE, SEEK_SET) == -1) { PLOG(ERROR) << "lseek to " << range_start << " failed"; return false; } - size_t size = (range_end - range_start) * BLOCKSIZE; - std::vector buf(size); - if (!android::base::ReadFully(fd.get(), buf.data(), size)) { - PLOG(ERROR) << "Failed to read blocks " << range_start << " to " << range_end; - return false; + size_t remain = (range_end - range_start) * BLOCKSIZE; + while (remain > 0) { + size_t to_read = std::min(remain, 1024 * BLOCKSIZE); + std::vector buf(to_read); + if (!android::base::ReadFully(fd.get(), buf.data(), to_read)) { + PLOG(ERROR) << "Failed to read blocks " << range_start << " to " << range_end; + return false; + } + remain -= to_read; } blk_count += (range_end - range_start); }