Mesa (staging/20.1): glsl: Eliminate out-of-bounds triop_vector_insert

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Aug 22 12:05:10 UTC 2020


Module: Mesa
Branch: staging/20.1
Commit: 0beac85a83ee625a5daa0978556fb99478820886
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0beac85a83ee625a5daa0978556fb99478820886

Author: Danylo Piliaiev <danylo.piliaiev at globallogic.com>
Date:   Tue Aug 18 10:41:31 2020 +0300

glsl: Eliminate out-of-bounds triop_vector_insert

Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says:

 "In the subsections described above for array, vector, matrix and
  structure accesses, any out-of-bounds access produced undefined
  behavior.... Out-of-bounds writes may be discarded or overwrite
  other variables of the active program."

Fixes crashes when dereferencing gl_ClipDistance and gl_TessLevel*, e.g:

  int index = -1;
  gl_ClipDistance[index] = -1;

When LowerCombinedClipCullDistance is true.

CC: <mesa-stable at lists.freedesktop.org>
Signed-off-by: Danylo Piliaiev <danylo.piliaiev at globallogic.com>
Reviewed-by: Eric Anholt <eric at anholt.net>
Reviewed-by: Marcin Ślusarz <marcin.slusarz at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6363>
(cherry picked from commit e802bff69ee74983215d0c2b7e213fca6d68a97d)

---

 .pick_status.json                         |  2 +-
 src/compiler/glsl/lower_vector_insert.cpp | 33 ++++++++++++++++++++++++++++++-
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index d1d656619f0..9deca1a64d4 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -292,7 +292,7 @@
         "description": "glsl: Eliminate out-of-bounds triop_vector_insert",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "master_sha": null,
         "because_sha": null
     },
diff --git a/src/compiler/glsl/lower_vector_insert.cpp b/src/compiler/glsl/lower_vector_insert.cpp
index ceaa5887c8a..81ef0491c3a 100644
--- a/src/compiler/glsl/lower_vector_insert.cpp
+++ b/src/compiler/glsl/lower_vector_insert.cpp
@@ -32,7 +32,8 @@ namespace {
 class vector_insert_visitor : public ir_rvalue_visitor {
 public:
    vector_insert_visitor(bool lower_nonconstant_index)
-      : progress(false), lower_nonconstant_index(lower_nonconstant_index)
+      : progress(false), lower_nonconstant_index(lower_nonconstant_index),
+        remove_assignment(false)
    {
       factory.instructions = &factory_instructions;
    }
@@ -43,11 +44,13 @@ public:
    }
 
    virtual void handle_rvalue(ir_rvalue **rv);
+   virtual ir_visitor_status visit_leave(ir_assignment *expr);
 
    ir_factory factory;
    exec_list factory_instructions;
    bool progress;
    bool lower_nonconstant_index;
+   bool remove_assignment;
 };
 
 } /* anonymous namespace */
@@ -68,6 +71,21 @@ vector_insert_visitor::handle_rvalue(ir_rvalue **rv)
    ir_constant *const idx =
       expr->operands[2]->constant_expression_value(factory.mem_ctx);
    if (idx != NULL) {
+      unsigned index = idx->value.u[0];
+
+      if (index >= expr->operands[0]->type->vector_elements) {
+         /* Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says:
+          *
+          *  In the subsections described above for array, vector, matrix and
+          *  structure accesses, any out-of-bounds access produced undefined
+          *  behavior.... Out-of-bounds writes may be discarded or overwrite
+          *  other variables of the active program.
+          */
+         this->remove_assignment = true;
+         this->progress = true;
+         return;
+      }
+
       /* Replace (vector_insert (vec) (scalar) (index)) with a dereference of
        * a new temporary.  The new temporary gets assigned as
        *
@@ -136,6 +154,19 @@ vector_insert_visitor::handle_rvalue(ir_rvalue **rv)
    base_ir->insert_before(factory.instructions);
 }
 
+ir_visitor_status
+vector_insert_visitor::visit_leave(ir_assignment *ir)
+{
+   ir_rvalue_visitor::visit_leave(ir);
+
+   if (this->remove_assignment) {
+      ir->remove();
+      this->remove_assignment = false;
+   }
+
+   return visit_continue;
+}
+
 bool
 lower_vector_insert(exec_list *instructions, bool lower_nonconstant_index)
 {



More information about the mesa-commit mailing list