[PATCH] erofs-utils: tar: fix self-hardlink handling

Gao Xiang hsiangkao at linux.alibaba.com
Fri Jan 9 15:14:18 AEDT 2026


The following tar can contain two header blocks, and the second
header block describes the same file `foo` as a hardlink:

 $ touch foo
 $ tar cf foo.tar foo foo
 $ mkfs.erofs --tar=f foo.erofs foo.tar
 mkfs.erofs 1.8.10
 Segmentation fault (core dumped)

Closes: https://github.com/erofs/erofs-utils/issues/32
Fixes: 95d315fd7958 ("erofs-utils: introduce tarerofs")
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 lib/tar.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/lib/tar.c b/lib/tar.c
index 8aa90c7dc0d4..d5095169f9ba 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -995,12 +995,6 @@ out_eot:
 			goto out;
 		}
 
-		if (d->type != EROFS_FT_UNKNOWN) {
-			tarerofs_remove_inode(d->inode);
-			erofs_iput(d->inode);
-		}
-		d->inode = NULL;
-
 		d2 = erofs_rebuild_get_dentry(root, eh.link, tar->aufs,
 					      &dumb, &dumb, false);
 		if (IS_ERR(d2)) {
@@ -1011,14 +1005,23 @@ out_eot:
 			ret = -ENOENT;
 			goto out;
 		}
+		if (d == d2) {
+			ret = 0;
+			goto out;
+		}
 		if (S_ISDIR(d2->inode->i_mode)) {
 			ret = -EISDIR;
 			goto out;
 		}
+
 		inode = erofs_igrab(d2->inode);
+		++inode->i_nlink;
+		if (d->type != EROFS_FT_UNKNOWN) {
+			tarerofs_remove_inode(d->inode);
+			erofs_iput(d->inode);
+		}
 		d->inode = inode;
 		d->type = d2->type;
-		++inode->i_nlink;
 		ret = 0;
 		goto out;
 	} else if (d->type != EROFS_FT_UNKNOWN) {
-- 
2.43.5



More information about the Linux-erofs mailing list