Linux-EROFS Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jingbo Xu <jefflexu@linux.alibaba.com>
To: hsiangkao@linux.alibaba.com, linux-erofs@lists.ozlabs.org
Subject: [PATCH v6 10/11] erofs-utils: lib: set origin xattr on parent directory of whiteout
Date: Tue,  5 Sep 2023 18:02:26 +0800	[thread overview]
Message-ID: <20230905100227.1072-11-jefflexu@linux.alibaba.com> (raw)
In-Reply-To: <20230905100227.1072-1-jefflexu@linux.alibaba.com>

Whiteouts will be exposed in the overlayfs mount if the whiteouts are
from non-merged directory without origin xattr set on the directory.

To fix this, set origin xattr (with empty value) on parent directory of
whiteouts, marking the parent directory as copied-up to avoid exposing
whiteouts in the overlayfs mount.

To avoid setting multiple origin xattrs on the same directory when
there are multiple whiteouts under the directory, enhance
erofs_setxattr() so that it could skip duplicate xattrs.

Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
---
 include/erofs/xattr.h |  3 ++-
 lib/rebuild.c         |  6 ++++++
 lib/tar.c             |  9 ++++++++-
 lib/xattr.c           | 27 ++++++++++++++++++++++++---
 4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 9fa1ad1..62d0b8b 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -55,8 +55,9 @@ void erofs_xattr_prefixes_cleanup(struct erofs_sb_info *sbi);
 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);
+		   const void *value, size_t size, bool nodup);
 int erofs_set_opaque_xattr(struct erofs_inode *inode);
+int erofs_set_origin_xattr(struct erofs_inode *inode);
 int erofs_read_xattrs_from_disk(struct erofs_inode *inode);
 
 #ifdef __cplusplus
diff --git a/lib/rebuild.c b/lib/rebuild.c
index 477d68d..b254dea 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -200,6 +200,12 @@ static int erofs_rebuild_fill_inode(struct erofs_inode *inode)
 
 	switch (inode->i_mode & S_IFMT) {
 	case S_IFCHR:
+		if (erofs_inode_is_whiteout(inode)) {
+			ret = erofs_set_origin_xattr(inode->i_parent);
+			if (ret)
+				break;
+		}
+		/* fallthrough */
 	case S_IFBLK:
 	case S_IFIFO:
 	case S_IFSOCK:
diff --git a/lib/tar.c b/lib/tar.c
index 8cb392c..b75b723 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -206,7 +206,7 @@ int tarerofs_apply_xattrs(struct erofs_inode *inode, struct list_head *xattrs)
 		item->kv[item->namelen] = '\0';
 		erofs_dbg("Recording xattr(%s)=\"%s\" (of %u bytes) to file %s",
 			  item->kv, v, vsz, inode->i_srcpath);
-		ret = erofs_setxattr(inode, item->kv, v, vsz);
+		ret = erofs_setxattr(inode, item->kv, v, vsz, false);
 		if (ret == -ENODATA)
 			erofs_err("Failed to set xattr(%s)=%s to file %s",
 				  item->kv, v, inode->i_srcpath);
@@ -740,6 +740,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 parent directory as copied-up to avoid exposing
+		 * whiteouts in the overlayfs mount.
+		 */
+		ret = erofs_set_origin_xattr(inode->i_parent);
+		if (ret)
+			goto out;
 	} 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 cc6a393..feafe96 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
 
@@ -455,11 +461,12 @@ err:
 }
 
 int erofs_setxattr(struct erofs_inode *inode, char *key,
-		   const void *value, size_t size)
+		   const void *value, size_t size, bool nodup)
 {
 	char *kvbuf;
 	unsigned int len[2];
 	struct xattr_item *item;
+	struct inode_xattr_node *node;
 	u8 prefix;
 	u16 prefixlen;
 
@@ -481,12 +488,26 @@ int erofs_setxattr(struct erofs_inode *inode, char *key,
 	if (IS_ERR(item))
 		return PTR_ERR(item);
 
+	if (nodup) {
+		list_for_each_entry(node, &inode->i_xattrs, list) {
+			if (node->item == item) {
+				put_xattritem(item);
+				return 0;
+			}
+		}
+	}
+
 	return erofs_xattr_add(&inode->i_xattrs, item);
 }
 
 int erofs_set_opaque_xattr(struct erofs_inode *inode)
 {
-	return erofs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1);
+	return erofs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1, false);
+}
+
+int erofs_set_origin_xattr(struct erofs_inode *inode)
+{
+	return erofs_setxattr(inode, OVL_XATTR_ORIGIN, NULL, 0, true);
 }
 
 #ifdef WITH_ANDROID
@@ -599,7 +620,7 @@ int erofs_read_xattrs_from_disk(struct erofs_inode *inode)
 			DBG_BUGON(ret != size);
 		}
 
-		ret = erofs_setxattr(inode, key, value, size);
+		ret = erofs_setxattr(inode, key, value, size, false);
 		free(value);
 		if (ret)
 			break;
-- 
2.19.1.6.gb485710b


  parent reply	other threads:[~2023-09-05 10:03 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-05 10:02 [PATCH v6 00/11] erofs-utils: mkfs: introduce rebuild mode Jingbo Xu
2023-09-05 10:02 ` [PATCH v6 01/11] erofs-utils: lib: remove unneeded NULL checking for returned item Jingbo Xu
2023-09-05 10:02 ` [PATCH v6 02/11] erofs-utils: lib: add list_splice_tail() helper Jingbo Xu
2023-09-05 10:02 ` [PATCH v6 03/11] erofs-utils: lib: make erofs_get_unhashed_chunk() global Jingbo Xu
2023-09-05 10:02 ` [PATCH v6 04/11] erofs-utils: lib: add erofs_read_xattrs_from_disk() helper Jingbo Xu
2023-09-06  8:12   ` Gao Xiang
2023-09-05 10:02 ` [PATCH v6 05/11] erofs-utils: lib: add erofs_insert_ihash() helper Jingbo Xu
2023-09-06  8:50   ` Gao Xiang
2023-09-05 10:02 ` [PATCH v6 06/11] erofs-utils: lib: add erofs_rebuild_get_dentry() helper Jingbo Xu
2023-09-07 10:02   ` Gao Xiang
2023-09-05 10:02 ` [PATCH v6 07/11] erofs-utils: lib: add erofs_rebuild_load_tree() helper Jingbo Xu
2023-09-05 10:02 ` [PATCH v6 08/11] erofs-utils: mkfs: introduce rebuild mode Jingbo Xu
2023-09-05 10:02 ` [PATCH v6 09/11] erofs-utils: lib: add erofs_inode_is_whiteout() helper Jingbo Xu
2023-09-05 10:02 ` Jingbo Xu [this message]
2023-09-05 10:02 ` [PATCH v6 11/11] erofs-utils: mkfs: add --overlay-strip option for tarfs and rebuild mode Jingbo Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230905100227.1072-11-jefflexu@linux.alibaba.com \
    --to=jefflexu@linux.alibaba.com \
    --cc=hsiangkao@linux.alibaba.com \
    --cc=linux-erofs@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox