From 314f576515585560ea6b375b0d5b8a02fd8991af Mon Sep 17 00:00:00 2001 From: MrBruh <4706866+cybersecurity@users.noreply.github.com> Date: Thu, 8 Oct 2026 10:20:47 +1300 Subject: [PATCH] Never free NULL in the Custom Edition loader The game's free (debug_free) reads a header before the pointer, so NULL faults at 0xffffffe0. A Custom Edition sound that failed to decode freed its frames with none made, which crashed Linux on loading CMT's a30 with Custom Edition's later sounds.map; the decoded sounds, model data and scratch buffer are now freed only when they were made. --- port/linux/game/custom_edition_cache.c | 4 +++- port/linux/game/custom_edition_geometry.c | 4 +++- port/linux/game/custom_edition_sounds.c | 8 ++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/port/linux/game/custom_edition_cache.c b/port/linux/game/custom_edition_cache.c index 4563da4e..3881b943 100644 --- a/port/linux/game/custom_edition_cache.c +++ b/port/linux/game/custom_edition_cache.c @@ -291,7 +291,9 @@ static boolean custom_edition_cache_models_convert( report, model_data); } - free(model_data); + /* (the game's free, debug_free, does not take NULL) */ + if (model_data) + free(model_data); return success; } diff --git a/port/linux/game/custom_edition_geometry.c b/port/linux/game/custom_edition_geometry.c index 232fcee7..c579f3fb 100644 --- a/port/linux/game/custom_edition_geometry.c +++ b/port/linux/game/custom_edition_geometry.c @@ -813,7 +813,9 @@ boolean custom_edition_models_convert( if (!globals->model_parts || !globals->model_geometry || !globals->palettes || !scratch) { error(_error_silent, "custom edition: out of memory for the geometry of %ld model parts", totals.part_count); - free(scratch); + /* (the game's free, debug_free, does not take NULL) */ + if (scratch) + free(scratch); return FALSE; } vertices = (struct model_vertex_compressed *)globals->model_geometry; diff --git a/port/linux/game/custom_edition_sounds.c b/port/linux/game/custom_edition_sounds.c index cf1123b3..f7c62b7f 100644 --- a/port/linux/game/custom_edition_sounds.c +++ b/port/linux/game/custom_edition_sounds.c @@ -205,10 +205,12 @@ struct frames long rate; }; +/* (none may have been made: the game's free, debug_free, does not take NULL) */ static void frames_free( struct frames *frames) { - free(frames->samples); + if (frames->samples) + free(frames->samples); frames->samples = NULL; } @@ -630,7 +632,9 @@ boolean custom_edition_sounds_read( void custom_edition_sounds_dispose( void) { - free(custom_edition_sounds_globals.decoded); + /* (none, when no sound needed decoding: debug_free does not take NULL) */ + if (custom_edition_sounds_globals.decoded) + free(custom_edition_sounds_globals.decoded); memset(&custom_edition_sounds_globals, 0, sizeof(custom_edition_sounds_globals)); return;