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