aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJingbo Xu <jefflexu@linux.alibaba.com>2023-09-10 00:32:31 +0800
committerGao Xiang <hsiangkao@linux.alibaba.com>2023-09-11 11:22:05 +0800
commit1d9a3368e2548970518eff6e5e83d37590d18fc1 (patch)
treece7230a12b10f7d716001d43a12a0219720452dc
parent93287dd55801d5d119ea88c764621a23e163c091 (diff)
downloaderofs-utils-1d9a3368e2548970518eff6e5e83d37590d18fc1.tar.gz
erofs-utils: lib: set OVL_XATTR_ORIGIN for directories with whiteouts
Whiteouts are exposed in the overlayfs mount if these are from some non-merged directory without OVL_XATTR_ORIGIN set on the directory. To fix this, tag OVL_XATTR_ORIGIN (with empty value) on the parent directory of whiteouts. Fixes: 95d315fd7958 ("erofs-utils: introduce tarerofs") Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20230909163240.42057-5-hsiangkao@linux.alibaba.com
-rw-r--r--include/erofs/internal.h2
-rw-r--r--include/erofs/xattr.h1
-rw-r--r--lib/inode.c3
-rw-r--r--lib/tar.c7
-rw-r--r--lib/xattr.c11
5 files changed, 24 insertions, 0 deletions
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index ac82336..ba4d6c6 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -192,6 +192,8 @@ struct erofs_inode {
bool compressed_idata;
bool lazy_tailblock;
bool with_tmpfile;
+ /* OVL: non-merge dir that may contain whiteout entries */
+ bool whiteouts;
unsigned int xattr_isize;
unsigned int extent_isize;
diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 59515d7..2ecb18e 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -57,6 +57,7 @@ int erofs_xattr_prefixes_init(struct erofs_sb_info *sbi);
int erofs_setxattr(struct erofs_inode *inode, char *key,
const void *value, size_t size);
int erofs_set_opaque_xattr(struct erofs_inode *inode);
+int erofs_set_origin_xattr(struct erofs_inode *inode);
#ifdef __cplusplus
}
diff --git a/lib/inode.c b/lib/inode.c
index a3a643f..c976be3 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1337,6 +1337,9 @@ int tarerofs_dump_tree(struct erofs_inode *dir)
dir->inode_isize = sizeof(struct erofs_inode_compact);
}
+ if (dir->whiteouts)
+ erofs_set_origin_xattr(dir);
+
ret = erofs_prepare_xattr_ibody(dir);
if (ret < 0)
return ret;
diff --git a/lib/tar.c b/lib/tar.c
index c5dbef0..b58bfd5 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -843,6 +843,13 @@ new_inode:
inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFCHR;
inode->u.i_rdev = EROFS_WHITEOUT_DEV;
d->type = EROFS_FT_CHRDEV;
+
+ /*
+ * Mark the parent directory as copied-up to avoid exposing
+ * whiteouts if mounted. See kernel commit b79e05aaa166
+ * ("ovl: no direct iteration for dir with origin xattr")
+ */
+ inode->i_parent->whiteouts = true;
} else {
inode->i_mode = st.st_mode;
if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
diff --git a/lib/xattr.c b/lib/xattr.c
index bd03831..671ae05 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -57,12 +57,18 @@
#ifndef OVL_XATTR_OPAQUE_POSTFIX
#define OVL_XATTR_OPAQUE_POSTFIX "opaque"
#endif
+#ifndef OVL_XATTR_ORIGIN_POSTFIX
+#define OVL_XATTR_ORIGIN_POSTFIX "origin"
+#endif
#ifndef OVL_XATTR_TRUSTED_PREFIX
#define OVL_XATTR_TRUSTED_PREFIX XATTR_TRUSTED_PREFIX OVL_XATTR_NAMESPACE
#endif
#ifndef OVL_XATTR_OPAQUE
#define OVL_XATTR_OPAQUE OVL_XATTR_TRUSTED_PREFIX OVL_XATTR_OPAQUE_POSTFIX
#endif
+#ifndef OVL_XATTR_ORIGIN
+#define OVL_XATTR_ORIGIN OVL_XATTR_TRUSTED_PREFIX OVL_XATTR_ORIGIN_POSTFIX
+#endif
#define EA_HASHTABLE_BITS 16
@@ -490,6 +496,11 @@ int erofs_set_opaque_xattr(struct erofs_inode *inode)
return erofs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1);
}
+int erofs_set_origin_xattr(struct erofs_inode *inode)
+{
+ return erofs_setxattr(inode, OVL_XATTR_ORIGIN, NULL, 0);
+}
+
#ifdef WITH_ANDROID
static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
{