Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0480de3 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

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
parent 7cd230c5
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -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
+24 −24
Original line number Diff line number Diff line
@@ -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);

+5 −3
Original line number Diff line number Diff line
@@ -62,12 +62,14 @@ 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) {
        if (object->getDisplay() == this) {
            object->incRef();
            return true;
        }
    }
    return false;
}

+4 −4
Original line number Diff line number Diff line
@@ -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);
@@ -120,7 +120,7 @@ public:

private:
            uint32_t                    refs;
    Mutex           lock;
    mutable Mutex                       lock;
            SortedVector<egl_object_t*> objects;
};

+2 −2
Original line number Diff line number Diff line
@@ -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);
}

// ----------------------------------------------------------------------------
Loading