From c7a3356746b8751fa0f04c8c0b674e26d73fdb76 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 21 Feb 2002 15:12:31 +0000 Subject: [PATCH] Fixed out-of-bounds memory write problem (CONVERT_TEXEL_DWORD macro). Renamed 'packing' to 'unpacking' since we're moving data from client -> GL. Rnamed DST_ROW_WIDTH to DST_ROW_BYTES. --- src/mesa/main/texutil.c | 64 +++++------ src/mesa/main/texutil_tmp.h | 215 ++++++++++++++++++++++-------------- 2 files changed, 166 insertions(+), 113 deletions(-) diff --git a/src/mesa/main/texutil.c b/src/mesa/main/texutil.c index 6231f589af2..0ac927797d6 100644 --- a/src/mesa/main/texutil.c +++ b/src/mesa/main/texutil.c @@ -1,10 +1,10 @@ -/* $Id: texutil.c,v 1.25 2001/06/15 15:22:08 brianp Exp $ */ +/* $Id: texutil.c,v 1.26 2002/02/21 15:12:31 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 4.0.2 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -52,7 +52,7 @@ struct gl_texture_convert { /* Needed for subimage replacement */ GLenum format, type; /* Source (user) format and type */ - const struct gl_pixelstore_attrib *packing; + const struct gl_pixelstore_attrib *unpacking; const GLvoid *srcImage; GLvoid *dstImage; @@ -63,7 +63,7 @@ struct gl_texture_convert { typedef GLboolean (*convert_func)( struct gl_texture_convert *convert ); #define CONVERT_STRIDE_BIT 0x1 -#define CONVERT_PACKING_BIT 0x2 +#define CONVERT_UNPACKING_BIT 0x2 @@ -681,23 +681,23 @@ static convert_func gl_convert_texsubimage3d_tab[] = { /* See if we need to care about the pixel store attributes when we're * converting the texture image. This should be stored as - * packing->_SomeBoolean and updated when the values change, to avoid + * unpacking->_SomeBoolean and updated when the values change, to avoid * testing every time... */ static INLINE GLboolean -convert_needs_packing( const struct gl_pixelstore_attrib *packing, +convert_needs_unpacking( const struct gl_pixelstore_attrib *unpacking, GLenum format, GLenum type ) { - if ( ( packing->Alignment == 1 || - ( packing->Alignment == 4 && /* Pick up the common Q3A case... */ + if ( ( unpacking->Alignment == 1 || + ( unpacking->Alignment == 4 && /* Pick up the common Q3A case... */ format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) && - packing->RowLength == 0 && - packing->SkipPixels == 0 && - packing->SkipRows == 0 && - packing->ImageHeight == 0 && - packing->SkipImages == 0 && - packing->SwapBytes == GL_FALSE && - packing->LsbFirst == GL_FALSE ) { + unpacking->RowLength == 0 && + unpacking->SkipPixels == 0 && + unpacking->SkipRows == 0 && + unpacking->ImageHeight == 0 && + unpacking->SkipImages == 0 && + unpacking->SwapBytes == GL_FALSE && + unpacking->LsbFirst == GL_FALSE ) { return GL_FALSE; } else { return GL_TRUE; @@ -710,12 +710,12 @@ _mesa_convert_texsubimage1d( GLint mesaFormat, GLint xoffset, GLint width, GLenum format, GLenum type, - const struct gl_pixelstore_attrib *packing, + const struct gl_pixelstore_attrib *unpacking, const GLvoid *srcImage, GLvoid *dstImage ) { struct gl_texture_convert convert; - ASSERT( packing ); + ASSERT( unpacking ); ASSERT( srcImage ); ASSERT( dstImage ); @@ -730,14 +730,14 @@ _mesa_convert_texsubimage1d( GLint mesaFormat, convert.height = 1; convert.format = format; convert.type = type; - convert.packing = packing; + convert.unpacking = unpacking; convert.srcImage = srcImage; convert.dstImage = dstImage; convert.index = 0; - if ( convert_needs_packing( packing, format, type ) ) - convert.index |= CONVERT_PACKING_BIT; + if ( convert_needs_unpacking( unpacking, format, type ) ) + convert.index |= CONVERT_UNPACKING_BIT; return gl_convert_texsubimage2d_tab[mesaFormat]( &convert ); } @@ -764,7 +764,7 @@ _mesa_convert_texsubimage1d( GLint mesaFormat, * width, height - incoming image size, also size of dest region. * dstImageWidth - width (row stride) of dest image in pixels * format, type - incoming image format and type - * packing - describes incoming image packing + * unpacking - describes incoming image unpacking * srcImage - pointer to source image * destImage - pointer to dest image */ @@ -774,12 +774,12 @@ _mesa_convert_texsubimage2d( GLint mesaFormat, GLint width, GLint height, GLint destImageWidth, GLenum format, GLenum type, - const struct gl_pixelstore_attrib *packing, + const struct gl_pixelstore_attrib *unpacking, const GLvoid *srcImage, GLvoid *dstImage ) { struct gl_texture_convert convert; - ASSERT( packing ); + ASSERT( unpacking ); ASSERT( srcImage ); ASSERT( dstImage ); @@ -795,14 +795,14 @@ _mesa_convert_texsubimage2d( GLint mesaFormat, convert.dstImageWidth = destImageWidth; convert.format = format; convert.type = type; - convert.packing = packing; + convert.unpacking = unpacking; convert.srcImage = srcImage; convert.dstImage = dstImage; convert.index = 0; - if ( convert_needs_packing( packing, format, type ) ) - convert.index |= CONVERT_PACKING_BIT; + if ( convert_needs_unpacking( unpacking, format, type ) ) + convert.index |= CONVERT_UNPACKING_BIT; if ( width != destImageWidth ) convert.index |= CONVERT_STRIDE_BIT; @@ -816,12 +816,12 @@ _mesa_convert_texsubimage3d( GLint mesaFormat, GLint width, GLint height, GLint depth, GLint dstImageWidth, GLint dstImageHeight, GLenum format, GLenum type, - const struct gl_pixelstore_attrib *packing, + const struct gl_pixelstore_attrib *unpacking, const GLvoid *srcImage, GLvoid *dstImage ) { struct gl_texture_convert convert; - ASSERT( packing ); + ASSERT( unpacking ); ASSERT( srcImage ); ASSERT( dstImage ); @@ -840,14 +840,14 @@ _mesa_convert_texsubimage3d( GLint mesaFormat, convert.dstImageHeight = dstImageHeight; convert.format = format; convert.type = type; - convert.packing = packing; + convert.unpacking = unpacking; convert.srcImage = srcImage; convert.dstImage = dstImage; convert.index = 0; - if ( convert_needs_packing( packing, format, type ) ) - convert.index |= CONVERT_PACKING_BIT; + if ( convert_needs_unpacking( unpacking, format, type ) ) + convert.index |= CONVERT_UNPACKING_BIT; if ( width != dstImageWidth || height != dstImageHeight ) convert.index |= CONVERT_STRIDE_BIT; diff --git a/src/mesa/main/texutil_tmp.h b/src/mesa/main/texutil_tmp.h index ec6274c80e8..3d2ecd9fd02 100644 --- a/src/mesa/main/texutil_tmp.h +++ b/src/mesa/main/texutil_tmp.h @@ -1,10 +1,10 @@ -/* $Id: texutil_tmp.h,v 1.8 2001/04/20 19:21:41 brianp Exp $ */ +/* $Id: texutil_tmp.h,v 1.9 2002/02/21 15:12:31 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 4.0.2 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -33,7 +33,7 @@ #define DST_TEXEL_BYTES (4 / DST_TEXELS_PER_DWORD) -#define DST_ROW_WIDTH (convert->width * DST_TEXEL_BYTES) +#define DST_ROW_BYTES (convert->width * DST_TEXEL_BYTES) #define DST_ROW_STRIDE (convert->dstImageWidth * DST_TEXEL_BYTES) #define DST_IMG_STRIDE (convert->dstImageWidth * \ convert->dstImageHeight * DST_TEXEL_BYTES) @@ -49,22 +49,27 @@ TAG(texsubimage2d)( struct gl_texture_convert *convert ) GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + (convert->yoffset * convert->dstImageWidth + convert->xoffset) * DST_TEXEL_BYTES); - GLint dwords, i; - (void) dwords; (void) i; #if DEBUG_TEXUTIL fprintf( stderr, __FUNCTION__ "\n" ); #endif #ifdef CONVERT_DIRECT - MEMCPY( dst, src, convert->height * DST_ROW_WIDTH ); + MEMCPY( dst, src, convert->height * DST_ROW_BYTES ); #else - dwords = (convert->width * convert->height + - DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD; - - for ( i = 0 ; i < dwords ; i++ ) { - CONVERT_TEXEL_DWORD( *dst++, src ); - src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + { + const GLint texels = convert->width * convert->height; + const GLint dwords = texels / DST_TEXELS_PER_DWORD; + const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD; + GLint i; + for ( i = 0 ; i < dwords ; i++ ) { + CONVERT_TEXEL_DWORD( *dst++, src ); + src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + } + for ( i = 0; i < leftover; i++ ) { + CONVERT_TEXEL( *dst++, src ); + src += SRC_TEXEL_BYTES; + } } #endif @@ -81,22 +86,26 @@ TAG(texsubimage3d)( struct gl_texture_convert *convert ) ((convert->zoffset * convert->height + convert->yoffset) * convert->width + convert->xoffset) * DST_TEXEL_BYTES); - GLint dwords, i; - (void) dwords; (void) i; - #if DEBUG_TEXUTIL fprintf( stderr, __FUNCTION__ "\n" ); #endif #ifdef CONVERT_DIRECT - MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_WIDTH ); + MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_BYTES ); #else - dwords = (convert->width * convert->height * convert->depth + - DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD; - - for ( i = 0 ; i < dwords ; i++ ) { - CONVERT_TEXEL_DWORD( *dst++, src ); - src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + { + const GLint texels = convert->width * convert->height * convert->depth; + const GLint dwords = texels / DST_TEXELS_PER_DWORD; + const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD; + GLint i; + for ( i = 0 ; i < dwords ; i++ ) { + CONVERT_TEXEL_DWORD( *dst++, src ); + src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + } + for ( i = 0; i < leftover; i++ ) { + CONVERT_TEXEL( *dst++, src ); + src += SRC_TEXEL_BYTES; + } } #endif @@ -182,42 +191,56 @@ TAG(texsubimage3d_stride)( struct gl_texture_convert *convert ) * PRE: Require pixelstore attribs, width == dstImageWidth. */ static GLboolean -TAG(texsubimage2d_pack)( struct gl_texture_convert *convert ) +TAG(texsubimage2d_unpack)( struct gl_texture_convert *convert ) { const GLubyte *src = (const GLubyte *) - _mesa_image_address( convert->packing, convert->srcImage, + _mesa_image_address( convert->unpacking, convert->srcImage, convert->width, convert->height, convert->format, convert->type, 0, 0, 0 ); const GLint srcRowStride = - _mesa_image_row_stride( convert->packing, convert->width, + _mesa_image_row_stride( convert->unpacking, convert->width, convert->format, convert->type ); - GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + - (convert->yoffset * convert->width + - convert->xoffset) * DST_TEXEL_BYTES); - GLint width; GLint row, col; - (void) col; #if DEBUG_TEXUTIL fprintf( stderr, __FUNCTION__ "\n" ); #endif - width = ((convert->width + DST_TEXELS_PER_DWORD - 1) - & ~(DST_TEXELS_PER_DWORD - 1)); - - for ( row = 0 ; row < convert->height ; row++ ) { + if (convert->width & (DST_TEXELS_PER_DWORD - 1)) { + /* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2 + * or width = 2 and texels/dword = 4). + */ + DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage + + (convert->yoffset * convert->width + + convert->xoffset) * DST_TEXEL_BYTES); + for ( row = 0 ; row < convert->height ; row++ ) { + const GLubyte *srcRow = src; + for ( col = 0; col < convert->width; col++ ) { + CONVERT_TEXEL(*dst, src); + src += SRC_TEXEL_BYTES; + } + src = srcRow + srcRowStride; + } + } + else { + /* the common case */ + GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + + (convert->yoffset * convert->width + + convert->xoffset) * DST_TEXEL_BYTES); + for ( row = 0 ; row < convert->height ; row++ ) { #ifdef CONVERT_DIRECT - MEMCPY( dst, src, DST_ROW_STRIDE ); - src += srcRowStride; - dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE); + MEMCPY( dst, src, DST_ROW_STRIDE ); + src += srcRowStride; + dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE); #else - const GLubyte *srcRow = src; - for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) { - CONVERT_TEXEL_DWORD( *dst++, src ); - src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; - } - src = srcRow + srcRowStride; + const GLubyte *srcRow = src; + for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) { + CONVERT_TEXEL_DWORD( *dst++, src ); + src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + } + src = srcRow + srcRowStride; #endif + } } return GL_TRUE; @@ -226,44 +249,69 @@ TAG(texsubimage2d_pack)( struct gl_texture_convert *convert ) /* PRE: as above, height == dstImageHeight also. */ static GLboolean -TAG(texsubimage3d_pack)( struct gl_texture_convert *convert ) +TAG(texsubimage3d_unpack)( struct gl_texture_convert *convert ) { const GLubyte *src = (const GLubyte *) - _mesa_image_address( convert->packing, convert->srcImage, + _mesa_image_address( convert->unpacking, convert->srcImage, convert->width, convert->height, convert->format, convert->type, 0, 0, 0 ); + const GLint srcImgStride = (const GLubyte *) + _mesa_image_address( convert->unpacking, convert->srcImage, + convert->width, convert->height, + convert->format, convert->type, 1, 0, 0 ) - src; const GLint srcRowStride = - _mesa_image_row_stride( convert->packing, convert->width, + _mesa_image_row_stride( convert->unpacking, convert->width, convert->format, convert->type ); - GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + - ((convert->zoffset * convert->height + - convert->yoffset) * convert->width + - convert->xoffset) * DST_TEXEL_BYTES); - GLint width; GLint row, col, img; - (void) col; #if DEBUG_TEXUTIL fprintf( stderr, __FUNCTION__ "\n" ); #endif - width = ((convert->width + DST_TEXELS_PER_DWORD - 1) - & ~(DST_TEXELS_PER_DWORD - 1)); - - for ( img = 0 ; img < convert->depth ; img++ ) { - for ( row = 0 ; row < convert->height ; row++ ) { + if (convert->width & (DST_TEXELS_PER_DWORD - 1)) { + /* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2 + * or width = 2 and texels/dword = 4). + */ + DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage + + ((convert->zoffset * convert->height + + convert->yoffset) * convert->width + + convert->xoffset) * DST_TEXEL_BYTES); + for ( img = 0 ; img < convert->depth ; img++ ) { + const GLubyte *srcImage = src; + for ( row = 0 ; row < convert->height ; row++ ) { + const GLubyte *srcRow = src; + for ( col = 0; col < convert->width; col++ ) { + CONVERT_TEXEL(*dst, src); + src += SRC_TEXEL_BYTES; + } + src = srcRow + srcRowStride; + } + src = srcImage + srcImgStride; + } + } + else { + /* the common case */ + GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + + ((convert->zoffset * convert->height + + convert->yoffset) * convert->width + + convert->xoffset) * DST_TEXEL_BYTES); + for ( img = 0 ; img < convert->depth ; img++ ) { + const GLubyte *srcImage = src; + for ( row = 0 ; row < convert->height ; row++ ) { #ifdef CONVERT_DIRECT - MEMCPY( dst, src, DST_ROW_STRIDE ); - src += srcRowStride; - dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE); + MEMCPY( dst, src, DST_ROW_STRIDE ); + src += srcRowStride; + dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE); #else - const GLubyte *srcRow = src; - for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) { - CONVERT_TEXEL_DWORD( *dst++, src ); - src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; - } - src = srcRow + srcRowStride; + const GLubyte *srcRow = src; + for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) { + CONVERT_TEXEL_DWORD( *dst++, src ); + src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + } + src = srcRow + srcRowStride; #endif + } + src = srcImage + srcImgStride; } } @@ -276,14 +324,14 @@ TAG(texsubimage3d_pack)( struct gl_texture_convert *convert ) * PRE: Require pixelstore attribs, width != dstImageWidth. */ static GLboolean -TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert ) +TAG(texsubimage2d_stride_unpack)( struct gl_texture_convert *convert ) { const GLubyte *src = (const GLubyte *) - _mesa_image_address( convert->packing, convert->srcImage, + _mesa_image_address( convert->unpacking, convert->srcImage, convert->width, convert->height, convert->format, convert->type, 0, 0, 0 ); const GLint srcRowStride = - _mesa_image_row_stride( convert->packing, convert->width, + _mesa_image_row_stride( convert->unpacking, convert->width, convert->format, convert->type ); DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage + (convert->yoffset * convert->dstImageWidth + @@ -304,7 +352,7 @@ TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert ) for ( row = 0 ; row < convert->height ; row++ ) { #ifdef CONVERT_DIRECT - MEMCPY( dst, src, DST_ROW_WIDTH ); + MEMCPY( dst, src, DST_ROW_BYTES ); src += srcRowStride; dst += convert->dstImageWidth; #else @@ -324,14 +372,18 @@ TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert ) /* PRE: As above, or height != dstImageHeight also. */ static GLboolean -TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert ) +TAG(texsubimage3d_stride_unpack)( struct gl_texture_convert *convert ) { const GLubyte *src = (const GLubyte *) - _mesa_image_address( convert->packing, convert->srcImage, + _mesa_image_address( convert->unpacking, convert->srcImage, convert->width, convert->height, convert->format, convert->type, 0, 0, 0 ); + const GLint srcImgStride = (const GLubyte *) + _mesa_image_address( convert->unpacking, convert->srcImage, + convert->width, convert->height, + convert->format, convert->type, 1, 0, 0 ) - src; const GLint srcRowStride = - _mesa_image_row_stride( convert->packing, convert->width, + _mesa_image_row_stride( convert->unpacking, convert->width, convert->format, convert->type ); DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage + ((convert->zoffset * convert->dstImageHeight + @@ -352,9 +404,10 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert ) #endif for ( img = 0 ; img < convert->depth ; img++ ) { + const GLubyte *srcImage = src; for ( row = 0 ; row < convert->height ; row++ ) { #ifdef CONVERT_DIRECT - MEMCPY( dst, src, DST_ROW_WIDTH ); + MEMCPY( dst, src, DST_ROW_BYTES ); src += srcRowStride; dst += convert->dstImageWidth; #else @@ -367,7 +420,7 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert ) dst += adjust; #endif } - /* FIXME: ... */ + src = srcImage + srcImgStride; } return GL_TRUE; @@ -378,15 +431,15 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert ) static convert_func TAG(texsubimage2d_tab)[] = { TAG(texsubimage2d), TAG(texsubimage2d_stride), - TAG(texsubimage2d_pack), - TAG(texsubimage2d_stride_pack), + TAG(texsubimage2d_unpack), + TAG(texsubimage2d_stride_unpack), }; static convert_func TAG(texsubimage3d_tab)[] = { TAG(texsubimage3d), TAG(texsubimage3d_stride), - TAG(texsubimage3d_pack), - TAG(texsubimage3d_stride_pack), + TAG(texsubimage3d_unpack), + TAG(texsubimage3d_stride_unpack), }; @@ -397,7 +450,7 @@ static convert_func TAG(texsubimage3d_tab)[] = { #undef SRC_TEXEL_BYTES #undef DST_TEXEL_BYTES -#undef DST_ROW_WIDTH +#undef DST_ROW_BYTES #undef DST_ROW_STRIDE #undef CONVERT_TEXEL -- 2.30.2