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) {