[PATCH 1/3] erofs-utils: lib: tar: ignore useless fields of PAX extended headers
Gao Xiang
hsiangkao at linux.alibaba.com
Thu Dec 26 15:58:06 AEDT 2024
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 <hsiangkao at 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)
More information about the Linux-erofs
mailing list