update_engine: Fix bzip size types.
bzip.cc converted between int32_t and size_t while handling the size of
the passed buffer. While that works with normal values, passing a buffer
of 2GiB or more gets converted to a negative size, then extended to
a 64-bit negative number and then underflows to a 64bit huge value.
This patch uses size_t all the way to handle the buffer size avoiding
the signed/unsigned conversion. bzip2 interface uses an unsigned 32 bit
variable for the size, so we simply fail to compress/decompress blobs
that are 4GiB or bigger.
BUG=chromium:504447
TEST=Ran payload generator on an image with a 2GiB file on it.
Change-Id: I5176691b18d7fb378c677b511015f320ce3e9974
Reviewed-on: https://chromium-review.googlesource.com/282346
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/bzip.cc b/bzip.cc
index 323a080..9b15f10 100644
--- a/bzip.cc
+++ b/bzip.cc
@@ -7,6 +7,8 @@
#include <stdlib.h>
#include <algorithm>
#include <bzlib.h>
+#include <limits>
+
#include "update_engine/utils.h"
using std::string;
@@ -51,7 +53,7 @@
const void* in,
uint32_t in_length)>
bool BzipData(const void* const in,
- const int32_t in_size,
+ const size_t in_size,
chromeos::Blob* const out) {
TEST_AND_RETURN_FALSE(out);
out->clear();
@@ -63,6 +65,8 @@
out->resize(buf_size);
for (;;) {
+ if (buf_size > std::numeric_limits<uint32_t>::max())
+ return false;
uint32_t data_size = buf_size;
int rc = F(out->data(), &data_size, in, in_size);
TEST_AND_RETURN_FALSE(rc == BZ_OUTBUFF_FULL || rc == BZ_OK);
@@ -81,9 +85,7 @@
} // namespace
bool BzipDecompress(const chromeos::Blob& in, chromeos::Blob* out) {
- return BzipData<BzipBuffToBuffDecompress>(in.data(),
- static_cast<int32_t>(in.size()),
- out);
+ return BzipData<BzipBuffToBuffDecompress>(in.data(), in.size(), out);
}
bool BzipCompress(const chromeos::Blob& in, chromeos::Blob* out) {
@@ -92,7 +94,7 @@
namespace {
template<bool F(const void* const in,
- const int32_t in_size,
+ const size_t in_size,
chromeos::Blob* const out)>
bool BzipString(const string& str,
chromeos::Blob* out) {