PROBLEM When creating a tarball from files on _some_ cd9660 filesystems (e.g. created by xorrisofs(1)), all symbolic links will be stripped of their link target: Expected: lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-1 -> /some/fqfn lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-2 -> ../relpath lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-3 -> symlink-1 Found: lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-1 -> lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-2 -> lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-3 -> ANALYSIS Even if tar(1) drops the symlink target when reading from a cd9660 filesystem, it does extract them correctly from the device node or ISO image themselves. Note that this error does not occur when the ISO has been created with makefs(8): makefs -t cd9660 -o rockridge -o label=TARPIT /tmp/tarpit.iso /tmp/tarpit It does, however, occur when the image is created by xorrisofs(1): xorrisofs -rock -volid TARPIT -o /tmp/tarpit.iso /tmp/tarpit HOW TO REPRODUCE # We need xorrisofs(1) pkg install -y xorriso # Create ISO image with symlinks mkdir /tmp/tarpit ln -s /some/fqfn /tmp/tarpit/symlink-1 ln -s ../relpath /tmp/tarpit/symlink-2 ln -s symlink-1 /tmp/tarpit/symlink-3 xorrisofs -rock -volid TARPIT -o /tmp/tarpit.iso /tmp/tarpit # Mount ISO image dev=$(mdconfig /tmp/tarpit.iso) mount -t cd9660 /dev/iso9660/TARPIT # Validate filesystem contents ls -l /mnt # total 0 # lrwxr-xr-x 1 root wheel 0 27 Okt. 05:41 symlink-1 -> /some/fqfn # lrwxr-xr-x 1 root wheel 0 27 Okt. 05:41 symlink-2 -> ../relpath # lrwxr-xr-x 1 root wheel 0 27 Okt. 05:41 symlink-3 -> symlink-1 # Produces broken symlinks with the target component stripped away tar cf - -C /mnt . | tar tvf - # drwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./ # lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-1 -> # lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-2 -> # lrwxr-xr-x 0 root wheel 0 27 Okt. 05:41 ./symlink-3 -> # Produces intact symlinks (directly from ISO device or image) tar tvf /dev/iso9660/TARPIT tar tvf /tmp/tarpit.iso # drwxr-xr-x 2 0 0 2048 27 Okt. 05:41 . # lrwxr-xr-x 1 0 0 0 27 Okt. 05:41 symlink-1 -> /some/fqfn # lrwxr-xr-x 1 0 0 0 27 Okt. 05:41 symlink-2 -> ../relpath # lrwxr-xr-x 1 0 0 0 27 Okt. 05:41 symlink-3 -> symlink-1 # Cleanup umount /mnt mdconfig -d -u "${dev#md}"
Have you tested upstream: https://github.com/libarchive/libarchive/releases/tag/v3.8.2?
(In reply to Michael Osipov from comment #1) I have now - it has the exact same behavior.
(In reply to Markus Stoff from comment #2) Then I would recommend to report it upstream first.
Can you please attach the ISO?
This is a FreeBSD kernel bug, not a libarchive bug: $ stat -f%z,%Y /tmp/tarpit/symlink-1 /mnt/symlink-1 10,/some/fqfn 0,/some/fqfn POSIX states that fstatat() / lstat() on a symbolic link shall set st_size to the length of the target of the symbolic link, including the terminating null character. There is code in cd9660_getattr() in sys/fs/cd9660/cd9660_vnops.c to handle that, but it clearly does not work. Most programs (stat, readlink, ls...) don't notice because they use a fixed-size buffer for readlink(), but libarchive trusts the result of fstatat() and ends up allocating a zero-length buffer, and therefore getting a zero-length answer.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=978aaa72f3196f5489630052762cac5a7863e774 commit 978aaa72f3196f5489630052762cac5a7863e774 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2025-11-10 13:58:11 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2025-11-10 13:58:20 +0000 cd9660: Unbreak symbolic links Since the introduction of permission masks, cd9660_getattr() returns a size of zero for all symbolic links, because the code to retrieve the length of the link target (as required by POSIX) is dead, since we strip away the type bits before we try to use them to identify the file as a link. Address this by checking the vnode type instead. PR: 290556 MFC after: 3 days Fixes: 82f2275b73e5 ("cd9660: Add support for mask,dirmask,uid,gid options") Reviewed by: olce Differential Revision: https://reviews.freebsd.org/D53598 sys/fs/cd9660/cd9660_vnops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
A commit in branch stable/15 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=1b51ad67cd0a85aea8351f86c6a724037eadc1fd commit 1b51ad67cd0a85aea8351f86c6a724037eadc1fd Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2025-11-10 13:58:11 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2025-11-14 14:43:26 +0000 cd9660: Unbreak symbolic links Since the introduction of permission masks, cd9660_getattr() returns a size of zero for all symbolic links, because the code to retrieve the length of the link target (as required by POSIX) is dead, since we strip away the type bits before we try to use them to identify the file as a link. Address this by checking the vnode type instead. PR: 290556 MFC after: 3 days Fixes: 82f2275b73e5 ("cd9660: Add support for mask,dirmask,uid,gid options") Reviewed by: olce Differential Revision: https://reviews.freebsd.org/D53598 (cherry picked from commit 978aaa72f3196f5489630052762cac5a7863e774) sys/fs/cd9660/cd9660_vnops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=0f910af019691bb829ebc8aef868e1d97c379462 commit 0f910af019691bb829ebc8aef868e1d97c379462 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2025-11-10 13:58:11 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2025-11-14 14:43:38 +0000 cd9660: Unbreak symbolic links Since the introduction of permission masks, cd9660_getattr() returns a size of zero for all symbolic links, because the code to retrieve the length of the link target (as required by POSIX) is dead, since we strip away the type bits before we try to use them to identify the file as a link. Address this by checking the vnode type instead. PR: 290556 MFC after: 3 days Fixes: 82f2275b73e5 ("cd9660: Add support for mask,dirmask,uid,gid options") Reviewed by: olce Differential Revision: https://reviews.freebsd.org/D53598 (cherry picked from commit 978aaa72f3196f5489630052762cac5a7863e774) sys/fs/cd9660/cd9660_vnops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
A commit in branch stable/13 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=3e8d5f36082414373462743d775db005daf07339 commit 3e8d5f36082414373462743d775db005daf07339 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2025-11-10 13:58:11 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2025-11-14 14:43:53 +0000 cd9660: Unbreak symbolic links Since the introduction of permission masks, cd9660_getattr() returns a size of zero for all symbolic links, because the code to retrieve the length of the link target (as required by POSIX) is dead, since we strip away the type bits before we try to use them to identify the file as a link. Address this by checking the vnode type instead. PR: 290556 MFC after: 3 days Fixes: 82f2275b73e5 ("cd9660: Add support for mask,dirmask,uid,gid options") Reviewed by: olce Differential Revision: https://reviews.freebsd.org/D53598 (cherry picked from commit 978aaa72f3196f5489630052762cac5a7863e774) sys/fs/cd9660/cd9660_vnops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)