Since some unknown writer just leaves zero-filled mtime, e.g. registry.k8s.io/pause:3.6 --platform windows
Layer sha256: bc8517709e9cfff223cb034ff5be8fcbfa5409de286cdac9ae1b8878ebea6b84 Fixes: 95d315fd7958 ("erofs-utils: introduce tarerofs") Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com> --- lib/tar.c | 78 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/lib/tar.c b/lib/tar.c index 0dd990e..12bf595 100644 --- a/lib/tar.c +++ b/lib/tar.c @@ -659,6 +659,7 @@ int tarerofs_parse_tar(struct erofs_inode *root, struct erofs_tarfile *tar) struct erofs_sb_info *sbi = root->sbi; bool whout, opq, e = false; struct stat st; + mode_t mode; erofs_off_t tar_offset, dataoff; struct tar_header *th; @@ -751,26 +752,6 @@ out_eot: goto out; } - st.st_mode = tarerofs_otoi(th->mode, sizeof(th->mode)); - if (errno) - goto invalid_tar; - - if (eh.use_uid) { - st.st_uid = eh.st.st_uid; - } else { - st.st_uid = tarerofs_parsenum(th->uid, sizeof(th->uid)); - if (errno) - goto invalid_tar; - } - - if (eh.use_gid) { - st.st_gid = eh.st.st_gid; - } else { - st.st_gid = tarerofs_parsenum(th->gid, sizeof(th->gid)); - if (errno) - goto invalid_tar; - } - if (eh.use_size) { st.st_size = eh.st.st_size; } else { @@ -779,16 +760,6 @@ out_eot: goto invalid_tar; } - if (eh.use_mtime) { - st.st_mtime = eh.st.st_mtime; - ST_MTIM_NSEC_SET(&st, ST_MTIM_NSEC(&eh.st)); - } else { - st.st_mtime = tarerofs_parsenum(th->mtime, sizeof(th->mtime)); - if (errno) - goto invalid_tar; - ST_MTIM_NSEC_SET(&st, 0); - } - if (th->typeflag <= '7' && !eh.path) { eh.path = path; j = 0; @@ -810,28 +781,29 @@ out_eot: dataoff = tar->offset; tar->offset += st.st_size; + st.st_mode = 0; switch(th->typeflag) { case '0': case '7': case '1': - st.st_mode |= S_IFREG; + 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; + st.st_mode = S_IFLNK; break; case '3': - st.st_mode |= S_IFCHR; + st.st_mode = S_IFCHR; break; case '4': - st.st_mode |= S_IFBLK; + st.st_mode = S_IFBLK; break; case '5': - st.st_mode |= S_IFDIR; + st.st_mode = S_IFDIR; break; case '6': - st.st_mode |= S_IFIFO; + st.st_mode = S_IFIFO; break; case 'g': ret = tarerofs_parse_pax_header(&tar->ios, &tar->global, @@ -876,6 +848,40 @@ out_eot: goto out; } + mode = tarerofs_otoi(th->mode, sizeof(th->mode)); + if (errno) + goto invalid_tar; + if (__erofs_unlikely(mode & S_IFMT) && + (mode & S_IFMT) != (st.st_mode & S_IFMT)) + erofs_warn("invalid ustar mode %05o @ %llu", mode, tar_offset); + st.st_mode |= mode & ~S_IFMT; + + if (eh.use_uid) { + st.st_uid = eh.st.st_uid; + } else { + st.st_uid = tarerofs_parsenum(th->uid, sizeof(th->uid)); + if (errno) + goto invalid_tar; + } + + if (eh.use_gid) { + st.st_gid = eh.st.st_gid; + } else { + st.st_gid = tarerofs_parsenum(th->gid, sizeof(th->gid)); + if (errno) + goto invalid_tar; + } + + if (eh.use_mtime) { + st.st_mtime = eh.st.st_mtime; + ST_MTIM_NSEC_SET(&st, ST_MTIM_NSEC(&eh.st)); + } else { + st.st_mtime = tarerofs_parsenum(th->mtime, sizeof(th->mtime)); + if (errno) + goto invalid_tar; + ST_MTIM_NSEC_SET(&st, 0); + } + st.st_rdev = 0; if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) { int major, minor; -- 2.39.3 (Apple Git-146)