diff options
author | Brian Paul <[email protected]> | 2008-11-10 14:27:42 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2008-11-10 14:27:42 -0700 |
commit | 13f96c5401ffe3869f08fecb2baf5bff2438b02e (patch) | |
tree | a7b3e9c73b980cb9cb744d656c918eea69a3f66b /src/glx/x11/single2.c | |
parent | 6186e7a20676c5df30b1b4bffeec87afa1550e25 (diff) |
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.
Diffstat (limited to 'src/glx/x11/single2.c')
-rw-r--r-- | src/glx/x11/single2.c | 103 |
1 files changed, 103 insertions, 0 deletions
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; + } +} |