Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1552)

Unified Diff: chrome/browser/android/vr_shell/vr_shell_gl.cc

Issue 2950233002: Validate untrusted VR mojo inputs into browser process (Closed)
Patch Set: add test and rebase Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/vr_shell/vr_shell_gl.cc
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc
index 13b3df6c35d0c9763e0ee6dc14fbbfdb07c8b20d..eb2f9c6ae9742b1bdaf4d9e844480218cba2ace4 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.cc
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -356,6 +356,13 @@ void VrShellGl::SubmitFrame(int16_t frame_index,
if (!submit_client_.get())
return;
+ if (frame_index < 0 ||
+ !webvr_frame_oustanding_[frame_index % kPoseRingBufferSize]) {
+ mojo::ReportBadMessage("SubmitFrame called with an invalid frame_index");
+ binding_.Close();
+ return;
+ }
+
webvr_time_js_submit_[frame_index % kPoseRingBufferSize] =
base::TimeTicks::Now();
@@ -432,6 +439,7 @@ void VrShellGl::InitializeRenderer() {
device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get(), &head_pose);
webvr_head_pose_.assign(kPoseRingBufferSize, head_pose);
webvr_time_pose_.assign(kPoseRingBufferSize, base::TimeTicks());
+ webvr_frame_oustanding_.assign(kPoseRingBufferSize, false);
webvr_time_js_submit_.assign(kPoseRingBufferSize, base::TimeTicks());
std::vector<gvr::BufferSpec> specs;
@@ -837,6 +845,7 @@ void VrShellGl::DrawFrame(int16_t frame_index) {
static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize),
"kPoseRingBufferSize must be a power of 2");
head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize];
+ webvr_frame_oustanding_[frame_index % kPoseRingBufferSize] = false;
} else {
device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get(), &head_pose);
}
@@ -1353,14 +1362,45 @@ void VrShellGl::ForceExitVr() {
browser_->ForceExitVr();
}
+namespace {
+bool ValidateRect(const gfx::RectF& bounds) {
+ // Bounds should be between 0 and 1, with positive width/height.
+ // We simply clamp to [0,1], but still validate that the bounds are not NAN.
+ return !std::isnan(bounds.width()) && !std::isnan(bounds.height()) &&
+ !std::isnan(bounds.x()) && !std::isnan(bounds.y());
+}
+
+gfx::RectF ClampRect(gfx::RectF bounds) {
+ bounds.AdjustToFit(gfx::RectF(0, 0, 1, 1));
+ return bounds;
+}
+
+} // namespace
+
void VrShellGl::UpdateLayerBounds(int16_t frame_index,
const gfx::RectF& left_bounds,
const gfx::RectF& right_bounds,
const gfx::Size& source_size) {
+ if (!ValidateRect(left_bounds) || !ValidateRect(right_bounds)) {
+ mojo::ReportBadMessage("UpdateLayerBounds called with invalid bounds");
+ binding_.Close();
+ return;
+ }
+
+ if (frame_index >= 0 &&
+ !webvr_frame_oustanding_[frame_index % kPoseRingBufferSize]) {
+ mojo::ReportBadMessage("UpdateLayerBounds called with invalid frame_index");
+ binding_.Close();
+ return;
+ }
+
if (frame_index < 0) {
- webvr_left_viewport_->SetSourceUv(UVFromGfxRect(left_bounds));
- webvr_right_viewport_->SetSourceUv(UVFromGfxRect(right_bounds));
+ webvr_left_viewport_->SetSourceUv(UVFromGfxRect(ClampRect(left_bounds)));
+ webvr_right_viewport_->SetSourceUv(UVFromGfxRect(ClampRect(right_bounds)));
CreateOrResizeWebVRSurface(source_size);
+
+ // clear all pending bounds
+ pending_bounds_ = std::queue<std::pair<uint8_t, WebVrBounds>>();
} else {
pending_bounds_.emplace(
frame_index, WebVrBounds(left_bounds, right_bounds, source_size));
@@ -1397,6 +1437,7 @@ void VrShellGl::SendVSync(base::TimeDelta time, GetVSyncCallback callback) {
prediction_nanos);
webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat;
+ webvr_frame_oustanding_[frame_index % kPoseRingBufferSize] = true;
webvr_time_pose_[frame_index % kPoseRingBufferSize] = base::TimeTicks::Now();
std::move(callback).Run(

Powered by Google App Engine
This is Rietveld 408576698