Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151177295
D44161.id135243.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D44161.id135243.diff
View Options
diff --git a/sys/fs/tarfs/tarfs_vfsops.c b/sys/fs/tarfs/tarfs_vfsops.c
--- a/sys/fs/tarfs/tarfs_vfsops.c
+++ b/sys/fs/tarfs/tarfs_vfsops.c
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2013 Juniper Networks, Inc.
- * Copyright (c) 2022-2023 Klara, Inc.
+ * Copyright (c) 2022-2024 Klara, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -451,7 +451,7 @@
int64_t num;
int endmarker = 0;
char *namep, *sep;
- struct tarfs_node *parent, *tnp;
+ struct tarfs_node *parent, *tnp, *other;
size_t namelen = 0, linklen = 0, realsize = 0, sz;
ssize_t res;
dev_t rdev;
@@ -732,28 +732,41 @@
link = hdrp->linkname;
linklen = strnlen(link, sizeof(hdrp->linkname));
}
- error = tarfs_alloc_node(tmp, namep, sep - namep, VREG,
- 0, 0, 0, 0, 0, 0, 0, NULL, 0, parent, &tnp);
- if (error != 0) {
+ if (linklen == 0) {
+ TARFS_DPF(ALLOC, "%s: %.*s: link without target\n",
+ __func__, (int)namelen, name);
+ error = EINVAL;
goto bad;
}
error = tarfs_lookup_path(tmp, link, linklen, NULL,
- NULL, NULL, &tnp->other, false);
- if (tnp->other == NULL ||
- tnp->other->type != VREG ||
- tnp->other->other != NULL) {
- TARFS_DPF(ALLOC, "%s: %.*s: dead hard link to %.*s\n",
+ NULL, NULL, &other, false);
+ if (error != 0) {
+ goto bad;
+ }
+ if (other->type != VREG || other->other != NULL) {
+ TARFS_DPF(ALLOC, "%s: %.*s: invalid link to %.*s\n",
__func__, (int)namelen, name, (int)linklen, link);
error = EINVAL;
goto bad;
}
- tnp->other->nlink++;
+ error = tarfs_alloc_node(tmp, namep, sep - namep, VREG,
+ 0, 0, 0, 0, 0, 0, 0, NULL, 0, parent, &tnp);
+ if (error == 0) {
+ tnp->other = other;
+ tnp->other->nlink++;
+ }
break;
case TAR_TYPE_SYMLINK:
if (link == NULL) {
link = hdrp->linkname;
linklen = strnlen(link, sizeof(hdrp->linkname));
}
+ if (linklen == 0) {
+ TARFS_DPF(ALLOC, "%s: %.*s: link without target\n",
+ __func__, (int)namelen, name);
+ error = EINVAL;
+ goto bad;
+ }
error = tarfs_alloc_node(tmp, namep, sep - namep, VLNK,
0, linklen, mtime, uid, gid, mode, flags, link, 0,
parent, &tnp);
diff --git a/tests/sys/fs/tarfs/Makefile b/tests/sys/fs/tarfs/Makefile
--- a/tests/sys/fs/tarfs/Makefile
+++ b/tests/sys/fs/tarfs/Makefile
@@ -3,7 +3,7 @@
TESTSDIR= ${TESTSBASE}/sys/fs/tarfs
BINDIR= ${TESTSDIR}
-PROGS+= mktar
+PROGS+= mktar tarsum
ATF_TESTS_SH+= tarfs_test
diff --git a/tests/sys/fs/tarfs/tarfs_test.sh b/tests/sys/fs/tarfs/tarfs_test.sh
--- a/tests/sys/fs/tarfs/tarfs_test.sh
+++ b/tests/sys/fs/tarfs/tarfs_test.sh
@@ -2,7 +2,7 @@
#-
# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2023 Klara, Inc.
+# Copyright (c) 2023-2024 Klara, Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -43,6 +43,10 @@
"$(atf_get_srcdir)"/mktar ${TARFS_USE_GNU_TAR+-g} "$@"
}
+tarsum() {
+ "$(atf_get_srcdir)"/tarsum
+}
+
atf_test_case tarfs_basic cleanup
tarfs_basic_head() {
atf_set "descr" "Basic function test"
@@ -225,6 +229,47 @@
tarfs_notdir_file_cleanup
}
+atf_test_case tarfs_emptylink cleanup
+tarfs_emptylink_head() {
+ atf_set "descr" "Regression test for PR 277360: empty link target"
+ atf_set "require.user" "root"
+}
+tarfs_emptylink_body() {
+ kldload -n tarfs || atf_skip "This test requires tarfs and could not load it"
+ mkdir "${mnt}"
+ touch z
+ ln -f z hard
+ ln -fs z soft
+ tar -cf - z hard soft | dd bs=512 skip=1 | tr z '\0' | \
+ tarsum >> tarfs_emptylink.tar
+ atf_check -s not-exit:0 -e match:"Invalid" \
+ mount -rt tarfs tarfs_emptylink.tar "${mnt}"
+}
+tarfs_emptylink_cleanup() {
+ umount "${mnt}" || true
+}
+
+atf_test_case tarfs_linktodir cleanup
+tarfs_linktodir_head() {
+ atf_set "descr" "Regression test for PR 277360: link to directory"
+ atf_set "require.user" "root"
+}
+tarfs_linktodir_body() {
+ kldload -n tarfs || atf_skip "This test requires tarfs and could not load it"
+ mkdir "${mnt}"
+ mkdir d
+ tar -cf - d | dd bs=512 count=1 > tarfs_linktodir.tar
+ rmdir d
+ touch d
+ ln -f d link
+ tar -cf - d link | dd bs=512 skip=1 >> tarfs_linktodir.tar
+ atf_check -s not-exit:0 -e match:"Invalid" \
+ mount -rt tarfs tarfs_linktodir.tar "${mnt}"
+}
+tarfs_linktodir_cleanup() {
+ umount "${mnt}" || true
+}
+
atf_init_test_cases() {
atf_add_test_case tarfs_basic
atf_add_test_case tarfs_basic_gnu
@@ -236,4 +281,6 @@
atf_add_test_case tarfs_notdir_dotdot_gnu
atf_add_test_case tarfs_notdir_file
atf_add_test_case tarfs_notdir_file_gnu
+ atf_add_test_case tarfs_emptylink
+ atf_add_test_case tarfs_linktodir
}
diff --git a/tests/sys/fs/tarfs/tarsum.c b/tests/sys/fs/tarfs/tarsum.c
new file mode 100644
--- /dev/null
+++ b/tests/sys/fs/tarfs/tarsum.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2024 Klara, Inc.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * This program reads a tarball from stdin, recalculates the checksums of
+ * all ustar records within it, and writes the result to stdout.
+ */
+
+#include <err.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+int
+main(void)
+{
+ union {
+ uint8_t bytes[512];
+ struct {
+ uint8_t prelude[148];
+ char checksum[8];
+ uint8_t interlude[101];
+ char magic[6];
+ char version[2];
+ char postlude[];
+ };
+ } ustar;
+ unsigned long sum;
+ ssize_t ret;
+ size_t i;
+
+ for (;;) {
+ if ((ret = fread(&ustar, 1, sizeof(ustar), stdin)) < 0)
+ err(1, "stdin");
+ else if (ret == 0)
+ break;
+ else if ((size_t)ret < sizeof(ustar))
+ err(1, "stdin: Short read");
+ if (strcmp(ustar.magic, "ustar") == 0 &&
+ ustar.version[0] == '0' && ustar.version[1] == '0') {
+ memset(ustar.checksum, ' ', sizeof(ustar.checksum));
+ for (sum = i = 0; i < sizeof(ustar); i++)
+ sum += ustar.bytes[i];
+ sprintf(ustar.checksum, "%#lo", sum);
+ }
+ if ((ret = fwrite(&ustar, 1, sizeof(ustar), stdout)) < 0)
+ err(1, "stdout");
+ else if ((size_t)ret < sizeof(ustar))
+ err(1, "stdout: Short write");
+ }
+ return (0);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 3:05 PM (4 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31038623
Default Alt Text
D44161.id135243.diff (6 KB)
Attached To
Mode
D44161: tarfs: Fix two input validation issues.
Attached
Detach File
Event Timeline
Log In to Comment