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