From fd461118b7a8112bddf1bb8a7dd6e94c86d8f96b Mon Sep 17 00:00:00 2001 From: Paul Drews Date: Wed, 18 Jan 2012 11:01:49 -0800 Subject: [PATCH] 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 Signed-off-by: Paul Drews --- opengl/libs/EGL/eglApi.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 0cc5265af2..c2ac5641c3 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -369,6 +370,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(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 // ---------------------------------------------------------------------------- @@ -408,6 +438,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); + } if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) { ALOGE("EGLNativeWindowType %p already connected to another API", window); -- 2.11.0