erofs-utils: mkfs: Fix input offset counting in headerball mode
authorMike Baynton <mike@mbaynton.com>
Mon, 11 Nov 2024 16:48:19 +0000 (10:48 -0600)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Tue, 12 Nov 2024 02:07:42 +0000 (10:07 +0800)
When using --tar=headerball, most files included in the headerball are
not included in the EROFS image. mkfs.erofs typically exits prematurely,
having processed non-USTAR blocks as USTAR and believing they are
end-of-archive markers. (Other failure modes are probably also possible
if the input stream doesn't look like end-of-archive markers at the
locations that are being read.)

This is because we lost correct count of bytes that are read from the
input stream when in headerball (or ddtaridx) modes. We were assuming that
in these modes no data would be read following the ustar block, but in
case of things like PAX headers, lots more data may be read without
incrementing tar->offset.

This corrects by always incrementing the offset counter, and then
decrementing it again in the one case where headerballs differ -
regular file data blocks are not present.

Signed-off-by: Mike Baynton <mike@mbaynton.com>
Link: https://lore.kernel.org/r/20241111164819.560567-1-mike@mbaynton.com
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
lib/tar.c

index b32abd43d633b4ef67862f7f7e7f17cf584139a2..990c6cb1b3729e2aaf02db11c768cfc8fe2f9ed8 100644 (file)
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -808,13 +808,14 @@ out_eot:
        }
 
        dataoff = tar->offset;
-       if (!(tar->headeronly_mode || tar->ddtaridx_mode))
-               tar->offset += st.st_size;
+       tar->offset += st.st_size;
        switch(th->typeflag) {
        case '0':
        case '7':
        case '1':
                st.st_mode |= S_IFREG;
+               if (tar->headeronly_mode || tar->ddtaridx_mode)
+                       tar->offset -= st.st_size;
                break;
        case '2':
                st.st_mode |= S_IFLNK;