From 13f96c5401ffe3869f08fecb2baf5bff2438b02e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 10 Nov 2008 14:27:42 -0700 Subject: [PATCH] GLX: fix out-of-bounds memory issue in indirect glAreTexturesResident() See bug 18445. When getting array results, __glXReadReply() always reads a multiple of four bytes. This can cause writing to invalid memory when 'n' is not a multiple of four. Special-case the glAreTexturesResident() functions now. To fix the bug, we use a temporary buffer that's a multiple of four bytes in length. NOTE: this commit also reverts part of commit 919ec22ecf72aa163e1b97d8c7381002131ed32c (glx/x11: Added some #ifdef GLX_DIRECT_RENDERING protection) which directly edited the indirect.c file rather than the python generator! I'm not repairing that issue at this time. --- src/glx/x11/indirect.c | 154 ++---------------- src/glx/x11/single2.c | 103 ++++++++++++ .../drivers/dri/common/extension_helper.h | 34 ++-- src/mesa/glapi/dispatch.h | 3 - src/mesa/glapi/gl_API.xml | 4 +- src/mesa/main/enums.c | 8 +- 6 files changed, 141 insertions(+), 165 deletions(-) diff --git a/src/glx/x11/indirect.c b/src/glx/x11/indirect.c index 3228e2d6fce..1fcd5ca1bb1 100644 --- a/src/glx/x11/indirect.c +++ b/src/glx/x11/indirect.c @@ -5075,85 +5075,6 @@ __indirect_glPolygonOffset(GLfloat factor, GLfloat units) } } -#define X_GLsop_AreTexturesResident 143 -GLboolean -__indirect_glAreTexturesResident(GLsizei n, const GLuint * textures, - GLboolean * residences) -{ - __GLXcontext *const gc = __glXGetCurrentContext(); - Display *const dpy = gc->currentDpy; - GLboolean retval = (GLboolean) 0; -#ifndef USE_XCB - const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); -#endif - if (n < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return 0; - } - if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { -#ifdef USE_XCB - xcb_connection_t *c = XGetXCBConnection(dpy); - (void) __glXFlushRenderBuffer(gc, gc->pc); - xcb_glx_are_textures_resident_reply_t *reply = - xcb_glx_are_textures_resident_reply(c, - xcb_glx_are_textures_resident - (c, gc->currentContextTag, n, - textures), NULL); - (void) memcpy(residences, xcb_glx_are_textures_resident_data(reply), - xcb_glx_are_textures_resident_data_length(reply) * - sizeof(GLboolean)); - retval = reply->ret_val; - free(reply); -#else - GLubyte const *pc = - __glXSetupSingleRequest(gc, X_GLsop_AreTexturesResident, cmdlen); - (void) memcpy((void *) (pc + 0), (void *) (&n), 4); - (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4)); - retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE); - UnlockDisplay(dpy); - SyncHandle(); -#endif /* USE_XCB */ - } - return retval; -} - -#define X_GLvop_AreTexturesResidentEXT 11 -GLboolean -glAreTexturesResidentEXT(GLsizei n, const GLuint * textures, - GLboolean * residences) -{ - __GLXcontext *const gc = __glXGetCurrentContext(); - -#ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { - return CALL_AreTexturesResident(GET_DISPATCH(), - (n, textures, residences)); - } else -#endif - { - __GLXcontext *const gc = __glXGetCurrentContext(); - Display *const dpy = gc->currentDpy; - GLboolean retval = (GLboolean) 0; - const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); - if (n < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return 0; - } - if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { - GLubyte const *pc = - __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, - X_GLvop_AreTexturesResidentEXT, - cmdlen); - (void) memcpy((void *) (pc + 0), (void *) (&n), 4); - (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4)); - retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE); - UnlockDisplay(dpy); - SyncHandle(); - } - return retval; - } -} - #define X_GLrop_CopyTexImage1D 4119 void __indirect_glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, @@ -5277,12 +5198,9 @@ glDeleteTexturesEXT(GLsizei n, const GLuint * textures) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_DeleteTextures(GET_DISPATCH(), (n, textures)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); @@ -5348,12 +5266,9 @@ glGenTexturesEXT(GLsizei n, GLuint * textures) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GenTextures(GET_DISPATCH(), (n, textures)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; @@ -5413,12 +5328,9 @@ glIsTextureEXT(GLuint texture) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { return CALL_IsTexture(GET_DISPATCH(), (texture)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; @@ -5730,12 +5642,9 @@ glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid * table) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetColorTable(GET_DISPATCH(), (target, format, type, table)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; @@ -5806,13 +5715,10 @@ glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetColorTableParameterfv(GET_DISPATCH(), (target, pname, params)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; @@ -5879,13 +5785,10 @@ glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetColorTableParameteriv(GET_DISPATCH(), (target, pname, params)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; @@ -6205,13 +6108,10 @@ gl_dispatch_stub_356(GLenum target, GLenum format, GLenum type, { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetConvolutionFilter(GET_DISPATCH(), (target, format, type, image)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; @@ -6283,13 +6183,10 @@ gl_dispatch_stub_357(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetConvolutionParameterfv(GET_DISPATCH(), (target, pname, params)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; @@ -6356,13 +6253,10 @@ gl_dispatch_stub_358(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetConvolutionParameteriv(GET_DISPATCH(), (target, pname, params)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; @@ -6436,13 +6330,10 @@ gl_dispatch_stub_361(GLenum target, GLboolean reset, GLenum format, { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetHistogram(GET_DISPATCH(), (target, reset, format, type, values)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; @@ -6513,12 +6404,9 @@ gl_dispatch_stub_362(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetHistogramParameterfv(GET_DISPATCH(), (target, pname, params)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; @@ -6584,12 +6472,9 @@ gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetHistogramParameteriv(GET_DISPATCH(), (target, pname, params)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; @@ -6659,12 +6544,9 @@ gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format, { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetMinmax(GET_DISPATCH(), (target, reset, format, type, values)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; @@ -6733,12 +6615,9 @@ gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetMinmaxParameterfv(GET_DISPATCH(), (target, pname, params)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; @@ -6801,12 +6680,9 @@ gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); -#ifdef GLX_DIRECT_RENDERING if (gc->driContext) { CALL_GetMinmaxParameteriv(GET_DISPATCH(), (target, pname, params)); - } else -#endif - { + } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; diff --git a/src/glx/x11/single2.c b/src/glx/x11/single2.c index 9732b6ef046..38fa6a536ea 100644 --- a/src/glx/x11/single2.c +++ b/src/glx/x11/single2.c @@ -36,6 +36,8 @@ #include "glxextensions.h" #include "indirect.h" #include "indirect_vertex_array.h" +#include "dispatch.h" +#include "glapi.h" /* Used for GL_ARB_transpose_matrix */ static void @@ -863,3 +865,104 @@ __indirect_glGetPointerv(GLenum pname, void **params) return; } } + + + +/** + * This was previously auto-generated, but we need to special-case + * how we handle writing into the 'residences' buffer when n%4!=0. + */ +#define X_GLsop_AreTexturesResident 143 +GLboolean +__indirect_glAreTexturesResident(GLsizei n, const GLuint * textures, + GLboolean * residences) +{ + __GLXcontext *const gc = __glXGetCurrentContext(); + Display *const dpy = gc->currentDpy; + GLboolean retval = (GLboolean) 0; + const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); + if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { +#ifdef USE_XCB + xcb_connection_t *c = XGetXCBConnection(dpy); + (void) __glXFlushRenderBuffer(gc, gc->pc); + xcb_glx_are_textures_resident_reply_t *reply = + xcb_glx_are_textures_resident_reply(c, + xcb_glx_are_textures_resident + (c, gc->currentContextTag, n, + textures), NULL); + (void) memcpy(residences, xcb_glx_are_textures_resident_data(reply), + xcb_glx_are_textures_resident_data_length(reply) * + sizeof(GLboolean)); + retval = reply->ret_val; + free(reply); +#else + GLubyte const *pc = + __glXSetupSingleRequest(gc, X_GLsop_AreTexturesResident, cmdlen); + (void) memcpy((void *) (pc + 0), (void *) (&n), 4); + (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4)); + if (n & 3) { + /* n is not a multiple of four. + * When reply_is_always_array is TRUE, __glXReadReply() will + * put a multiple of four bytes into the dest buffer. If the + * caller's buffer is not a multiple of four in size, we'll write + * out of bounds. So use a temporary buffer that's a few bytes + * larger. + */ + GLboolean *res4 = malloc((n + 3) & ~3); + retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE); + memcpy(residences, res4, n); + free(res4); + } + else { + retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE); + } + UnlockDisplay(dpy); + SyncHandle(); +#endif /* USE_XCB */ + } + return retval; +} + + +/** + * This was previously auto-generated, but we need to special-case + * how we handle writing into the 'residences' buffer when n%4!=0. + */ +#define X_GLvop_AreTexturesResidentEXT 11 +GLboolean +glAreTexturesResidentEXT(GLsizei n, const GLuint * textures, + GLboolean * residences) +{ + __GLXcontext *const gc = __glXGetCurrentContext(); + + if (gc->isDirect) { + return CALL_AreTexturesResident(GET_DISPATCH(), + (n, textures, residences)); + } else { + __GLXcontext *const gc = __glXGetCurrentContext(); + Display *const dpy = gc->currentDpy; + GLboolean retval = (GLboolean) 0; + const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); + if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { + GLubyte const *pc = + __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, + X_GLvop_AreTexturesResidentEXT, + cmdlen); + (void) memcpy((void *) (pc + 0), (void *) (&n), 4); + (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4)); + if (n & 3) { + /* see comments in __indirect_glAreTexturesResident() */ + GLboolean *res4 = malloc((n + 3) & ~3); + retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE); + memcpy(residences, res4, n); + free(res4); + } + else { + retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE); + } + UnlockDisplay(dpy); + SyncHandle(); + } + return retval; + } +} diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h index 3143ea2b104..65e96657b8a 100644 --- a/src/mesa/drivers/dri/common/extension_helper.h +++ b/src/mesa/drivers/dri/common/extension_helper.h @@ -26,7 +26,7 @@ */ #include "utils.h" -#include "glapi/dispatch.h" +#include "dispatch.h" #ifndef NULL # define NULL 0 @@ -1077,6 +1077,13 @@ static const char AreTexturesResident_names[] = ""; #endif +#if defined(need_GL_EXT_framebuffer_object) +static const char IsRenderbufferEXT_names[] = + "i\0" /* Parameter signature */ + "glIsRenderbufferEXT\0" + ""; +#endif + #if defined(need_GL_VERSION_2_0) || defined(need_GL_ATI_separate_stencil) static const char StencilOpSeparate_names[] = "iiii\0" /* Parameter signature */ @@ -1756,6 +1763,13 @@ static const char DeleteFencesNV_names[] = ""; #endif +#if defined(need_GL_SGIX_polynomial_ffd) +static const char DeformationMap3dSGIX_names[] = + "iddiiddiiddiip\0" /* Parameter signature */ + "glDeformationMap3dSGIX\0" + ""; +#endif + #if defined(need_GL_VERSION_2_0) static const char IsShader_names[] = "i\0" /* Parameter signature */ @@ -2001,13 +2015,6 @@ static const char WeightfvARB_names[] = ""; #endif -#if defined(need_GL_EXT_framebuffer_object) -static const char IsRenderbufferEXT_names[] = - "i\0" /* Parameter signature */ - "glIsRenderbufferEXT\0" - ""; -#endif - #if defined(need_GL_MESA_window_pos) static const char WindowPos4fMESA_names[] = "ffff\0" /* Parameter signature */ @@ -4523,13 +4530,6 @@ static const char Minmax_names[] = ""; #endif -#if defined(need_GL_SGIX_polynomial_ffd) -static const char DeformationMap3dSGIX_names[] = - "iddiiddiiddiip\0" /* Parameter signature */ - "glDeformationMap3dSGIX\0" - ""; -#endif - #if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord) static const char FogCoorddvEXT_names[] = "p\0" /* Parameter signature */ @@ -5319,13 +5319,13 @@ static const struct dri_extension_function GL_EXT_framebuffer_blit_functions[] = #if defined(need_GL_EXT_framebuffer_object) static const struct dri_extension_function GL_EXT_framebuffer_object_functions[] = { { GenerateMipmapEXT_names, GenerateMipmapEXT_remap_index, -1 }, + { IsRenderbufferEXT_names, IsRenderbufferEXT_remap_index, -1 }, { RenderbufferStorageEXT_names, RenderbufferStorageEXT_remap_index, -1 }, { CheckFramebufferStatusEXT_names, CheckFramebufferStatusEXT_remap_index, -1 }, { DeleteRenderbuffersEXT_names, DeleteRenderbuffersEXT_remap_index, -1 }, { FramebufferTexture3DEXT_names, FramebufferTexture3DEXT_remap_index, -1 }, { FramebufferRenderbufferEXT_names, FramebufferRenderbufferEXT_remap_index, -1 }, { FramebufferTexture1DEXT_names, FramebufferTexture1DEXT_remap_index, -1 }, - { IsRenderbufferEXT_names, IsRenderbufferEXT_remap_index, -1 }, { BindFramebufferEXT_names, BindFramebufferEXT_remap_index, -1 }, { GenRenderbuffersEXT_names, GenRenderbuffersEXT_remap_index, -1 }, { IsFramebufferEXT_names, IsFramebufferEXT_remap_index, -1 }, @@ -5965,9 +5965,9 @@ static const struct dri_extension_function GL_SGIX_pixel_texture_functions[] = { #if defined(need_GL_SGIX_polynomial_ffd) static const struct dri_extension_function GL_SGIX_polynomial_ffd_functions[] = { { LoadIdentityDeformationMapSGIX_names, LoadIdentityDeformationMapSGIX_remap_index, -1 }, + { DeformationMap3dSGIX_names, DeformationMap3dSGIX_remap_index, -1 }, { DeformSGIX_names, DeformSGIX_remap_index, -1 }, { DeformationMap3fSGIX_names, DeformationMap3fSGIX_remap_index, -1 }, - { DeformationMap3dSGIX_names, DeformationMap3dSGIX_remap_index, -1 }, { NULL, 0, 0 } }; #endif diff --git a/src/mesa/glapi/dispatch.h b/src/mesa/glapi/dispatch.h index 98f654f4022..71231560852 100644 --- a/src/mesa/glapi/dispatch.h +++ b/src/mesa/glapi/dispatch.h @@ -28,9 +28,6 @@ #if !defined( _DISPATCH_H_ ) # define _DISPATCH_H_ -#include "glapitable.h" - - /** * \file dispatch.h * Macros for handling GL dispatch tables. diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml index 2d8a967ba79..6c0367aad79 100644 --- a/src/mesa/glapi/gl_API.xml +++ b/src/mesa/glapi/gl_API.xml @@ -3289,7 +3289,7 @@ - + @@ -8645,7 +8645,7 @@ - + diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c index 15e7d5b96ce..a9c102e4f2d 100644 --- a/src/mesa/main/enums.c +++ b/src/mesa/main/enums.c @@ -4866,8 +4866,8 @@ const char *_mesa_lookup_enum_by_nr( int nr ) { unsigned * i; - i = (unsigned *)_mesa_bsearch( & nr, reduced_enums, Elements(reduced_enums), - sizeof(reduced_enums[0]), (cfunc) compar_nr ); + i = (unsigned *)bsearch( & nr, reduced_enums, Elements(reduced_enums), + sizeof(reduced_enums[0]), (cfunc) compar_nr ); if ( i != NULL ) { return & enum_string_table[ all_enums[ *i ].offset ]; @@ -4884,8 +4884,8 @@ int _mesa_lookup_enum_by_name( const char *symbol ) enum_elt * f = NULL; if ( symbol != NULL ) { - f = (enum_elt *)_mesa_bsearch( symbol, all_enums, Elements(all_enums), - sizeof( enum_elt ), (cfunc) compar_name ); + f = (enum_elt *)bsearch( symbol, all_enums, Elements(all_enums), + sizeof( enum_elt ), (cfunc) compar_name ); } return (f != NULL) ? f->n : -1; -- 2.30.2