On Tue, Apr 16, 2024 at 06:23:18PM +0200, Caspar Schutijser wrote:
> Hi,
>
> While I was testing jca@'s diff to make the pax format the
> default for tar(1), I ran into the following bug in the code
> that reads extended headers. (To be clear: this has nothing to
> do with the code that *writes* extended headers and/or jca@'s
> diff.)
>
> If the file name of the file in the archive is too long, pax and
> tar will say:
> pax: Extended header record length 513 is out of range
>
> The problem appears if one extended header record exceeds 512 bytes.
> Below is a test case. If the file name is 502 bytes long, the length
> of the extended header record is 512 bytes and all is fine. If the
> file name is 503 bytes, one byte longer, the extended header record
> will be 513 bytes and the error message mentioned above appears.
>
> If we want this to work, rd_xheader() probably needs to be fixed.
Thanks for the tests and reproducer.
Here's a cheap trick. Testing with path=... longer than PATH_MAX
results in broken behavior. If you want to test this with symbolic
links and long linkpath=... please use the latest tar.c.
There's probably a better way to solve this but the amount of pointer
arithmetic in this function doesn't make it attractive. What do you
folks think?
Index: tar.c
===================================================================
--- tar.c.orig 2024-04-16 22:29:44.269086676 +0100
+++ tar.c 2024-04-16 22:35:25.849167081 +0100
@@ -1588,7 +1588,13 @@
static int
rd_xheader(ARCHD *arcn, int global, off_t size)
{
- char buf[MAXXHDRSZ];
+ /*
+ * The pax format supposedly supports arbitrarily sized extended
+ * record headers. However the largest useful extended header
+ * for this implementation seems to be one that fits a PATH_MAX
+ * (1024 bytes) path/linkpath.
+ */
+ char buf[sizeof("10xx linkpath=") - 1 + PATH_MAX + sizeof("\n")];
long len;
char *delim, *keyword;
char *nextp, *p, *end;
--
jca