On Sun, Oct 08, 2023 at 12:18:34AM -0400, George Koehler wrote:
> 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'.

FWIW, archivers/pigz aka. pigz(1) pledges like base gzip(1) but works,
i.e. 'pigz -Nd < rc.gz' drops to "stdio rpath" and succeeds, so it must
have ignored -N.

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

I think I'd make sense to also add the original diff's regress test to
cover this missing case.

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

That diff reads OK to me and regress stays happy.

> 
> 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. */

        /* -c overrides -N. */
would read a tad better, imho.

> +     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