View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0000678 | Cinelerra-GG | Bug | public | 2026-07-06 06:48 | 2026-07-06 06:48 |
| Reporter | tarceri | Assigned To | |||
| Priority | high | Severity | major | Reproducibility | always |
| Status | new | Resolution | open | ||
| Summary | 0000678: gl_fb_config values not cleared after being freed | ||||
| Description | BC_DisplayInfo::gl_fb_config() uses if-statements to check if fb_cfgs and vis_info are null but when BC_DisplayInfo::gl_probe() frees them it doesn't clear the pointers. So any further gl_fb_config()/gl_probe() calls will risk use after free and double free issues. I've attach a patch with a fix but its untested as I don't use the software I'm just looking into the Mesa bug report: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/11976 with Mesa drivers the OpenGL backend is currently unusable. | ||||
| Steps To Reproduce | Select OpenGL mode | ||||
| Tags | No tags attached. | ||||
| Attached Files | 0001-guicast-dont-free-gl-fb-config-until-destruction.patch (2,365 bytes)
From 1cfcd8327707d27693a0fcdcfc6a238acc47a4e2 Mon Sep 17 00:00:00 2001
From: Timothy Arceri <tarceri@itsqueeze.com>
Date: Mon, 6 Jul 2026 14:27:55 +1000
Subject: [PATCH] guicast: dont free gl fb config until destruction
BC_DisplayInfo::gl_fb_config() uses if-statements to check if
fb_cfgs and vis_info are null but when BC_DisplayInfo::gl_probe()
frees them it doesn't clear the pointers. This can lead to use
after free and double free issues. Instead free gl fb cfgs
on destruction.
Fixes: 59e74f262d7b
---
cinelerra-5.1/guicast/bcdisplayinfo.C | 32 +++++++++++++++------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/cinelerra-5.1/guicast/bcdisplayinfo.C b/cinelerra-5.1/guicast/bcdisplayinfo.C
index 62d58338..5e153dd9 100644
--- a/cinelerra-5.1/guicast/bcdisplayinfo.C
+++ b/cinelerra-5.1/guicast/bcdisplayinfo.C
@@ -63,6 +63,10 @@ BC_DisplayInfo::BC_DisplayInfo(const char *display_name, int show_error)
BC_DisplayInfo::~BC_DisplayInfo()
{
if( xinerama_info ) XFree(xinerama_info);
+#ifdef HAVE_GL
+ if( fb_cfgs ) XFree(fb_cfgs);
+ if( vis_info ) XFree(vis_info);
+#endif
#ifndef SINGLE_THREAD
XCloseDisplay(display);
#endif
@@ -212,19 +216,21 @@ int BC_DisplayInfo::gl_fb_config()
fb_cfgs = glXChooseFBConfig(display, scrnum, fb_attrs+2, &ncfgs);
if( fb_cfgs && ncfgs ) break;
fb_cfgs = glXChooseFBConfig(display, scrnum, fb_attrs+0, &ncfgs);
+
+ if( fb_cfgs && ncfgs ) {
+ for( int i=0; !vis_info && i<ncfgs; ++i )
+ vis_info = glXGetVisualFromFBConfig(display, cfg=fb_cfgs[i]);
+ }
+ if( vis_info ) {
+ vis = vis_info->visual;
+ depth = vis_info->depth;
+ }
+ else {
+ printf("%s\n", "BC_DisplayInfo::gl_fb_config failed");
+ cfg = 0;
+ }
} while(0);
- if( fb_cfgs && ncfgs ) {
- for( int i=0; !vis_info && i<ncfgs; ++i )
- vis_info = glXGetVisualFromFBConfig(display, cfg=fb_cfgs[i]);
- }
- if( vis_info ) {
- vis = vis_info->visual;
- depth = vis_info->depth;
- }
- else {
- printf("%s\n", "BC_DisplayInfo::gl_fb_config failed");
- cfg = 0;
- }
+
return 0;
}
@@ -246,8 +252,6 @@ int BC_DisplayInfo::gl_probe(Window win)
glXMakeContextCurrent(display, None, None, 0);
if( glx_ctx ) glXDestroyContext(display, glx_ctx);
if( glx_win ) glXDestroyWindow(display, glx_win);
- if( fb_cfgs ) XFree(fb_cfgs);
- if( vis_info ) XFree(vis_info);
return 0;
}
#endif
--
2.54.0
| ||||