From 6fc0b2a43de1bff582f3d720540ccb71baf1c52e Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Wed, 11 Aug 2021 22:12:26 +0100 Subject: [PATCH] LibJS: Use Checked for offsets in the GetViewValue AO Fixes #9336. --- .../Libraries/LibJS/Runtime/DataViewPrototype.cpp | 13 ++++++++++--- .../DataView/DataView-invalid-read-and-write.js | 9 +++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 Userland/Libraries/LibJS/Tests/builtins/DataView/DataView-invalid-read-and-write.js diff --git a/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp b/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp index 3aff121995..21d4c81e5d 100644 --- a/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include @@ -87,13 +88,19 @@ static Value get_view_value(GlobalObject& global_object, Value request_index, Va auto view_size = view->byte_length(); auto element_size = sizeof(T); - if (get_index + element_size > view_size) { + + Checked buffer_index = get_index; + buffer_index += view_offset; + + Checked end_index = get_index; + end_index += element_size; + + if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size) { vm.throw_exception(global_object, ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size); return {}; } - auto buffer_index = get_index + view_offset; - return buffer->get_value(buffer_index, false, ArrayBuffer::Order::Unordered, little_endian); + return buffer->get_value(buffer_index.value(), false, ArrayBuffer::Order::Unordered, little_endian); } // 25.3.1.2 SetViewValue ( view, requestIndex, isLittleEndian, type, value ), https://tc39.es/ecma262/#sec-setviewvalue diff --git a/Userland/Libraries/LibJS/Tests/builtins/DataView/DataView-invalid-read-and-write.js b/Userland/Libraries/LibJS/Tests/builtins/DataView/DataView-invalid-read-and-write.js new file mode 100644 index 0000000000..99e8aefbd5 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/DataView/DataView-invalid-read-and-write.js @@ -0,0 +1,9 @@ +test("Issue #9336, integer overflow in get_view_value", () => { + const dataView = new DataView(new ArrayBuffer(16)); + expect(() => { + dataView.getUint32(0xfffffffc); + }).toThrowWithMessage( + RangeError, + "Data view byte offset 4294967292 is out of range for buffer with length 16" + ); +});