tarfs: Don't panic if the parent of a new node is not a directory.
PR: 269519 Sponsored by: Juniper Networks, Inc. Sponsored by: Klara, Inc. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D38587
This commit is contained in:
parent
b918ee2ce4
commit
ae6cff8973
@ -171,6 +171,8 @@ tarfs_alloc_node(struct tarfs_mount *tmp, const char *name, size_t namelen,
|
||||
|
||||
TARFS_DPF(ALLOC, "%s(%.*s)\n", __func__, (int)namelen, name);
|
||||
|
||||
if (parent != NULL && parent->type != VDIR)
|
||||
return (ENOTDIR);
|
||||
tnp = malloc(sizeof(struct tarfs_node), M_TARFSNODE, M_WAITOK | M_ZERO);
|
||||
mtx_init(&tnp->lock, "tarfs node lock", NULL, MTX_DEF);
|
||||
tnp->gen = arc4random();
|
||||
@ -233,7 +235,6 @@ tarfs_alloc_node(struct tarfs_mount *tmp, const char *name, size_t namelen,
|
||||
panic("%s: type %d not allowed", __func__, type);
|
||||
}
|
||||
if (parent != NULL) {
|
||||
MPASS(parent->type == VDIR);
|
||||
TARFS_NODE_LOCK(parent);
|
||||
TAILQ_INSERT_TAIL(&parent->dir.dirhead, tnp, dirents);
|
||||
parent->size += sizeof(struct tarfs_node);
|
||||
|
@ -320,6 +320,12 @@ tarfs_lookup_path(struct tarfs_mount *tmp, char *name, size_t namelen,
|
||||
break;
|
||||
}
|
||||
|
||||
/* we're not at the end, so parent must be a directory */
|
||||
if (parent->type != VDIR) {
|
||||
error = ENOTDIR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* locate the next separator */
|
||||
for (sep = name, len = 0;
|
||||
*sep != '\0' && *sep != '/' && len < namelen;
|
||||
@ -685,8 +691,12 @@ tarfs_alloc_one(struct tarfs_mount *tmp, off_t *blknump)
|
||||
|
||||
error = tarfs_lookup_path(tmp, name, namelen, &namep,
|
||||
&sep, &parent, &tnp, true);
|
||||
if (error != 0)
|
||||
if (error != 0) {
|
||||
TARFS_DPF(ALLOC, "%s: failed to look up %.*s\n", __func__,
|
||||
(int)namelen, name);
|
||||
error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
if (tnp != NULL) {
|
||||
if (hdrp->typeflag[0] == TAR_TYPE_DIRECTORY) {
|
||||
/* XXX set attributes? */
|
||||
|
@ -33,10 +33,11 @@ mnt="$(realpath ${TMPDIR:-/tmp})/mnt.$$"
|
||||
sum=4da2143234486307bb44eaa610375301781a577d1172f362b88bb4b1643dee62
|
||||
|
||||
atf_test_case tarfs_test
|
||||
tarfs_test_head() {
|
||||
tarfs_basic_head() {
|
||||
atf_set "descr" "Basic function test"
|
||||
atf_set "require.user" "root"
|
||||
}
|
||||
tarfs_test_body() {
|
||||
tarfs_basic_body() {
|
||||
mkdir "${mnt}"
|
||||
"${mktar}" tarfs_test.tar.zst
|
||||
atf_check mount -rt tarfs tarfs_test.tar.zst "${mnt}"
|
||||
@ -45,10 +46,31 @@ tarfs_test_body() {
|
||||
atf_check_equal "$(stat -f%d,%i "${mnt}"/sparse_file)" "$(stat -L -f%d,%i "${mnt}"/long_link)"
|
||||
atf_check_equal "$(sha256 -q "${mnt}"/sparse_file)" ${sum}
|
||||
}
|
||||
tarfs_test_cleanup() {
|
||||
tarfs_basic_cleanup() {
|
||||
umount "${mnt}"
|
||||
}
|
||||
|
||||
atf_test_case tarfs_notdir
|
||||
tarfs_notdir_head() {
|
||||
atf_set "descr" "Regression test for PR 269519"
|
||||
atf_set "require.user" "root"
|
||||
}
|
||||
tarfs_notdir_body() {
|
||||
mkdir "${mnt}"
|
||||
echo "hello" >d
|
||||
tar cf tarfs_notdir.tar d
|
||||
rm d
|
||||
mkdir -p d/s
|
||||
echo "world" >d/s/f
|
||||
tar rf tarfs_notdir.tar d/s/f
|
||||
atf_check -s not-exit:0 -e match:"Invalid" \
|
||||
mount -rt tarfs tarfs_notdir.tar "${mnt}"
|
||||
}
|
||||
tarfs_notdir_cleanup() {
|
||||
umount "${mnt}"
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case tarfs_test
|
||||
atf_add_test_case tarfs_basic
|
||||
atf_add_test_case tarfs_notdir
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user