Mesa (master): draw: check for an integer overflow when computing stride

Zack Rusin zack at kemper.freedesktop.org
Mon Jul 1 20:51:00 UTC 2013


Module: Mesa
Branch: master
Commit: 2f13f28120fdfe2f5a64e87b4ec19db94bf63713
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2f13f28120fdfe2f5a64e87b4ec19db94bf63713

Author: Zack Rusin <zackr at vmware.com>
Date:   Tue Jun 25 16:14:06 2013 -0400

draw: check for an integer overflow when computing stride

Our buffer overflow arithmetic was susceptible to integer
overflows which was the buffer overflow logic to break.
Lets use the llvm overflow intrinsics to check for integer
overflows while computing the stride/needed buffer size.

Signed-off-by: Zack Rusin <zackr at vmware.com>

---

 src/gallium/auxiliary/draw/draw_llvm.c |   53 ++++++++++++++++++++++++++------
 1 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index f27776a..c1b4acd 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -699,6 +699,13 @@ generate_fetch(struct gallivm_state *gallivm,
    LLVMValueRef temp_ptr =
       lp_build_alloca(gallivm,
                       lp_build_vec_type(gallivm, lp_float32_vec4_type()), "");
+   LLVMValueRef ofbit, oresult;
+   LLVMTypeRef oelems[2] = {
+      LLVMInt32TypeInContext(gallivm->context),
+      LLVMInt1TypeInContext(gallivm->context)
+   };
+   LLVMTypeRef otype = LLVMStructTypeInContext(gallivm->context,
+                                               oelems, 2, FALSE);
    struct lp_build_if_state if_ctx;
 
    if (velem->instance_divisor) {
@@ -708,23 +715,49 @@ generate_fetch(struct gallivm_state *gallivm,
                             "instance_divisor");
    }
 
-   stride = LLVMBuildMul(builder, vb_stride, index, "");
+   oresult = lp_build_intrinsic_binary(builder,
+                                       "llvm.umul.with.overflow.i32",
+                                       otype, vb_stride, index);
+   ofbit = LLVMBuildExtractValue(builder, oresult, 1, "");
+   stride = LLVMBuildExtractValue(builder, oresult, 0, "");
+
+   oresult = lp_build_intrinsic_binary(builder,
+                                       "llvm.uadd.with.overflow.i32",
+                                       otype, stride, vb_buffer_offset);
+   ofbit = LLVMBuildOr(
+      builder, ofbit,
+      LLVMBuildExtractValue(builder, oresult,  1, ""),
+      "");
+   stride = LLVMBuildExtractValue(builder, oresult, 0, "");
+
+   oresult = lp_build_intrinsic_binary(
+      builder,
+      "llvm.uadd.with.overflow.i32",
+      otype, stride,
+      lp_build_const_int32(gallivm, velem->src_offset));
+   ofbit = LLVMBuildOr(
+      builder, ofbit,
+      LLVMBuildExtractValue(builder, oresult, 1, ""),
+      "");
+   stride = LLVMBuildExtractValue(builder, oresult,  0, "");
 
-   stride = LLVMBuildAdd(builder, stride,
-                         vb_buffer_offset,
-                         "");
-   stride = LLVMBuildAdd(builder, stride,
-                         lp_build_const_int32(gallivm, velem->src_offset),
-                         "");
-   needed_buffer_size = LLVMBuildAdd(
-      builder, stride,
+
+   oresult = lp_build_intrinsic_binary(
+      builder,
+      "llvm.uadd.with.overflow.i32",
+      otype, stride,
       lp_build_const_int32(gallivm,
-                           util_format_get_blocksize(velem->src_format)),
+                           util_format_get_blocksize(velem->src_format)));
+   ofbit = LLVMBuildOr(
+      builder, ofbit,
+      LLVMBuildExtractValue(builder, oresult, 1, ""),
       "");
+   needed_buffer_size = LLVMBuildExtractValue(builder, oresult, 0, "");
 
    buffer_overflowed = LLVMBuildICmp(builder, LLVMIntUGT,
                                      needed_buffer_size, buffer_size,
                                      "buffer_overflowed");
+   buffer_overflowed = LLVMBuildOr(builder, buffer_overflowed, ofbit, "");
 #if 0
    lp_build_printf(gallivm, "vbuf index = %u, vb_stride is %u\n",
                    index, vb_stride);




More information about the mesa-commit mailing list