From: jca Date: Tue, 16 Apr 2024 18:52:43 +0000 (+0000) Subject: Correctly detect 'pax' format archives in append mode X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ce1e26fb725c95543619ef3f3a658bc8890a7572;p=openbsd Correctly detect 'pax' format archives in append mode We expect that existing pax archives start with a global or extended header. If they don't, append operations will be done using ustar format. Fixes append mode on pax archives where pax(1) would bail out when appending to pax archives, falsely detecting a mismatch. Reading was unaffected. Reported by caspar@, ok caspar@ millert@ --- diff --git a/bin/pax/extern.h b/bin/pax/extern.h index 9730b8db82b..6e7031ab18d 100644 --- a/bin/pax/extern.h +++ b/bin/pax/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.62 2023/12/09 23:00:11 jca Exp $ */ +/* $OpenBSD: extern.h,v 1.63 2024/04/16 18:52:43 jca Exp $ */ /* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */ /*- @@ -284,6 +284,7 @@ int tar_wr(ARCHD *); int ustar_id(char *, int); int ustar_rd(ARCHD *, char *); int ustar_wr(ARCHD *); +int pax_id(char *, int); int pax_wr(ARCHD *); /* diff --git a/bin/pax/options.c b/bin/pax/options.c index d8b1c09951f..2259b77bcf7 100644 --- a/bin/pax/options.c +++ b/bin/pax/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.109 2024/04/15 22:07:08 caspar Exp $ */ +/* $OpenBSD: options.c,v 1.110 2024/04/16 18:52:43 jca Exp $ */ /* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */ /*- @@ -228,7 +228,7 @@ FSUB fsub[] = { /* 9: gzip, to detect failure to use -z */ {NULL, 0, 4, 0, 0, 0, 0, gzip_id}, /* 10: POSIX PAX */ - {"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, no_op, + {"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, pax_id, no_op, ustar_rd, tar_endrd, no_op, pax_wr, tar_endwr, tar_trail, tar_opt}, #endif @@ -249,7 +249,7 @@ FSUB fsub[] = { * of archive we are dealing with. This helps to properly id archive formats * some formats may be subsets of others.... */ -int ford[] = {5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1}; +int ford[] = {10, 5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1}; /* * Do we have -C anywhere and what is it? diff --git a/bin/pax/tar.c b/bin/pax/tar.c index cd64ec7bad1..2e84004ea7b 100644 --- a/bin/pax/tar.c +++ b/bin/pax/tar.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tar.c,v 1.79 2024/01/20 17:34:50 jca Exp $ */ +/* $OpenBSD: tar.c,v 1.80 2024/04/16 18:52:43 jca Exp $ */ /* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */ /*- @@ -1391,6 +1391,46 @@ ustar_wr(ARCHD *arcn) return wr_ustar_or_pax(arcn, 1); } +/* + * pax_id() + * determine if a block given to us is a valid pax header. + * Return: + * 0 if a pax header, -1 otherwise + */ +#ifndef SMALL +int +pax_id(char *blk, int size) +{ + HD_USTAR *hd; + + if (size < BLKMULT) + return(-1); + hd = (HD_USTAR *)blk; + + /* + * check for block of zero's first, a simple and fast test then check + * ustar magic cookie. We should use TMAGLEN, but some USTAR archive + * programs are fouled up and create archives missing the \0. Last we + * check the checksum and the type flag. If ok we have to assume it is + * a valid pax header. + */ + if (hd->prefix[0] == '\0' && hd->name[0] == '\0') + return(-1); + if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0) + return(-1); + if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT)) + return(-1); + /* + * It is valid for a pax formatted archive not to start with + * a global header nor with an extended header. In that case + * we'll fall back to ustar in append mode. + */ + if (hd->typeflag == XHDRTYPE || hd->typeflag == GHDRTYPE) + return(0); + return (-1); +} +#endif + /* * pax_wr() * Write out a pax format archive.