tarfs: Support paths that spill into exthdrs.

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

View file

@ -614,7 +614,10 @@ tarfs_alloc_one(struct tarfs_mount *tmp, off_t *blknump)
value = sep + 1;
TARFS_DPF(ALLOC, "%s: exthdr %s=%s\n", __func__,
key, value);
if (strcmp(key, "linkpath") == 0) {
if (strcmp(key, "path") == 0) {
name = value;
namelen = eol - value;
} else if (strcmp(key, "linkpath") == 0) {
link = value;
linklen = eol - value;
} else if (strcmp(key, "GNU.sparse.major") == 0) {
@ -905,6 +908,8 @@ tarfs_alloc_mount(struct mount *mp, struct vnode *vp,
blknum = 0;
do {
if ((error = tarfs_alloc_one(tmp, &blknum)) != 0) {
printf("unsupported or corrupt tar file at %zu\n",
TARFS_BLOCKSIZE * blknum);
goto bad;
}
} while (blknum != TAR_EOF);

View file

@ -309,6 +309,54 @@ tarfs_checksum_cleanup() {
tarfs_cleanup
}
atf_test_case tarfs_long_names cleanup
tarfs_long_names_head() {
atf_set "descr" "Verify that tarfs supports long file names"
atf_set "require.user" "root"
}
tarfs_long_names_body() {
tarfs_setup
local a b c d e
a="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
b="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
c="cccccccccccccccccccccccccccccccccccccccc"
d="dddddddddddddddddddddddddddddddddddddddd"
e="eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
mkdir -p "${a}"
touch "${a}/${b}_${c}_${d}_${e}_foo"
ln "${a}/${b}_${c}_${d}_${e}_foo" "${a}/${b}_${c}_${d}_${e}_bar"
ln -s "${b}_${c}_${d}_${e}_bar" "${a}/${b}_${c}_${d}_${e}_baz"
tar -cf tarfs_long_names.tar "${a}"
atf_check mount -rt tarfs tarfs_long_names.tar "${mnt}"
}
tarfs_long_names_cleanup() {
tarfs_cleanup
}
atf_test_case tarfs_long_paths cleanup
tarfs_long_paths_head() {
atf_set "descr" "Verify that tarfs supports long paths"
atf_set "require.user" "root"
}
tarfs_long_paths_body() {
tarfs_setup
local a b c d e
a="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
b="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
c="cccccccccccccccccccccccccccccccccccccccc"
d="dddddddddddddddddddddddddddddddddddddddd"
e="eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
mkdir -p "${a}/${b}/${c}/${d}/${e}"
touch "${a}/${b}/${c}/${d}/${e}/foo"
ln "${a}/${b}/${c}/${d}/${e}/foo" "${a}/${b}/${c}/${d}/${e}/bar"
ln -s "${b}/${c}/${d}/${e}/bar" "${a}/baz"
tar -cf tarfs_long_paths.tar "${a}"
atf_check mount -rt tarfs tarfs_long_paths.tar "${mnt}"
}
tarfs_long_paths_cleanup() {
tarfs_cleanup
}
atf_init_test_cases() {
atf_add_test_case tarfs_basic
atf_add_test_case tarfs_basic_gnu
@ -324,4 +372,6 @@ atf_init_test_cases() {
atf_add_test_case tarfs_linktodir
atf_add_test_case tarfs_linktononexistent
atf_add_test_case tarfs_checksum
atf_add_test_case tarfs_long_names
atf_add_test_case tarfs_long_paths
}