This avoids forming invalid pointers needlessly, which even if never dereferenced is undefined behavior. It also makes _mesa_validate_pbo_access() more comprehensible. --- src/mesa/drivers/dri/intel/intel_pixel_read.c | 5 +++-- src/mesa/main/pbo.c | 25 ++++++++++++++----------- 2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c index c8e415d..d45a442 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_read.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c @@ -120,8 +120,9 @@ do_blit_readpixels(struct gl_context * ctx, rowLength = -rowLength; } - dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height, - format, type, 0, 0, 0); + dst_offset = (GLintptr)pixels; + dst_offset += _mesa_image_offset(2, pack, width, height, + format, type, 0, 0, 0); if (!_mesa_clip_copytexsubimage(ctx, &dst_x, &dst_y, diff --git a/src/mesa/main/pbo.c b/src/mesa/main/pbo.c index 4e7e6f9..023662d 100644 --- a/src/mesa/main/pbo.c +++ b/src/mesa/main/pbo.c @@ -68,8 +68,8 @@ _mesa_validate_pbo_access(GLuint dimensions, GLenum format, GLenum type, GLsizei clientMemSize, const GLvoid *ptr) { - const GLvoid *start, *end, *offset; - const GLubyte *sizeAddr; /* buffer size, cast to a pointer */ + /* unsigned, to detect overflow/wrap-around */ + uintptr_t start, end, offset, size; /* If no PBO is bound, 'ptr' is a pointer to client memory containing 'clientMemSize' bytes. @@ -78,29 +78,32 @@ _mesa_validate_pbo_access(GLuint dimensions, */ if (!_mesa_is_bufferobj(pack->BufferObj)) { offset = 0; - sizeAddr = ((const GLubyte *) 0) + clientMemSize; + size = clientMemSize; } else { offset = ptr; - sizeAddr = ((const GLubyte *) 0) + pack->BufferObj->Size; + size = pack->BufferObj->Size; } - if (sizeAddr == 0) + if (size == 0) /* no buffer! */ return GL_FALSE; /* get the offset to the first pixel we'll read/write */ - start = _mesa_image_address(dimensions, pack, offset, width, height, - format, type, 0, 0, 0); + start = _mesa_image_offset(dimensions, pack, width, height, + format, type, 0, 0, 0); /* get the offset to just past the last pixel we'll read/write */ - end = _mesa_image_address(dimensions, pack, offset, width, height, - format, type, depth-1, height-1, width); + end = _mesa_image_offset(dimensions, pack, width, height, + format, type, depth-1, height-1, width); - if ((const GLubyte *) start > sizeAddr) { + start += offset; + end += offset; + + if (start > size) { /* This will catch negative values / wrap-around */ return GL_FALSE; } - if ((const GLubyte *) end > sizeAddr) { + if (end > size) { /* Image read/write goes beyond end of buffer */ return GL_FALSE; } -- 1.7.6.msysgit.0
From 0fec8cecad17894d77d6cffffd677bd7b2ec7773 Mon Sep 17 00:00:00 2001 From: nobled <nob...@dreamwidth.org> Date: Wed, 19 Oct 2011 06:35:53 +0000 Subject: [PATCH 9/9] mesa,intel: use _mesa_image_offset() for PBOs This avoids forming invalid pointers needlessly, which even if never dereferenced is undefined behavior. It also makes _mesa_validate_pbo_access() more comprehensible. --- src/mesa/drivers/dri/intel/intel_pixel_read.c | 5 +++-- src/mesa/main/pbo.c | 25 ++++++++++++++----------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c index c8e415d..d45a442 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_read.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c @@ -120,8 +120,9 @@ do_blit_readpixels(struct gl_context * ctx, rowLength = -rowLength; } - dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height, - format, type, 0, 0, 0); + dst_offset = (GLintptr)pixels; + dst_offset += _mesa_image_offset(2, pack, width, height, + format, type, 0, 0, 0); if (!_mesa_clip_copytexsubimage(ctx, &dst_x, &dst_y, diff --git a/src/mesa/main/pbo.c b/src/mesa/main/pbo.c index 4e7e6f9..023662d 100644 --- a/src/mesa/main/pbo.c +++ b/src/mesa/main/pbo.c @@ -68,8 +68,8 @@ _mesa_validate_pbo_access(GLuint dimensions, GLenum format, GLenum type, GLsizei clientMemSize, const GLvoid *ptr) { - const GLvoid *start, *end, *offset; - const GLubyte *sizeAddr; /* buffer size, cast to a pointer */ + /* unsigned, to detect overflow/wrap-around */ + uintptr_t start, end, offset, size; /* If no PBO is bound, 'ptr' is a pointer to client memory containing 'clientMemSize' bytes. @@ -78,29 +78,32 @@ _mesa_validate_pbo_access(GLuint dimensions, */ if (!_mesa_is_bufferobj(pack->BufferObj)) { offset = 0; - sizeAddr = ((const GLubyte *) 0) + clientMemSize; + size = clientMemSize; } else { offset = ptr; - sizeAddr = ((const GLubyte *) 0) + pack->BufferObj->Size; + size = pack->BufferObj->Size; } - if (sizeAddr == 0) + if (size == 0) /* no buffer! */ return GL_FALSE; /* get the offset to the first pixel we'll read/write */ - start = _mesa_image_address(dimensions, pack, offset, width, height, - format, type, 0, 0, 0); + start = _mesa_image_offset(dimensions, pack, width, height, + format, type, 0, 0, 0); /* get the offset to just past the last pixel we'll read/write */ - end = _mesa_image_address(dimensions, pack, offset, width, height, - format, type, depth-1, height-1, width); + end = _mesa_image_offset(dimensions, pack, width, height, + format, type, depth-1, height-1, width); - if ((const GLubyte *) start > sizeAddr) { + start += offset; + end += offset; + + if (start > size) { /* This will catch negative values / wrap-around */ return GL_FALSE; } - if ((const GLubyte *) end > sizeAddr) { + if (end > size) { /* Image read/write goes beyond end of buffer */ return GL_FALSE; } -- 1.7.6.msysgit.0
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev