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 <[email protected]> --- 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
