From 2eed9ff2fb5b218b7b274d2989b0dbbe5fcfedef Mon Sep 17 00:00:00 2001 From: Tomasz Lis Date: Thu, 18 Jul 2013 14:19:38 -0700 Subject: glx: Validate the GLX_RENDER_TYPE value Correctly handle the value of renderType in GLX context. In case of the value being incorrect, context creation fails. v2 (idr): indirect_create_context is just a memory allocator, so don't validate the GLX_RENDER_TYPE there. Fixes regressions in several GLX_ARB_create_context piglit tests. Signed-off-by: Tomasz Lis Signed-off-by: Ian Romanick Reviewed-by: Ian Romanick --- src/glx/dri2_glx.c | 8 ++++++++ src/glx/dri_glx.c | 4 ++++ src/glx/drisw_glx.c | 9 +++++++++ src/glx/glxclient.h | 3 +++ src/glx/glxcmds.c | 27 +++++++++++++++++++++++++++ src/glx/indirect_glx.c | 4 ++++ src/mesa/drivers/x11/fakeglx.c | 5 ++++- 7 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 9581bff02dc..c54edacab5b 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -205,6 +205,10 @@ dri2_create_context(struct glx_screen *base, __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; __DRIcontext *shared = NULL; + /* Check the renderType value */ + if (!validate_renderType_against_config(config_base, renderType)) + return NULL; + if (shareList) { /* If the shareList context is not a DRI2 context, we cannot possibly * create a DRI2 context that shares it. @@ -277,6 +281,10 @@ dri2_create_context_attribs(struct glx_screen *base, &api, &reset, error)) goto error_exit; + /* Check the renderType value */ + if (!validate_renderType_against_config(config_base, renderType)) + goto error_exit; + if (shareList) { pcp_shared = (struct dri2_context *) shareList; shared = pcp_shared->driContext; diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index cc45734b66c..faed9d0d16d 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -581,6 +581,10 @@ dri_create_context(struct glx_screen *base, if (!psc->base.driScreen) return NULL; + /* Check the renderType value */ + if (!validate_renderType_against_config(config_base, renderType)) + return NULL; + if (shareList) { /* If the shareList context is not a DRI context, we cannot possibly * create a DRI context that shares it. diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 2c3e8b5f3ba..0583cd15ab5 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -380,6 +380,10 @@ drisw_create_context(struct glx_screen *base, if (!psc->base.driScreen) return NULL; + /* Check the renderType value */ + if (!validate_renderType_against_config(config_base, renderType)) + return NULL; + if (shareList) { /* If the shareList context is not a DRISW context, we cannot possibly * create a DRISW context that shares it. @@ -451,6 +455,11 @@ drisw_create_context_attribs(struct glx_screen *base, &api, &reset, error)) return NULL; + /* Check the renderType value */ + if (!validate_renderType_against_config(config_base, renderType)) { + return NULL; + } + if (reset != __DRI_CTX_RESET_NO_NOTIFICATION) return NULL; diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 5b99e093d01..81ae792bf74 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -803,6 +803,9 @@ extern int applegl_create_display(struct glx_display *display); #endif +extern Bool validate_renderType_against_config(const struct glx_config *config, + int renderType); + extern struct glx_drawable *GetGLXDrawable(Display *dpy, GLXDrawable drawable); extern int InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index f6eb07df192..7c66c9bf82f 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -224,6 +224,33 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig) return NULL; } +/** + * Verifies context's GLX_RENDER_TYPE value with config. + * + * \param config GLX FBConfig which will support the returned renderType. + * \param renderType The context render type to be verified. + * \return True if the value of context renderType was approved, or 0 if no + * valid value was found. + */ +Bool +validate_renderType_against_config(const struct glx_config *config, + int renderType) +{ + switch (renderType) { + case GLX_RGBA_TYPE: + return (config->renderType & GLX_RGBA_BIT) != 0; + case GLX_COLOR_INDEX_TYPE: + return (config->renderType & GLX_COLOR_INDEX_BIT) != 0; + case GLX_RGBA_FLOAT_TYPE_ARB: + return (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) != 0; + case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT: + return (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) != 0; + default: + break; + } + return 0; +} + _X_HIDDEN Bool glx_context_init(struct glx_context *gc, struct glx_screen *psc, struct glx_config *config) diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c index 11e92979156..f8944a74006 100644 --- a/src/glx/indirect_glx.c +++ b/src/glx/indirect_glx.c @@ -335,6 +335,10 @@ static const struct glx_context_vtable indirect_context_vtable = { * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new * function called \c __glXAllocateClientState that allocates the memory and * does all the initialization (including the pixel pack / unpack). + * + * \note + * This function is \b not the place to validate the context creation + * parameters. It is just the allocator for the \c glx_context. */ _X_HIDDEN struct glx_context * indirect_create_context(struct glx_screen *psc, diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c index 7a2cfbeda7c..def157f52df 100644 --- a/src/mesa/drivers/x11/fakeglx.c +++ b/src/mesa/drivers/x11/fakeglx.c @@ -2325,7 +2325,10 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, XMesaVisual xmvis = (XMesaVisual) config; if (!dpy || !config || - (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE)) + (renderType != GLX_RGBA_TYPE && + renderType != GLX_COLOR_INDEX_TYPE && + renderType != GLX_RGBA_FLOAT_TYPE_ARB && + renderType != GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT)) return 0; glxCtx = CALLOC_STRUCT(fake_glx_context); -- cgit v1.2.3