diff options
author | Paul Drews <paul.drews@intel.com> | 2012-01-18 11:01:49 -0800 |
---|---|---|
committer | Chih-Wei Huang <cwhuang@linux.org.tw> | 2016-05-06 01:55:11 +0800 |
commit | a5252da6a4c6064d71eed6cd9824ad3e0e047589 (patch) | |
tree | 4eeb86aa9a6f6f8b58fdd425f8c6a3716ed54d89 | |
parent | dd07995c754e7281e788d24f66b7363afa173c4f (diff) | |
download | frameworks_native-a5252da6a4c6064d71eed6cd9824ad3e0e047589.zip frameworks_native-a5252da6a4c6064d71eed6cd9824ad3e0e047589.tar.gz frameworks_native-a5252da6a4c6064d71eed6cd9824ad3e0e047589.tar.bz2 |
Pre-test native window pointer for validity
This fixes a segfault in the oglconform tests when running
the test:
adb shell /data/app/oglconform -v 4 -minFmt -es -test egl-basic negative.drawables.winSurfBadWin
According the the egl specification this should return
EGL_BAD_NATIVE_WINDOW. The segfault was resulting from the
fact that the window handle is a (cast to opaque) pointer,
and there are not straightforward ways of pre-testing a
pointer for validity. The fix implemented here is:
() Take advantage of the msync() system-call logic to test
pre-test basic pointer validity
() Once confirmed that we can reference through the
pointer, look for the "magic" value dropped in by the
implementation to mark this type at runtime.
Change-Id: Id7d21c822c8a416e45caba25c63d7076d1e547a5
Original-Change-Id: I3c8df8ef5ece5c0fa71c47417766b5453c355f8b
Signed-off-by: Russell Webb <russell.webb@intel.com>
Signed-off-by: Paul Drews <paul.drews@intel.com>
-rw-r--r-- | opengl/libs/EGL/eglApi.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index cdec565..fc71662 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -23,6 +23,7 @@ #include <hardware/gralloc.h> #include <system/window.h> +#include <sys/mman.h> #include <EGL/egl.h> #include <EGL/eglext.h> @@ -414,6 +415,35 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, } // ---------------------------------------------------------------------------- +// Utility procedure to test a NativeWindowType for validity before referencing +// through the pointer. It's not feasible to test for deliberate forgeries, +// but this heuristic is good enough to test for basic accidental cases, using +// the special "magic" value placed in a native-window structure. +// ---------------------------------------------------------------------------- +EGLBoolean isValidNativeWindow(NativeWindowType window) +{ + ANativeWindow *nwindow = static_cast<ANativeWindow*>(window); + // the msync system call returns with ENOMEM error for unmapped memory + // pages. This is used here as a way to test whether we can read through a + // pointer without getting a segfault. + uintptr_t pagesize = (uintptr_t) sysconf(_SC_PAGESIZE); + uintptr_t addr = ((uintptr_t)(&nwindow->common.magic)) & (~(pagesize - 1)); + int rc = msync((void *)addr, pagesize, MS_ASYNC); + if (0 == rc) { + if (nwindow->common.magic == ANDROID_NATIVE_WINDOW_MAGIC) + return EGL_TRUE; + else + return EGL_FALSE; + } + if (ENOMEM == errno) + return EGL_FALSE; + ALOGE("error unexpected msync error: %s (%d)", + strerror(-errno), errno); + return EGL_FALSE; +} + + +// ---------------------------------------------------------------------------- // surfaces // ---------------------------------------------------------------------------- @@ -448,6 +478,10 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, if (dp) { EGLDisplay iDpy = dp->disp.dpy; + if (!isValidNativeWindow(window)) { + ALOGE("EGLNativeWindow %p invalid", window); + return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); + } int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); if (result != OK) { ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) " |