[Mesa-dev] [PATCH] mesa: add bounds checking to eliminate buffer overrun
Courtney Goeltzenleuchter
courtney at lunarg.com
Fri Feb 14 07:52:10 PST 2014
Decompressing ETC2 textures was causing intermitent segfault
by copying resulting 4x4 texel block to the destination texture
regardless of the size of the destination texture. Issue found
via application crash in GLBenchmark 3.0's Manhattan test.
Signed-off-by: Courtney Goeltzenleuchter <courtney at LunarG.com>
---
src/mesa/main/texcompress_etc.c | 49 +++++++++++++++++++++--------------------
1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c
index e3862be..f9234b0 100644
--- a/src/mesa/main/texcompress_etc.c
+++ b/src/mesa/main/texcompress_etc.c
@@ -684,9 +684,10 @@ etc2_unpack_rgb8(uint8_t *dst_row,
etc2_rgb8_parse_block(&block, src,
false /* punchthrough_alpha */);
- for (j = 0; j < bh; j++) {
+ /* be sure to stay within the bounds of the texture */
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_rgb8_fetch_texel(&block, i, j, dst,
false /* punchthrough_alpha */);
dst[3] = 255;
@@ -721,9 +722,9 @@ etc2_unpack_srgb8(uint8_t *dst_row,
etc2_rgb8_parse_block(&block, src,
false /* punchthrough_alpha */);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_rgb8_fetch_texel(&block, i, j, dst,
false /* punchthrough_alpha */);
/* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
@@ -764,9 +765,9 @@ etc2_unpack_rgba8(uint8_t *dst_row,
for (x = 0; x < width; x+= bw) {
etc2_rgba8_parse_block(&block, src);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_rgba8_fetch_texel(&block, i, j, dst);
dst += comps;
}
@@ -801,9 +802,9 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row,
for (x = 0; x < width; x+= bw) {
etc2_rgba8_parse_block(&block, src);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_rgba8_fetch_texel(&block, i, j, dst);
/* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
@@ -843,9 +844,9 @@ etc2_unpack_r11(uint8_t *dst_row,
for (x = 0; x < width; x+= bw) {
etc2_r11_parse_block(&block, src);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_r11_fetch_texel(&block, i, j, dst);
dst += comps * comp_size;
}
@@ -879,10 +880,10 @@ etc2_unpack_rg11(uint8_t *dst_row,
/* red component */
etc2_r11_parse_block(&block, src);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride +
x * comps * comp_size;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_r11_fetch_texel(&block, i, j, dst);
dst += comps * comp_size;
}
@@ -890,10 +891,10 @@ etc2_unpack_rg11(uint8_t *dst_row,
/* green component */
etc2_r11_parse_block(&block, src + 8);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride +
x * comps * comp_size;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_r11_fetch_texel(&block, i, j, dst + comp_size);
dst += comps * comp_size;
}
@@ -926,10 +927,10 @@ etc2_unpack_signed_r11(uint8_t *dst_row,
for (x = 0; x < width; x+= bw) {
etc2_r11_parse_block(&block, src);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride +
x * comps * comp_size;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_signed_r11_fetch_texel(&block, i, j, dst);
dst += comps * comp_size;
}
@@ -963,10 +964,10 @@ etc2_unpack_signed_rg11(uint8_t *dst_row,
/* red component */
etc2_r11_parse_block(&block, src);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride +
x * comps * comp_size;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_signed_r11_fetch_texel(&block, i, j, dst);
dst += comps * comp_size;
}
@@ -974,10 +975,10 @@ etc2_unpack_signed_rg11(uint8_t *dst_row,
/* green component */
etc2_r11_parse_block(&block, src + 8);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride +
x * comps * comp_size;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_signed_r11_fetch_texel(&block, i, j, dst + comp_size);
dst += comps * comp_size;
}
@@ -1007,9 +1008,9 @@ etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row,
for (x = 0; x < width; x+= bw) {
etc2_rgb8_parse_block(&block, src,
true /* punchthrough_alpha */);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_rgb8_fetch_texel(&block, i, j, dst,
true /* punchthrough_alpha */);
dst += comps;
@@ -1042,9 +1043,9 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row,
for (x = 0; x < width; x+= bw) {
etc2_rgb8_parse_block(&block, src,
true /* punchthrough_alpha */);
- for (j = 0; j < bh; j++) {
+ for (j = 0; j < bh && (j+y) < height; j++) {
uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
- for (i = 0; i < bw; i++) {
+ for (i = 0; i < bw && (i+x) < width; i++) {
etc2_rgb8_fetch_texel(&block, i, j, dst,
true /* punchthrough_alpha */);
/* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
--
1.8.3.2
More information about the mesa-dev
mailing list