Mesa (master): glx/indirect: Validate the context version in CreateContextAttribs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Dec 3 05:01:59 UTC 2020


Module: Mesa
Branch: master
Commit: f39fd3dce72eaef59ab39a23b75030ef9efc2a40
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f39fd3dce72eaef59ab39a23b75030ef9efc2a40

Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Nov 10 16:23:23 2020 -0500

glx/indirect: Validate the context version in CreateContextAttribs

This is Sort Of handled by nerfing GL_VERSION in __indirect_glGetString,
but that doesn't cover GLES contexts which we also don't have any
indirect support for. Xorg's GLX would reject this for us since it has
the same limitation, but NVIDIA's GLX seems to interpret a request for
ES 2.0 as desktop, despite having the ES2 profile bit set, leading to a
very confusing GL_VERSION string and probably not the ES2-compatible
context you were hoping for.

Since we may now return NULL from indirect_create_context_attribs for
reasons other than malloc failure, we need to reasonably handle the case
where gc == NULL by the time we get to the XCB call. We rely on the
server to generate correct return values in this case, but if it
succeeds despite our client-side failure we just throw GLXBadFBConfig
(chosen to keep piglit/glx-create-context-core-profile happy, since
nothing else seems to hit it).

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7369>

---

 src/glx/create_context.c                  | 24 +++++++++++++++++-------
 src/glx/indirect_glx.c                    | 18 ++++++++++++++++++
 src/glx/tests/create_context_unittest.cpp |  9 +++++++++
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/src/glx/create_context.c b/src/glx/create_context.c
index 38e949ab4cd..11c1466ddcd 100644
--- a/src/glx/create_context.c
+++ b/src/glx/create_context.c
@@ -47,7 +47,7 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
    xcb_generic_error_t *err;
    xcb_void_cookie_t cookie;
    unsigned dummy_err = 0;
-
+   uint32_t xid, share_xid;
 
    if (dpy == NULL || cfg == NULL)
       return NULL;
@@ -90,8 +90,8 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
 #endif
    }
 
-   gc->xid = xcb_generate_id(c);
-   gc->share_xid = (share != NULL) ? share->xid : 0;
+   xid = xcb_generate_id(c);
+   share_xid = (share != NULL) ? share->xid : 0;
 
    /* The manual pages for glXCreateContext and glXCreateNewContext say:
     *
@@ -103,21 +103,31 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
     */
    cookie =
       xcb_glx_create_context_attribs_arb_checked(c,
-						 gc->xid,
+						 xid,
 						 cfg->fbconfigID,
 						 cfg->screen,
-						 gc->share_xid,
-						 gc->isDirect,
+						 share_xid,
+						 gc ? gc->isDirect : direct,
 						 num_attribs,
 						 (const uint32_t *)
 						 attrib_list);
    err = xcb_request_check(c, cookie);
    if (err != NULL) {
-      gc->vtable->destroy(gc);
+      if (gc)
+         gc->vtable->destroy(gc);
       gc = NULL;
 
       __glXSendErrorForXcb(dpy, err);
       free(err);
+   } else if (!gc) {
+      /* the server thought the context description was okay, but we failed
+       * somehow on the client side. clean up the server resource and panic.
+       */
+      xcb_glx_destroy_context(c, xid);
+      __glXSendError(dpy, GLXBadFBConfig, xid, 0, False);
+   } else {
+      gc->xid = xid;
+      gc->share_xid = share_xid;
    }
 
    return (GLXContext) gc;
diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
index a7a6ba5f13b..5c8e71beb39 100644
--- a/src/glx/indirect_glx.c
+++ b/src/glx/indirect_glx.c
@@ -382,6 +382,9 @@ indirect_create_context_attribs(struct glx_screen *psc,
    CARD8 opcode;
    __GLXattribute *state;
    int i, renderType = GLX_RGBA_TYPE;
+   uint32_t mask = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+   uint32_t major = 1;
+   uint32_t minor = 0;
 
    opcode = __glXSetupForCommand(psc->dpy);
    if (!opcode) {
@@ -393,6 +396,21 @@ indirect_create_context_attribs(struct glx_screen *psc,
 
       if (attr == GLX_RENDER_TYPE)
          renderType = val;
+      if (attr == GLX_CONTEXT_PROFILE_MASK_ARB)
+         mask = val;
+      if (attr == GLX_CONTEXT_MAJOR_VERSION_ARB)
+         major = val;
+      if (attr == GLX_CONTEXT_MINOR_VERSION_ARB)
+         minor = val;
+   }
+
+   /* We have no indirect support for core or ES contexts, and our compat
+    * context support is limited to GL 1.4.
+    */
+   if (mask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ||
+       major != 1 ||
+       minor > 4) {
+      return NULL;
    }
 
    /* Allocate our context record */
diff --git a/src/glx/tests/create_context_unittest.cpp b/src/glx/tests/create_context_unittest.cpp
index a2590589db2..448dbea10f6 100644
--- a/src/glx/tests/create_context_unittest.cpp
+++ b/src/glx/tests/create_context_unittest.cpp
@@ -101,6 +101,15 @@ xcb_glx_create_context_attribs_arb_checked(xcb_connection_t *c,
    return cookie;
 }
 
+extern "C" xcb_void_cookie_t
+xcb_glx_destroy_context(xcb_connection_t *c, xcb_glx_context_t context)
+{
+   xcb_void_cookie_t cookie;
+   cookie.sequence = 0xbadc0de;
+
+   return cookie;
+}
+
 extern "C" xcb_generic_error_t *
 xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
 {



More information about the mesa-commit mailing list