From nobody Wed Mar 06 16:24:33 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Tqd75674rz5Csr1; Wed, 6 Mar 2024 16:24:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Tqd753tLRz4fWs; Wed, 6 Mar 2024 16:24:33 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1709742273; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Wd9eYdDG50dDf+b8UuzgrHYH/SsqyTm6AocQDpmmAH4=; b=VG8PfnccEPhnLv/mqK666nyxWIYlBVvdyaeaCV5ZMzInopFXT7yKsxInoQrAGMg0jTnHLs HCfKRRtgrwivZ5x0WxWlJldm4JSMu3enH1YGGN0HQ4yl9LsjXjHVaXiBk/677HqLZ9svEc kHq85Sz8ZjgDPCv0PDMzCCxZ6K2UxhaF9hzJhO4p1IfMtEo1kRv40KhWlkRwDDNkxttKoH AL2/jjgxTPrIq7BVJ6zJc+hqib0TRCnzra3npBCX4et9Ax/Q8uZBhMJ6RUm7VE/qPuMCSX MRpewSExolXZEmMwFjByHaOOLURg8vQ40BgS16VROthGmgGpn/l5CAQjx0gbhA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1709742273; a=rsa-sha256; cv=none; b=iQx0No3kIsISnLx24I3KfxTa2/IYihOgrd+dzfgmJkLjrgX1yviyBDLEw2cYru+0VFSYkD spaGxuEOO+0FkdKIlmznMdZZfjDY45VkJvBIV27koZYTnm8CLs/BXPR5j3WPmfAN6cA+7p A2RMhpjgRg1nFyaXfVLpIKzZyIHyFjGn/4Op4BI+/xH0mzmkKw73+ClF2hQSkMbRVdu/Jm EsvfejKptl+VOhMUH8e5bGFO/8eoxnuQs+xNfq2EJk1ON4uuPHkqM1DJpX1BZ+aNe4KLEu cZpXSSXe27x3/ULP7oFajLCaYcVhIFvQm01/ne40DHNSHJdufP6xvVjg5CDnjw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1709742273; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Wd9eYdDG50dDf+b8UuzgrHYH/SsqyTm6AocQDpmmAH4=; b=A7+fLfZpzIs0j8RrK61ycFJvaGqK5rGTlmkpY7pUqeyBYLpGmVh6OAIohfvA1qFcOFaMtk ExjBCEHnW14fvfoihH22CNewgPDMpwQ68c/z/D/atu6i3Pzz0xxDuVxwLz70y/0N7sgfBl NPkGaxXFTqv75XYzoqEFNDy6vSaLr4pmsXyr8nE8Kx7BVe6tzuzNs1TIvL3hbOQBsPz528 WneS2kyP4oWhM3AmJaj3wntg8bMi3kqanC3A/aJMoCaNGPskEjGPO+AyPIkI41N8wuEDxh EAgZiw8zbfz7j+Ey0e+CkodcgBrs5rXkQGb56XXi0UYFXaj4KWw9EFIAKmVsxg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Tqd753SmjzxY6; Wed, 6 Mar 2024 16:24:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 426GOXtH025210; Wed, 6 Mar 2024 16:24:33 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 426GOXC7025207; Wed, 6 Mar 2024 16:24:33 GMT (envelope-from git) Date: Wed, 6 Mar 2024 16:24:33 GMT Message-Id: <202403061624.426GOXC7025207@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 0118b0c8e58a - main - tarfs: Fix checksum calculation. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 0118b0c8e58a438a931a5ce1bf8d7ae6208cc61b Auto-Submitted: auto-generated The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=0118b0c8e58a438a931a5ce1bf8d7ae6208cc61b commit 0118b0c8e58a438a931a5ce1bf8d7ae6208cc61b Author: Dag-Erling Smørgrav AuthorDate: 2024-03-06 16:14:01 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2024-03-06 16:14:01 +0000 tarfs: Fix checksum calculation. The checksum code assumed that struct ustar_header filled an entire block and calculcated the checksum based on the size of the structure. The header is in fact only 500 bytes long while the checksum covers the entire block (“logical record” in POSIX terms). Add padding and an assertion, and clean up the checksum code. MFC after: 3 days Sponsored by: Juniper Networks, Inc. Sponsored by: Klara, Inc. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D44226 --- sys/fs/tarfs/tarfs_vfsops.c | 31 ++++++++++++++++++++----------- tests/sys/fs/tarfs/tarfs_test.sh | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/sys/fs/tarfs/tarfs_vfsops.c b/sys/fs/tarfs/tarfs_vfsops.c index 33cc019028e6..ce896c5841c0 100644 --- a/sys/fs/tarfs/tarfs_vfsops.c +++ b/sys/fs/tarfs/tarfs_vfsops.c @@ -56,7 +56,7 @@ #include #include -CTASSERT(ZERO_REGION_SIZE > TARFS_BLOCKSIZE); +CTASSERT(ZERO_REGION_SIZE >= TARFS_BLOCKSIZE); struct ustar_header { char name[100]; /* File name */ @@ -75,8 +75,11 @@ struct ustar_header { 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 @@ static boolean_t 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 @@ tarfs_checksum(struct ustar_header *hdrp) 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 index 6f45062c18d9..46aefd832d5d 100644 --- a/tests/sys/fs/tarfs/tarfs_test.sh +++ b/tests/sys/fs/tarfs/tarfs_test.sh @@ -285,6 +285,27 @@ tarfs_linktononexistent_body() { 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_init_test_cases() { atf_add_test_case tarfs_emptylink atf_add_test_case tarfs_linktodir atf_add_test_case tarfs_linktononexistent + atf_add_test_case tarfs_checksum }