GNOME Bugzilla – Bug 786051
glupload: EGLImage cache is not thread safe
Last modified: 2018-11-03 11:59:03 UTC
When we receive a DMABuf, we create a cache associated EGLImage. While the wrapper is refcounted, the way we store that EGLImage is not thread safe. The problem is that we don't get and ref the EGLImage atomically when retrieving the qdata. So in between, sometimes the EGLImage get destroyed, and then we ended with use after free crashing GStreamer or Mesa. The pipeline I use to reproduce currently: gst-launch-1.0 v4l2src device=/dev/video1 io-mode=dmabuf ! tee name=t \ t. ! queue ! glsinkbin sink=gtkglsink \ t. ! queue ! glsinkbin sink=gtkglsink \ t. ! queue ! glsinkbin sink=gtkglsink \ t. ! queue ! glsinkbin sink=gtkglsink \ t. ! queue ! glsinkbin sink=gtkglsink
I thought a moment we could use gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE) ? but in fact it is a try-lock. Can we guard that for loop (around get_cache/set_cache) with gst_gl_display_lock/unlock ? This should be the same GstGLDisplay instance since it is per pipeline if I am correct. Or using gst_memory_share somehow ? So that all memories going out of the tee are not the same GstMemory instances as the input. It solves the race while not using a global lock. It will create much more eglimage but these are just references of the same underlying memory.
We need a local cache anyway to implement drain properly (see kmssink recent changes). As soon as you have that, it's easy to stop using qdata. I prefer using a cache per uploader, since it removes the contention.
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/375.