tarfs: Ignore global extended headers.

Previously, we would error out if we encountered a global extended
header, because we don't know what it means.  This doesn't really
matter though, and traditionally, tar implementations have either
ignored them or treated them as plain files, so just ignore them.
This allows tarfs to mount tar files created by `git archive`.

MFC after:	3 days
Sponsored by:	Juniper Networks, Inc.
Sponsored by:	Klara, Inc.
Reviewed by:	kevans
Differential Revision:	https://reviews.freebsd.org/D44600
This commit is contained in:
Dag-Erling Smørgrav 2024-04-03 11:55:06 +02:00
parent b1fd95c9e2
commit 584e1c355a
2 changed files with 31 additions and 6 deletions

View file

@ -553,13 +553,14 @@ again:
TARFS_DPF(ALLOC, "%s: [%c] %zu @%jd %o %d:%d\n", __func__,
hdrp->typeflag[0], sz, (intmax_t)mtime, mode, uid, gid);
/* extended header? */
/* global extended header? */
if (hdrp->typeflag[0] == TAR_TYPE_GLOBAL_EXTHDR) {
printf("%s: unsupported global extended header at %zu\n",
__func__, (size_t)(TARFS_BLOCKSIZE * (blknum - 1)));
error = EFTYPE;
goto bad;
TARFS_DPF(ALLOC, "%s: %zu-byte global extended header at %zu\n",
__func__, sz, TARFS_BLOCKSIZE * (blknum - 1));
goto skip;
}
/* extended header? */
if (hdrp->typeflag[0] == TAR_TYPE_EXTHDR) {
if (exthdr != NULL) {
TARFS_DPF(IO, "%s: multiple extended headers at %zu\n",
@ -568,7 +569,7 @@ again:
goto bad;
}
/* read the contents of the exthdr */
TARFS_DPF(ALLOC, "%s: %zu-byte extended header at %zd\n",
TARFS_DPF(ALLOC, "%s: %zu-byte extended header at %zu\n",
__func__, sz, TARFS_BLOCKSIZE * (blknum - 1));
exthdr = malloc(sz, M_TEMP, M_WAITOK);
res = tarfs_io_read_buf(tmp, false, exthdr,

View file

@ -357,6 +357,29 @@ tarfs_long_paths_cleanup() {
tarfs_cleanup
}
atf_test_case tarfs_git_archive cleanup
tarfs_git_archive_head() {
atf_set "descr" "Verify that tarfs supports archives created by git"
atf_set "require.user" "root"
atf_set "require.progs" "git"
}
tarfs_git_archive_body() {
tarfs_setup
mkdir foo
echo "Hello, world!" >foo/bar
git -C foo init --initial-branch=tarfs
git -C foo config user.name "File System"
git -C foo config user.email fs@freebsd.org
git -C foo add bar
git -C foo commit -m bar
git -C foo archive --output=../tarfs_git_archive.tar HEAD
atf_check mount -rt tarfs tarfs_git_archive.tar "${mnt}"
atf_check -o file:foo/bar cat "${mnt}"/bar
}
tarfs_git_archive_cleanup() {
tarfs_cleanup
}
atf_init_test_cases() {
atf_add_test_case tarfs_basic
atf_add_test_case tarfs_basic_gnu
@ -374,4 +397,5 @@ atf_init_test_cases() {
atf_add_test_case tarfs_checksum
atf_add_test_case tarfs_long_names
atf_add_test_case tarfs_long_paths
atf_add_test_case tarfs_git_archive
}