This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

X11 Display pointer check bug

Hi,

A normal way to integrate Mali on Linux/X11 is to first open a connection with the X server and get an X display pointer via XOpenDisplay(), and pass that to eglGetDisplay() to get the equivalent EGL display pointer.

We are seeing a bug where sometimes eglGetDisplay() fails for no obvious reason. This is most reproducible in Chromium although later analysis shows that this bug is not in any way related to Chromium.

XOpenDisplay() returns a pointer (or NULL on error). However, Mali seems to treat it as a number in __egl_platform_display_valid:

00058360 <__egl_platform_display_valid>:

   58360:       2800            cmp     r0, #0

   58362:       d002            beq.n   5836a <__egl_platform_display_valid+0xa>

   58364:       bfd4            ite     le

   58366:       2000            movle   r0, #0

   58368:       2001            movgt   r0, #1

   5836a:       4770            bx      lr

The above code takes the X Display pointer as an input in r0 and says:

  • If the input is 0, return 0 (failure)
  • If the input is less than or equal to 0, return 0 (failure)
  • else return 1 (success)

So, the X display pointer is being interpreted as a number. That means that if the pointer happens to have the high bit set (which can and does happen sometimes), the pointer will be interpreted as a negative number, so __egl_platform_display_valid will incorrectly return failure and eglGetDisplay() will fail.


Here is a test app that shows the problem:

#include <X11/Xlib.h>

#include <EGL/egl.h>

#include <stdio.h>

int main(int argc, char *argv[])

{

   EGLDisplay egl_dpy;

   Display *x_dpy = 1 << 31; // set high bit in display pointer

   printf("try with dpy %p\n", x_dpy);

   egl_dpy = eglGetDisplay(x_dpy);

   if (!egl_dpy)

      printf("eglGetDisplay failed\n");

   else

      printf("eglGetDisplay OK\n");

}

The above test app passes an X display pointer of 0x80000000. eglGetDisplay() is here expected to return success, or crash (because we've passed in a nonsense X display value). Instead, it returns failure.

This has been reproduced in r3p2-01rel0 but the same buggy assembly code is also present in r4p0.