Page MenuHomeFreeBSD

D44226.id135405.diff
No OneTemporary

D44226.id135405.diff

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
@@ -56,7 +56,7 @@
#include <fs/tarfs/tarfs.h>
#include <fs/tarfs/tarfs_dbg.h>
-CTASSERT(ZERO_REGION_SIZE > TARFS_BLOCKSIZE);
+CTASSERT(ZERO_REGION_SIZE >= TARFS_BLOCKSIZE);
struct ustar_header {
char name[100]; /* File name */
@@ -75,8 +75,11 @@
char major[8]; /* Device major number */
char minor[8]; /* Device minor number */
char prefix[155]; /* Path prefix */
+ char _pad[12];
};
+CTASSERT(sizeof(struct ustar_header) == TARFS_BLOCKSIZE);
+
#define TAR_EOF ((off_t)-1)
#define TAR_TYPE_FILE '0'
@@ -202,22 +205,27 @@
tarfs_checksum(struct ustar_header *hdrp)
{
const unsigned char *ptr;
- int64_t checksum, hdrsum;
- size_t idx;
+ unsigned long checksum, hdrsum;
- hdrsum = tarfs_str2int64(hdrp->checksum, sizeof(hdrp->checksum));
- TARFS_DPF(CHECKSUM, "%s: header checksum %lx\n", __func__, hdrsum);
+ if (tarfs_str2int64(hdrp->checksum, sizeof(hdrp->checksum), &hdrsum) != 0) {
+ TARFS_DPF(CHECKSUM, "%s: invalid header checksum \"%.*s\"\n",
+ __func__, (int)sizeof(hdrp->checksum), hdrp->checksum);
+ return (false);
+ }
+ TARFS_DPF(CHECKSUM, "%s: header checksum \"%.*s\" = %#lo\n", __func__,
+ (int)sizeof(hdrp->checksum), hdrp->checksum, hdrsum);
checksum = 0;
for (ptr = (const unsigned char *)hdrp;
ptr < (const unsigned char *)hdrp->checksum; ptr++)
checksum += *ptr;
- for (idx = 0; idx < sizeof(hdrp->checksum); idx++)
+ for (;
+ ptr < (const unsigned char *)hdrp->typeflag; ptr++)
checksum += 0x20;
- for (ptr = (const unsigned char *)hdrp->typeflag;
+ for (;
ptr < (const unsigned char *)(hdrp + 1); ptr++)
checksum += *ptr;
- TARFS_DPF(CHECKSUM, "%s: calc unsigned checksum %lx\n", __func__,
+ TARFS_DPF(CHECKSUM, "%s: calc unsigned checksum %#lo\n", __func__,
checksum);
if (hdrsum == checksum)
return (true);
@@ -230,12 +238,13 @@
for (ptr = (const unsigned char *)hdrp;
ptr < (const unsigned char *)&hdrp->checksum; ptr++)
checksum += *((const signed char *)ptr);
- for (idx = 0; idx < sizeof(hdrp->checksum); idx++)
+ for (;
+ ptr < (const unsigned char *)&hdrp->typeflag; ptr++)
checksum += 0x20;
- for (ptr = (const unsigned char *)&hdrp->typeflag;
+ for (;
ptr < (const unsigned char *)(hdrp + 1); ptr++)
checksum += *((const signed char *)ptr);
- TARFS_DPF(CHECKSUM, "%s: calc signed checksum %lx\n", __func__,
+ TARFS_DPF(CHECKSUM, "%s: calc signed checksum %#lo\n", __func__,
checksum);
if (hdrsum == checksum)
return (true);
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
@@ -285,6 +285,27 @@
mount -rt tarfs tarfs_linktononexistent.tar "${mnt}"
}
tarfs_linktononexistent_cleanup() {
+ tarfs_cleanup
+}
+
+atf_test_case tarfs_checksum cleanup
+tarfs_checksum_head() {
+ atf_set "descr" "Verify that the checksum covers header padding"
+ atf_set "require.user" "root"
+}
+tarfs_checksum_body() {
+ kldload -n tarfs || atf_skip "This test requires tarfs and could not load it"
+ mkdir "${mnt}"
+ touch f
+ tar -cf tarfs_checksum.tar f
+ truncate -s 500 tarfs_checksum.tar
+ printf "\1\1\1\1\1\1\1\1\1\1\1\1" >> tarfs_checksum.tar
+ dd if=/dev/zero bs=512 count=2 >> tarfs_checksum.tar
+ hexdump -C tarfs_checksum.tar
+ atf_check -s not-exit:0 -e match:"Invalid" \
+ mount -rt tarfs tarfs_checksum.tar "${mnt}"
+}
+tarfs_checksum_cleanup() {
umount "${mnt}" || true
}
@@ -302,4 +323,5 @@
atf_add_test_case tarfs_emptylink
atf_add_test_case tarfs_linktodir
atf_add_test_case tarfs_linktononexistent
+ atf_add_test_case tarfs_checksum
}

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 8, 8:40 AM (17 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31038566
Default Alt Text
D44226.id135405.diff (3 KB)

Event Timeline