Commit 8d6f2763 authored by Will Cassella's avatar Will Cassella Committed by Commit Bot

Prevent JS from transferring ArrayBuffers that are used by native code in WebVR.

WebVR apps could potentially transfer ArrayBuffers that were in use by native code.
This CL prevents that by either ensuring that buffers have not been transferred before
writing to them, or preventing the WebApp from moving the internal buffer at all.

Additionally, ArrayBufferView did not null out its base_address_ member when neutering.
This CL adds that, so that unchecked reads and writes cause a null pointer dereference
instead of a (much more) severe use-after-free scenario.

Bug: 957516
Change-Id: I5dbadab03f96d6f742cd41cec16d5c7423cc9b3a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1636091
Commit-Queue: Will Cassella <cassew@google.com>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#664846}
parent 258ab397
......@@ -24,6 +24,10 @@ VREyeParameters::VREyeParameters(
render_height_ = eye_parameters->renderHeight * render_scale;
}
DOMFloat32Array* VREyeParameters::offset() const {
return DOMFloat32Array::Create(offset_->Data(), 3);
}
void VREyeParameters::Trace(blink::Visitor* visitor) {
visitor->Trace(offset_);
visitor->Trace(field_of_view_);
......
......@@ -22,7 +22,8 @@ class VREyeParameters final : public ScriptWrappable {
explicit VREyeParameters(const device::mojom::blink::VREyeParametersPtr&,
double render_scale);
DOMFloat32Array* offset() const { return offset_; }
DOMFloat32Array* offset() const;
DOMFloat32Array* offsetInternal() const { return offset_; }
VRFieldOfView* FieldOfView() const { return field_of_view_; }
uint32_t renderWidth() const { return render_width_; }
uint32_t renderHeight() const { return render_height_; }
......
......@@ -9,15 +9,15 @@
#include <cmath>
namespace blink {
namespace {
// TODO(bajones): All of the matrix math here is temporary. It will be removed
// once the VRService has been updated to allow the underlying VR APIs to
// provide the projection and view matrices directly.
// Build a projection matrix from a field of view and near/far planes.
void ProjectionFromFieldOfView(DOMFloat32Array* out_array,
VRFieldOfView* fov,
void ProjectionFromFieldOfView(blink::DOMFloat32Array* out_array,
blink::VRFieldOfView* fov,
float depth_near,
float depth_far) {
float up_tan = tanf(fov->UpDegrees() * M_PI / 180.0);
......@@ -48,7 +48,7 @@ void ProjectionFromFieldOfView(DOMFloat32Array* out_array,
// Create a matrix from a rotation and translation.
void MatrixfromRotationTranslation(
DOMFloat32Array* out_array,
blink::DOMFloat32Array* out_array,
const base::Optional<WTF::Vector<float>>& rotation,
const base::Optional<WTF::Vector<float>>& translation) {
// Quaternion math
......@@ -90,8 +90,8 @@ void MatrixfromRotationTranslation(
}
// Translate a matrix
void MatrixTranslate(DOMFloat32Array* out_array,
const DOMFloat32Array* translation) {
void MatrixTranslate(blink::DOMFloat32Array* out_array,
const blink::DOMFloat32Array* translation) {
if (!translation)
return;
......@@ -106,7 +106,7 @@ void MatrixTranslate(DOMFloat32Array* out_array,
out[15] = out[3] * x + out[7] * y + out[11] * z + out[15];
}
bool MatrixInvert(DOMFloat32Array* out_array) {
bool MatrixInvert(blink::DOMFloat32Array* out_array) {
float* out = out_array->Data();
float a00 = out[0];
float a01 = out[1];
......@@ -167,6 +167,18 @@ bool MatrixInvert(DOMFloat32Array* out_array) {
return true;
}
blink::DOMFloat32Array* EnsureMatrix(blink::DOMFloat32Array* existing) {
if (!existing || existing->length() != 16) {
return blink::DOMFloat32Array::Create(16);
}
return existing;
}
} // namespace
namespace blink {
VRFrameData::VRFrameData() {
left_projection_matrix_ = DOMFloat32Array::Create(16);
left_view_matrix_ = DOMFloat32Array::Create(16);
......@@ -191,20 +203,24 @@ bool VRFrameData::Update(const device::mojom::blink::VRPosePtr& pose,
}
// Build the projection matrices
left_projection_matrix_ = EnsureMatrix(left_projection_matrix_);
ProjectionFromFieldOfView(left_projection_matrix_, fov_left, depth_near,
depth_far);
right_projection_matrix_ = EnsureMatrix(right_projection_matrix_);
ProjectionFromFieldOfView(right_projection_matrix_, fov_right, depth_near,
depth_far);
// Build the view matrices
left_view_matrix_ = EnsureMatrix(left_view_matrix_);
MatrixfromRotationTranslation(left_view_matrix_, pose->orientation,
pose->position);
right_view_matrix_ = EnsureMatrix(right_view_matrix_);
MatrixfromRotationTranslation(right_view_matrix_, pose->orientation,
pose->position);
if (left_eye && right_eye) {
MatrixTranslate(left_view_matrix_, left_eye->offset());
MatrixTranslate(right_view_matrix_, right_eye->offset());
MatrixTranslate(left_view_matrix_, left_eye->offsetInternal());
MatrixTranslate(right_view_matrix_, right_eye->offsetInternal());
}
if (!MatrixInvert(left_view_matrix_) || !MatrixInvert(right_view_matrix_))
......
......@@ -50,6 +50,7 @@ ArrayBufferView::~ArrayBufferView() {
void ArrayBufferView::Neuter() {
buffer_ = nullptr;
base_address_ = nullptr;
byte_offset_ = 0;
}
......
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