Subject: Re: bug#72283: Path traversal in gzip's -S option

From: Paul Eggert <[email-masked]>
Date: Wed, 24 Jul 2024 19:16:40 -0700

On 2024-07-24 14:59, Alex Stumpf wrote:
> It's up to you whether you consider this a fix-worthy bug,

Thanks for reporting that. It's bad behavior, and worth a fix. I 
installed the attached and am closing the bug report.

From 75f9f29ec64eec61025bd05f65beeece62d3cf84 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Wed, 24 Jul 2024 19:13:51 -0700
Subject: [PATCH] gzip: reject suffixes containing '/'

Problem reported by Alex Stumpf <https://bugs.gnu.org/72283>.
* gzip.c (main): Diagnose suffixes containing '/', and exit.
---
 NEWS          | 2 ++
 doc/gzip.texi | 8 +++++---
 gzip.1        | 4 ++--
 gzip.c        | 7 ++++++-
 4 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 0a95e7f..33c5b0e 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@ GNU gzip NEWS                                    -*- outline -*-
   'gzip -l' no longer misreports lengths of multimember inputs.
   [bug introduced in gzip-1.12]
 
+  'gzip -S' now rejects suffixes containing '/'.
+  [bug present since the beginning]
 
 * Noteworthy changes in release 1.13 (2023-08-19) [stable]
 
diff --git a/doc/gzip.texi b/doc/gzip.texi
index 180faf5..a9b67d6 100644
--- a/doc/gzip.texi
+++ b/doc/gzip.texi
@@ -364,10 +364,12 @@ the compressed output is usually about one percent larger.
 
 @item --suffix @var{suf}
 @itemx -S @var{suf}
-Use suffix @var{suf} instead of @samp{.gz}.  Any suffix can be
-given, but suffixes other than @samp{.z} and @samp{.gz} should be
+
+Use suffix @var{suf} instead of @samp{.gz}.
+Although any suffix can be given so long as it does not contain @samp{/},
+suffixes other than @samp{.z} and @samp{.gz} should be
 avoided to avoid confusion when files are transferred to other systems.
-A null suffix forces gunzip to try decompression on all given files
+An empty suffix forces gunzip to try decompression on all given files
 regardless of suffix, as in:
 
 @example
diff --git a/gzip.1 b/gzip.1
index b9772e4..d87db1d 100644
--- a/gzip.1
+++ b/gzip.1
@@ -316,8 +316,8 @@ will descend into the directory and compress all the files it finds there
 .TP
 .B \-S .suf   \-\-suffix .suf
 When compressing, use suffix .suf instead of .gz.
-Any non-empty suffix can be given, but suffixes
-other than .z and .gz should be avoided to avoid confusion when files
+Although any non-empty suffix can be given so long as it does not contain "/",
+suffixes other than .z and .gz should be avoided to avoid confusion when files
 are transferred to other systems.
 
 When decompressing, add .suf to the beginning of the list of
diff --git a/gzip.c b/gzip.c
index 7ff4826..866028a 100644
--- a/gzip.c
+++ b/gzip.c
@@ -564,7 +564,12 @@ int main (int argc, char **argv)
 #ifdef NO_MULTIPLE_DOTS
             if (*optarg == '.') optarg++;
 #endif
-            z_len = strlen(optarg);
+            for (z_len = 0; optarg[z_len]; z_len++)
+              if (optarg[z_len] == '/')
+                {
+                  fprintf (stderr, "%s: suffix contains '/'\n", program_name);
+                  do_exit (ERROR);
+                }
             z_suffix = optarg;
             break;
         case SYNCHRONOUS_OPTION:
-- 
2.43.0