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

Reply via email to