summaryrefslogtreecommitdiffstats
path: root/opengl/libs
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2011-11-13 20:50:07 -0800
committerMathias Agopian <mathias@google.com>2011-11-14 17:40:21 -0800
commit274e03c90ee6054e81a16b1bd0a54258e08ddee9 (patch)
tree1ec08e7176e5253e7561d373e35cf572a1bafe18 /opengl/libs
parent6b228af6ff20b3f592db4ad5662e1bc401d09b4d (diff)
downloadframeworks_base-274e03c90ee6054e81a16b1bd0a54258e08ddee9.zip
frameworks_base-274e03c90ee6054e81a16b1bd0a54258e08ddee9.tar.gz
frameworks_base-274e03c90ee6054e81a16b1bd0a54258e08ddee9.tar.bz2
fix crash when validating an invalid EGL objects
the code that validated EGL objects dereferenced the object to access its EGLDisplay -- needed for validation (!). This was wrong for two reasons, first we dereferenced the object before validating it (potentially leading to a crash), secondly we didn't validate that the object existed in the right EGLDisplay. We now use the EGLDisplay passed by the user API. Change-Id: I66f9e851d4f8507892a6b1fee3065f124c4e7138
Diffstat (limited to 'opengl/libs')
-rw-r--r--opengl/libs/EGL/egl.cpp14
-rw-r--r--opengl/libs/EGL/eglApi.cpp48
-rw-r--r--opengl/libs/EGL/egl_display.cpp8
-rw-r--r--opengl/libs/EGL/egl_display.h8
-rw-r--r--opengl/libs/EGL/egl_object.cpp4
-rw-r--r--opengl/libs/EGL/egl_object.h7
6 files changed, 48 insertions, 41 deletions
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 1e43195..6ad06af 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -212,16 +212,20 @@ egl_connection_t* validate_display_config(EGLDisplay dpy, EGLConfig config,
EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
{
- ImageRef _i(image);
- if (!_i.get())
- return EGL_NO_IMAGE_KHR;
-
EGLContext context = egl_tls_t::getContext();
if (context == EGL_NO_CONTEXT || image == EGL_NO_IMAGE_KHR)
return EGL_NO_IMAGE_KHR;
egl_context_t const * const c = get_context(context);
- if (c == NULL) // this should never happen
+ if (c == NULL) // this should never happen, by construction
+ return EGL_NO_IMAGE_KHR;
+
+ egl_display_t* display = egl_display_t::get(c->dpy);
+ if (display == NULL) // this should never happen, by construction
+ return EGL_NO_IMAGE_KHR;
+
+ ImageRef _i(display, image);
+ if (!_i.get())
return EGL_NO_IMAGE_KHR;
// here we don't validate the context because if it's been marked for
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 63f02e4..095f10c 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -451,7 +451,7 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -472,7 +472,7 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -541,7 +541,7 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
if (!dp)
return EGL_FALSE;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -592,9 +592,9 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
}
// get a reference to the object passed in
- ContextRef _c(ctx);
- SurfaceRef _d(draw);
- SurfaceRef _r(read);
+ ContextRef _c(dp, ctx);
+ SurfaceRef _d(dp, draw);
+ SurfaceRef _r(dp, read);
// validate the context (if not EGL_NO_CONTEXT)
if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
@@ -696,7 +696,7 @@ EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
egl_context_t * const c = get_context(ctx);
@@ -944,7 +944,7 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(draw);
+ SurfaceRef _s(dp, draw);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -960,7 +960,7 @@ EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface,
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1002,7 +1002,7 @@ EGLBoolean eglSurfaceAttrib(
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1022,7 +1022,7 @@ EGLBoolean eglBindTexImage(
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1042,7 +1042,7 @@ EGLBoolean eglReleaseTexImage(
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1201,7 +1201,7 @@ EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1220,7 +1220,7 @@ EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1241,7 +1241,7 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
if (!dp) return EGL_NO_IMAGE_KHR;
if (ctx != EGL_NO_CONTEXT) {
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
egl_context_t * const c = get_context(ctx);
@@ -1310,7 +1310,7 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- ImageRef _i(img);
+ ImageRef _i(dp, img);
if (!_i.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
egl_image_t* image = get_image(img);
@@ -1349,7 +1349,7 @@ EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_l
if (!dp) return EGL_NO_SYNC_KHR;
EGLContext ctx = eglGetCurrentContext();
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
@@ -1372,12 +1372,12 @@ EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SyncRef _s(sync);
+ SyncRef _s(dp, sync);
if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
egl_sync_t* syncObject = get_sync(sync);
EGLContext ctx = syncObject->context;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -1399,12 +1399,12 @@ EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTi
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SyncRef _s(sync);
+ SyncRef _s(dp, sync);
if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
egl_sync_t* syncObject = get_sync(sync);
EGLContext ctx = syncObject->context;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -1424,13 +1424,13 @@ EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SyncRef _s(sync);
+ SyncRef _s(dp, sync);
if (!_s.get())
return setError(EGL_BAD_PARAMETER, EGL_FALSE);
egl_sync_t* syncObject = get_sync(sync);
EGLContext ctx = syncObject->context;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -1455,7 +1455,7 @@ EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(draw);
+ SurfaceRef _s(dp, draw);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 558ca77..2935832 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -62,11 +62,13 @@ void egl_display_t::removeObject(egl_object_t* object) {
objects.remove(object);
}
-bool egl_display_t::getObject(egl_object_t* object) {
+bool egl_display_t::getObject(egl_object_t* object) const {
Mutex::Autolock _l(lock);
if (objects.indexOf(object) >= 0) {
- object->incRef();
- return true;
+ if (object->getDisplay() == this) {
+ object->incRef();
+ return true;
+ }
}
return false;
}
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index e0a367d..94077be 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -81,7 +81,7 @@ public:
// remove object from this display's list
void removeObject(egl_object_t* object);
// add reference to this object. returns true if this is a valid object.
- bool getObject(egl_object_t* object);
+ bool getObject(egl_object_t* object) const;
static egl_display_t* get(EGLDisplay dpy);
@@ -119,9 +119,9 @@ public:
egl_config_t* configs;
private:
- uint32_t refs;
- Mutex lock;
- SortedVector<egl_object_t*> objects;
+ uint32_t refs;
+ mutable Mutex lock;
+ SortedVector<egl_object_t*> objects;
};
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index dbf9a01..20cdc7e 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -55,10 +55,10 @@ void egl_object_t::destroy() {
}
}
-bool egl_object_t::get() {
+bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) {
// used by LocalRef, this does an incRef() atomically with
// checking that the object is valid.
- return display->getObject(this);
+ return display->getObject(object);
}
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 46f7139..df1b261 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -52,10 +52,11 @@ public:
inline int32_t incRef() { return android_atomic_inc(&count); }
inline int32_t decRef() { return android_atomic_dec(&count); }
+ inline egl_display_t* getDisplay() const { return display; }
private:
void terminate();
- bool get();
+ static bool get(egl_display_t const* display, egl_object_t* object);
public:
template <typename N, typename T>
@@ -66,9 +67,9 @@ public:
public:
~LocalRef();
explicit LocalRef(egl_object_t* rhs);
- explicit LocalRef(T o) : ref(0) {
+ explicit LocalRef(egl_display_t const* display, T o) : ref(0) {
egl_object_t* native = reinterpret_cast<N*>(o);
- if (o && native->get()) {
+ if (o && egl_object_t::get(display, native)) {
ref = native;
}
}