use-after-free of GdkGLContext when using ngl + llvmpipe or softpipe
Steps to reproduce
Run a reftest with the ngl renderer (or run in an environment with no hardware Vulkan driver available so that GTK falls back to GL by default), and use LIBGL_ALWAYS_SOFTWARE=true
to force Mesa to use llvmpipe or softpipe (or run in an environment with no access to a GPU, such as a Linux distribution autobuilder). I used an AddressSanitizer build of GTK, with:
ASAN_OPTIONS=detect_leaks=0,fast_unwind_on_malloc=false \
LIBGL_ALWAYS_SOFTWARE=true \
GDK_BACKEND=wayland \
GSK_RENDERER=ngl \
meson test -C ~/tmp/build/gtk/asan 'reftest window-height-for-width.ui'
Current behavior
There's a use-after-free of the GdkGLContext. When not using AddressSanitizer, this typically manifests as a GDK_IS_GL_CONTEXT
assertion failure, and debugging indicates that the object has been filled with "poison" bytes. With AddressSanitizer, it's diagnosed:
==1186312==ERROR: AddressSanitizer: heap-use-after-free on address 0x5120001637b0 at pc 0x7fd679ea0504 bp 0x7ffc2cba58e0 sp 0x7ffc2cba58d8
READ of size 8 at 0x5120001637b0 thread T0
#0 0x7fd679ea0503 in gdk_gl_context_make_current ../../../../src/gtk/gdk/gdkglcontext.c:1840
#1 0x7fd679ea7a37 in gdk_gl_texture_invoke_callback ../../../../src/gtk/gdk/gdkgltexture.c:116
#2 0x7fd679136ff4 in g_main_context_invoke_full (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5dff4) (BuildId: 52ef4dac9c06d1b0b7d01b53d9910769fc90f641)
#3 0x7fd679ea7532 in gdk_gl_texture_run ../../../../src/gtk/gdk/gdkgltexture.c:130
#4 0x7fd679ea77fb in gdk_gl_texture_download ../../../../src/gtk/gdk/gdkgltexture.c:436
#5 0x7fd679edcba4 in gdk_texture_do_download ../../../../src/gtk/gdk/gdktexture.c:840
#6 0x7fd679edea0e in gdk_texture_downloader_download_into ../../../../src/gtk/gdk/gdktexturedownloader.c:267
#7 0x7fd67b0cd43d in reftest_compare_textures ../../../../src/gtk/testsuite/reftests/reftest-compare.c:292
#8 0x56490444c9a6 in test_ui_file ../../../../src/gtk/testsuite/reftests/gtk-reftest.c:375
...
0x5120001637b0 is located 240 bytes inside of 296-byte region [0x5120001636c0,0x5120001637e8)
freed by thread T0 here:
#0 0x7fd67aaf3978 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7fd6790ae5ce in g_type_free_instance (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x385ce) (BuildId: f9b9a09397d517f0a0bc98ad66679e3b91680151)
#2 0x7fd6790924f5 in g_object_unref (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x1c4f5) (BuildId: f9b9a09397d517f0a0bc98ad66679e3b91680151)
#3 0x7fd679e9beb9 in unref_unmasked ../../../../src/gtk/gdk/gdkglcontext.c:191
#4 0x7fd679ea04b4 in gdk_gl_context_make_current ../../../../src/gtk/gdk/gdkglcontext.c:1879
#5 0x7fd679ea78b7 in gdk_gl_texture_invoke_callback ../../../../src/gtk/gdk/gdkgltexture.c:104
#6 0x7fd679136ff4 in g_main_context_invoke_full (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5dff4) (BuildId: 52ef4dac9c06d1b0b7d01b53d9910769fc90f641)
#7 0x7fd679ea7532 in gdk_gl_texture_run ../../../../src/gtk/gdk/gdkgltexture.c:130
#8 0x7fd679ea77fb in gdk_gl_texture_download ../../../../src/gtk/gdk/gdkgltexture.c:436
#9 0x7fd679edcba4 in gdk_texture_do_download ../../../../src/gtk/gdk/gdktexture.c:840
#10 0x7fd679edea0e in gdk_texture_downloader_download_into ../../../../src/gtk/gdk/gdktexturedownloader.c:267
#11 0x7fd67b0cd43d in reftest_compare_textures ../../../../src/gtk/testsuite/reftests/reftest-compare.c:292
#12 0x56490444c9a6 in test_ui_file ../../../../src/gtk/testsuite/reftests/gtk-reftest.c:375
...
previously allocated by thread T0 here:
#0 0x7fd67aaf4690 in calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x7fd67913cbd9 in g_malloc0 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x63bd9) (BuildId: 52ef4dac9c06d1b0b7d01b53d9910769fc90f641)
#2 0x7fd6790afbf9 in g_type_create_instance (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x39bf9) (BuildId: f9b9a09397d517f0a0bc98ad66679e3b91680151)
#3 0x7fd679092abf (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x1cabf) (BuildId: f9b9a09397d517f0a0bc98ad66679e3b91680151)
#4 0x7fd6790956ba in g_object_new_valist (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x1f6ba) (BuildId: f9b9a09397d517f0a0bc98ad66679e3b91680151)
#5 0x7fd679095a0c in g_object_new (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x1fa0c) (BuildId: f9b9a09397d517f0a0bc98ad66679e3b91680151)
#6 0x7fd679e9c349 in gdk_gl_context_new ../../../../src/gtk/gdk/gdkglcontext.c:846
#7 0x7fd679f7e052 in gsk_ngl_renderer_create_context ../../../../src/gtk/gsk/gpu/gsknglrenderer.c:51
#8 0x7fd67a04ff58 in gsk_gpu_renderer_realize ../../../../src/gtk/gsk/gpu/gskgpurenderer.c:217
#9 0x7fd679f1120a in gsk_renderer_do_realize ../../../../src/gtk/gsk/gskrenderer.c:272
#10 0x7fd679f12140 in gsk_renderer_realize ../../../../src/gtk/gsk/gskrenderer.c:325
#11 0x7fd679f12df1 in gsk_renderer_new_for_surface ../../../../src/gtk/gsk/gskrenderer.c:782
#12 0x7fd679a428ba in gtk_window_realize ../../../../src/gtk/gtk/gtkwindow.c:4304
For whatever reason, if I don't force LIBGL_ALWAYS_SOFTWARE=true
and let GTK use my GPU (Intel + Mesa), this doesn't happen.
Expected outcome
Test passes, no issues detected by AddressSanitizer
Version information
- GTK 4.16.0, bug still reproducible in GTK git main as of 43303bf7
- Linux 6.10
- Debian testing/unstable rolling release
- Mesa 24.2.2
- Locally built GTK,
--buildtype=debug -Dmedia-gstreamer=disabled
, otherwise default options (I also used AddressSanitizer but the crash is reproducible without it)