On Fri, 8 Jul 2022 16:04:47 +0000
Guilherme Janczak <guilherme.janc...@yandex.com> wrote:

> gzip violates wpath if you tell it to extract stdin and restore the
> original filename.

More than a year ago, Guilherme Janczak reported that OpenBSD's
"gzip -dN <rc.gz" crashes by pledge and crashes, and sent a diff to
skip the 2nd pledge call.  I put the diff in one of my src trees and
forgot about it until today.

I observe that "gzip -dN <rc.gz" doesn't crash with the pledge-skip
diff, but "zcat -N rc.gz" still crashes.  (The diff works with an
implicit -c from reading stdin, but not with an explicit "gzip -c" or
"zcat".)

In other systems (I tried GNU gzip 1.12 and NetBSD gzip 20170803),
-c overrides -N, so "gzip -dN <rc.gz" and "zcat -N rc.gz" both ignore
the -N and cat to stdout.  In OpenBSD, -N overrides -c, so these
commands try to write "rc" (the stored filename), but crash like,
'gzip[11955]: pledge "wpath", syscall 5'.

The pledge-skip diff is in
https://marc.info/?l=openbsd-tech&m=165729624913806&w=2

I made a new diff for -c overrides -N, is this better?
--gkoehler

Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/compress/main.c,v
retrieving revision 1.105
diff -u -p -r1.105 main.c
--- main.c      11 Aug 2023 04:45:05 -0000      1.105
+++ main.c      8 Oct 2023 04:00:57 -0000
@@ -699,7 +699,8 @@ dodecompress(const char *in, char *out, 
                close (ifd);
                return (FAILURE);
        }
-       if (storename && oldname[0] != '\0') {
+       /* Do -N only if not -c. */
+       if (storename && !cat && oldname[0] != '\0') {
                const char *oldbase = basename(oldname);
                char *cp = strrchr(out, '/');
                if (cp != NULL) {
@@ -707,7 +708,6 @@ dodecompress(const char *in, char *out, 
                        strlcat(out, oldbase, PATH_MAX);
                } else
                        strlcpy(out, oldbase, PATH_MAX);
-               cat = 0;                        /* XXX should -c override? */
        }
 
        if (testmode) {

Reply via email to