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 919ec22ecf
(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.
This commit is contained in:
Brian Paul
2008-11-10 14:27:42 -07:00
parent 6186e7a206
commit 13f96c5401
6 changed files with 141 additions and 165 deletions
+15 -139
View File
@@ -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;
+103
View File
@@ -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;
}
}
+17 -17
View File
@@ -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
-3
View File
@@ -28,9 +28,6 @@
#if !defined( _DISPATCH_H_ )
# define _DISPATCH_H_
#include "glapitable.h"
/**
* \file dispatch.h
* Macros for handling GL dispatch tables.
+2 -2
View File
@@ -3289,7 +3289,7 @@
<param name="textures" type="const GLuint *" count="n"/>
<param name="residences" type="GLboolean *" output="true" count="n"/>
<return type="GLboolean"/>
<glx sop="143" always_array="true"/>
<glx sop="143" handcode="client" always_array="true"/>
</function>
<function name="BindTexture" offset="307">
@@ -8645,7 +8645,7 @@
<param name="textures" type="const GLuint *" count="n"/>
<param name="residences" type="GLboolean *" output="true" count="n"/>
<return type="GLboolean"/>
<glx vendorpriv="11" always_array="true"/>
<glx vendorpriv="11" handcode="client" always_array="true"/>
</function>
<function name="BindTextureEXT" alias="BindTexture">
+4 -4
View File
@@ -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;