Commit 5aaeb2fd authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Simplify bounds check

We really just need one check instead of three. This also unifies the
error message to be the same on 32 and 64 bit systems.

Drive-by: Fix potential overflow in {validate_size}.

R=titzer@chromium.org

Bug: chromium:794353
Change-Id: I63c1f5ef53c1f245b9e82bcbf86a5d9ac0d2725e
Reviewed-on: https://chromium-review.googlesource.com/824082Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50071}
parent 577b4c80
...@@ -45,16 +45,20 @@ class Decoder { ...@@ -45,16 +45,20 @@ class Decoder {
enum TraceFlag : bool { kTrace = true, kNoTrace = false }; enum TraceFlag : bool { kTrace = true, kNoTrace = false };
Decoder(const byte* start, const byte* end, uint32_t buffer_offset = 0) Decoder(const byte* start, const byte* end, uint32_t buffer_offset = 0)
: start_(start), pc_(start), end_(end), buffer_offset_(buffer_offset) {} : Decoder(start, start, end, buffer_offset) {}
Decoder(const byte* start, const byte* pc, const byte* end, Decoder(const byte* start, const byte* pc, const byte* end,
uint32_t buffer_offset = 0) uint32_t buffer_offset = 0)
: start_(start), pc_(pc), end_(end), buffer_offset_(buffer_offset) {} : start_(start), pc_(pc), end_(end), buffer_offset_(buffer_offset) {
DCHECK_LE(start, pc);
DCHECK_LE(pc, end);
DCHECK_EQ(static_cast<uint32_t>(end - start), end - start);
}
virtual ~Decoder() {} virtual ~Decoder() {}
inline bool validate_size(const byte* pc, uint32_t length, const char* msg) { inline bool validate_size(const byte* pc, uint32_t length, const char* msg) {
DCHECK_LE(start_, pc); DCHECK_LE(start_, pc);
if (V8_UNLIKELY(pc + length > end_)) { if (V8_UNLIKELY(length > static_cast<uint32_t>(end_ - pc))) {
error(pc, msg); error(pc, msg);
return false; return false;
} }
...@@ -161,16 +165,11 @@ class Decoder { ...@@ -161,16 +165,11 @@ class Decoder {
// Check that at least {size} bytes exist between {pc_} and {end_}. // Check that at least {size} bytes exist between {pc_} and {end_}.
bool checkAvailable(uint32_t size) { bool checkAvailable(uint32_t size) {
uintptr_t pc_overflow_value = std::numeric_limits<uintptr_t>::max() - size; if (V8_UNLIKELY(size > static_cast<uint32_t>(end_ - pc_))) {
if ((uintptr_t)pc_ > pc_overflow_value) {
errorf(pc_, "reading %u bytes would underflow/overflow", size);
return false;
} else if (pc_ < start_ || end_ < (pc_ + size)) {
errorf(pc_, "expected %u bytes, fell off end", size); errorf(pc_, "expected %u bytes, fell off end", size);
return false; return false;
} else {
return true;
} }
return true;
} }
void error(const char* msg) { errorf(pc_, "%s", msg); } void error(const char* msg) { errorf(pc_, "%s", msg); }
...@@ -227,6 +226,8 @@ class Decoder { ...@@ -227,6 +226,8 @@ class Decoder {
// Resets the boundaries of this decoder. // Resets the boundaries of this decoder.
void Reset(const byte* start, const byte* end, uint32_t buffer_offset = 0) { void Reset(const byte* start, const byte* end, uint32_t buffer_offset = 0) {
DCHECK_LE(start, end);
DCHECK_EQ(static_cast<uint32_t>(end - start), end - start);
start_ = start; start_ = start;
pc_ = start; pc_ = start;
end_ = end; end_ = end;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment