Zebediah Figura : vkd3d-shader/hlsl: Return false from hlsl_offset_from_deref() if the offset falls out of bounds.

Alexandre Julliard julliard at winehq.org
Thu Feb 24 15:28:55 CST 2022


Module: vkd3d
Branch: master
Commit: 7f166c4da45ada4986999be938dce38626c3e980
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=7f166c4da45ada4986999be938dce38626c3e980

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Thu Feb 24 15:06:15 2022 +0100

vkd3d-shader/hlsl: Return false from hlsl_offset_from_deref() if the offset falls out of bounds.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
Signed-off-by: Francisco Casas <fcasas at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d-shader/hlsl.h                 |  2 +-
 libs/vkd3d-shader/hlsl_codegen.c         | 25 +++++++++++++++++--------
 libs/vkd3d-shader/vkd3d_shader_private.h |  1 +
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index be515e3..043d7fb 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -790,7 +790,7 @@ unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second);
 unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask);
 unsigned int hlsl_swizzle_from_writemask(unsigned int writemask);
 
-bool hlsl_offset_from_deref(const struct hlsl_deref *deref, unsigned int *offset);
+bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset);
 unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl_deref *deref);
 struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
         const struct hlsl_type *type);
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 17a7649..e416647 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -349,15 +349,16 @@ static void copy_propagation_set_value(struct copy_propagation_var_def *var_def,
     }
 }
 
-static struct hlsl_ir_node *copy_propagation_compute_replacement(const struct copy_propagation_state *state,
-        const struct hlsl_deref *deref, unsigned int count, unsigned int *swizzle)
+static struct hlsl_ir_node *copy_propagation_compute_replacement(struct hlsl_ctx *ctx,
+        const struct copy_propagation_state *state, const struct hlsl_deref *deref,
+        unsigned int count, unsigned int *swizzle)
 {
     const struct hlsl_ir_var *var = deref->var;
     struct copy_propagation_var_def *var_def;
     struct hlsl_ir_node *node = NULL;
     unsigned int offset, i;
 
-    if (!hlsl_offset_from_deref(deref, &offset))
+    if (!hlsl_offset_from_deref(ctx, deref, &offset))
         return NULL;
 
     if (!(var_def = copy_propagation_get_var_def(state, var)))
@@ -414,7 +415,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
             return false;
     }
 
-    if (!(new_node = copy_propagation_compute_replacement(state, &load->src, dimx, &swizzle)))
+    if (!(new_node = copy_propagation_compute_replacement(ctx, state, &load->src, dimx, &swizzle)))
         return false;
 
     if (type->type != HLSL_CLASS_OBJECT)
@@ -435,7 +436,7 @@ static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx,
     struct hlsl_ir_node *node;
     unsigned int swizzle;
 
-    if (!(node = copy_propagation_compute_replacement(state, deref, 1, &swizzle)))
+    if (!(node = copy_propagation_compute_replacement(ctx, state, deref, 1, &swizzle)))
         return false;
 
     /* Only HLSL_IR_LOAD can produce an object. */
@@ -468,7 +469,7 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s
     if (!(var_def = copy_propagation_create_var_def(ctx, state, var)))
         return;
 
-    if (hlsl_offset_from_deref(lhs, &offset))
+    if (hlsl_offset_from_deref(ctx, lhs, &offset))
     {
         unsigned int writemask = store->writemask;
 
@@ -1546,7 +1547,7 @@ static bool type_is_single_reg(const struct hlsl_type *type)
     return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR;
 }
 
-bool hlsl_offset_from_deref(const struct hlsl_deref *deref, unsigned int *offset)
+bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset)
 {
     struct hlsl_ir_node *offset_node = deref->offset.node;
 
@@ -1564,6 +1565,14 @@ bool hlsl_offset_from_deref(const struct hlsl_deref *deref, unsigned int *offset
         return false;
 
     *offset = hlsl_ir_constant(offset_node)->value[0].u;
+
+    if (*offset >= deref->var->data_type->reg_size)
+    {
+        hlsl_error(ctx, &deref->offset.node->loc, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS,
+                "Dereference is out of bounds.");
+        return false;
+    }
+
     return true;
 }
 
@@ -1571,7 +1580,7 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl
 {
     unsigned int offset;
 
-    if (hlsl_offset_from_deref(deref, &offset))
+    if (hlsl_offset_from_deref(ctx, deref, &offset))
         return offset;
 
     hlsl_fixme(ctx, &deref->offset.node->loc, "Dereference with non-constant offset of type %s.",
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 1de67f4..5ab8494 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -115,6 +115,7 @@ enum vkd3d_shader_error
     VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION         = 5016,
     VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED             = 5017,
     VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET        = 5018,
+    VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS        = 5019,
 
     VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION       = 5300,
 




More information about the wine-cvs mailing list