From 11b348e9b8a050622d1e7ebe66e69dcb11fe575c Mon Sep 17 00:00:00 2001 From: Amit Mishra Date: Sat, 27 Jun 2026 18:05:32 +0530 Subject: [PATCH] fix: prevent use-after-free in switch_output_file on basename failure If get_basename(enc_ctx->out->original_filename) returns NULL, the function left enc_ctx->out->filename pointing at memory it had just freed a few lines above, then unconditionally passed enc_ctx->out to write_subtitle_file_header(), which dereferences filename downstream (write_subtitle_file_header -> write_spumux_header -> spunpg_init). NULL the pointer immediately after freeing it, and return early (with a warning) when no basename can be derived, instead of falling through to use a context with no valid filename/handle. Fixes #2273. --- src/lib_ccx/ccx_encoders_common.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/lib_ccx/ccx_encoders_common.c b/src/lib_ccx/ccx_encoders_common.c index 749d2e75f..97f38e4a6 100644 --- a/src/lib_ccx/ccx_encoders_common.c +++ b/src/lib_ccx/ccx_encoders_common.c @@ -1361,18 +1361,25 @@ void switch_output_file(struct lib_ccx_ctx *ctx, struct encoder_ctx *enc_ctx, in if (enc_ctx->out->filename != NULL) { // Close and release the previous handle free(enc_ctx->out->filename); + enc_ctx->out->filename = NULL; close(enc_ctx->out->fh); } const char *ext = get_file_extension(ctx->write_format); char suffix[32]; snprintf(suffix, sizeof(suffix), "_%d", track_id); char *basename = get_basename(enc_ctx->out->original_filename); - if (basename != NULL) + if (basename == NULL) { - enc_ctx->out->filename = create_outfilename(basename, suffix, ext); - enc_ctx->out->fh = open(enc_ctx->out->filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE); - free(basename); + // Without a basename there is no valid filename/handle to write + // to; bail out instead of falling through to write_subtitle_file_header() + // with the NULLed filename above (or, before that fix, a dangling + // pointer to the just-freed previous filename - see issue #2273). + mprint("WARNING: Unable to determine basename for output file when switching to track %d.\n", track_id); + return; } + enc_ctx->out->filename = create_outfilename(basename, suffix, ext); + enc_ctx->out->fh = open(enc_ctx->out->filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE); + free(basename); write_subtitle_file_header(enc_ctx, enc_ctx->out);