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
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;
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
}
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;
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))
#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
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)
{