]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
xz: Fix --files/--files0 usage via XZ_OPT and XZ_DEFAULTS env vars master
authorrootvector2 <dxbnaveed.k@gmail.com>
Thu, 28 May 2026 06:59:23 +0000 (12:29 +0530)
committerLasse Collin <lasse.collin@tukaani.org>
Thu, 28 May 2026 10:22:55 +0000 (13:22 +0300)
If --files=FILELIST or --files0=FILELIST was specified via an enrivonment
variable, it worked if there were no errors when reading from the file
FILELIST. However, if an error occurred when reading from FILELIST,
there was a use-after-free bug when printing the error message because
the memory containing the string "FILELIST" had been freed.

    printf foo.xz > filelist.txt
    XZ_OPT=--files=filelist.txt xz -l

Because filelist.txt doesn't end in a newline, the file list is seen as
invalid/truncated, resulting in an error message like this:

    xz: ????????.txt: Unexpected end of input when reading filenames

The question marks are because the garbage string is masked using
tuklib_mask_nonprint(). After this commit, it works:

    xz: filelist.txt: Unexpected end of input when reading filenames

Co-authored-by: Lasse Collin <lasse.collin@tukaani.org>
Fixes: https://github.com/tukaani-project/xz/pull/223
src/xz/args.c

index bc7a5e8b02434b413907bf7cf1c0400a734ea1ac..8a9f98dcec26b7822fbda3f23c82a7b70b23ed4e 100644 (file)
@@ -641,15 +641,20 @@ parse_real(args_info *args, int argc, char **argv)
                                args->files_name = stdin_filename;
                                args->files_file = stdin;
                        } else {
-                               args->files_name = optarg;
-                               args->files_file = fopen(optarg,
+                               // If we are called from parse_environment(),
+                               // the memory pointed by optarg will be freed
+                               // after we return to parse_environment().
+                               // We need to duplicate the string.
+                               args->files_name = xstrdup(optarg);
+                               args->files_file = fopen(args->files_name,
                                                c == OPT_FILES ? "r" : "rb");
                                if (args->files_file == NULL)
                                        // TRANSLATORS: This is a translatable
                                        // string because French needs a space
                                        // before the colon ("%s : %s").
                                        message_fatal(_("%s: %s"),
-                                               tuklib_mask_nonprint(optarg),
+                                               tuklib_mask_nonprint(
+                                                       args->files_name),
                                                strerror(errno));
                        }