Skip to content

Fix NULL pointer dereference in RE_Shutdown when renderer interface is not initialized#372

Merged
ec- merged 1 commit intoec-:mainfrom
runlevel5:fix-renderer-shutdown-null-deref
Feb 11, 2026
Merged

Fix NULL pointer dereference in RE_Shutdown when renderer interface is not initialized#372
ec- merged 1 commit intoec-:mainfrom
runlevel5:fix-renderer-shutdown-null-deref

Conversation

@runlevel5
Copy link
Contributor

Summary

  • Add NULL guards for ri.GLimp_Shutdown and ri.VKimp_Shutdown calls in RE_Shutdown() across all three renderers (opengl, opengl2, vulkan)

Problem

When the client binary is built without USE_OPENGL_API (e.g. RENDERER_DEFAULT=vulkan with USE_RENDERER_DLOPEN=0) but later loads the OpenGL renderer .so at runtime, ri.GLimp_Init is NULL. The renderer correctly detects this at InitOpenGL() and calls ri.Error(ERR_FATAL, "OpenGL interface is not initialized"), but the resulting shutdown path in RE_Shutdown() calls ri.GLimp_Shutdown() without checking for NULL, causing a SIGSEGV at address 0x0.

The same issue applies to ri.VKimp_Shutdown in the vulkan renderer's #ifdef USE_VULKAN path and to ri.GLimp_Shutdown in its #else fallback path.

Crash backtrace

#0  0x0000000000000000 in ?? ()
#1  RE_Shutdown (code=REF_UNLOAD_DLL) at code/renderer/tr_init.c:1935
#2  CL_ShutdownRef (code=REF_UNLOAD_DLL) at code/client/cl_main.c:3174
#3  CL_Shutdown (...) at code/client/cl_main.c:4083
#4  Com_Error (code=ERR_FATAL, fmt="OpenGL interface is not initialized") at code/qcommon/common.c:397
#5  InitOpenGL () at code/renderer/tr_init.c:588

GDB confirms the function pointers are NULL:

GLimp_Init = 0x0
GLimp_Shutdown = 0x0
GLimp_EndFrame = 0x0
GL_GetProcAddress = 0x0
VKimp_Init = 0x10173890 <VKimp_Init>     // populated
VKimp_Shutdown = 0x10173c3c <VKimp_Shutdown>  // populated

Fix

Simple NULL guards before the function pointer calls in RE_Shutdown():

  • code/renderer/tr_init.c — guard ri.GLimp_Shutdown
  • code/renderer2/tr_init.c — guard ri.GLimp_Shutdown
  • code/renderervk/tr_init.c — guard both ri.VKimp_Shutdown and ri.GLimp_Shutdown

Testing

Tested on ppc64le (Power9, AMD RX 6600 XT, Fedora 43):

  • Built client with USE_OPENGL_API=0, loaded OpenGL renderer: previously crashed with SIGSEGV, now exits cleanly with Sys_Error: OpenGL interface is not initialized
  • Both OpenGL and Vulkan renderers still work correctly with a normal build (regression test)

…s not initialized

Add NULL guards for ri.GLimp_Shutdown and ri.VKimp_Shutdown calls in
RE_Shutdown() across all three renderers (opengl, opengl2, vulkan).

When the client binary is built without USE_OPENGL_API (e.g.
RENDERER_DEFAULT=vulkan with USE_RENDERER_DLOPEN=0) but later loads the
OpenGL renderer .so at runtime, ri.GLimp_Init is NULL. The renderer
correctly detects this and calls ri.Error(ERR_FATAL), but the resulting
shutdown path in RE_Shutdown calls ri.GLimp_Shutdown without checking
for NULL, causing a SIGSEGV at address 0x0.
@ec- ec- merged commit 2fe0918 into ec-:main Feb 11, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants