From nobody Tue Apr 25 08:00:36 2023 X-Original-To: dev-commits-src-all@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 4Q5DvS3DMfz46pc5; Tue, 25 Apr 2023 08:00:36 +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 4Q5DvS2mtpz3kKv; Tue, 25 Apr 2023 08:00:36 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682409636; 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=Ote/GN7EQhqs9XMk4QGdq5p9j0WzhzaYUJvJUpijubI=; b=geUAyRAU4hsVt7RExyJjmpNNjp5RNT6jddwTFPY2OpBqri8c49OwYILSWfKtHmmppDlRa6 Mg/DPU87BXy04PCA/W40VIGAI6bPJS8Cj7CMyRr7sVS9Dm2xDdUWs9Z0JkRhVHOtIrgHL7 Lc33OWTyFBvHQ67L5Ayzif8JttkaGnyW2O0wimxEC2kfrHBOCPHGGkAFUruyRQTGEJeOIG IXZmvUEZ6FfsDwb43nlzyBaLOv2MDK9LPfoqvdcJgZZYJTfDxDyuzHPOfP2sJrX0/vdvQW PWQiAQHGJWlCsSpyC53V8rEw3WYLiDlIzhsOcdxH+bl3+MPTo9/DDk8psac1fA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682409636; 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=Ote/GN7EQhqs9XMk4QGdq5p9j0WzhzaYUJvJUpijubI=; b=TJx+CS5+4xT9uziLHRALt0waPt6K9tQIjndBQQ3RUh417fJ/A12boFNKMGuBloVt3j0ubq IMbKOM162QRjoOMe/FVD5d3TSf9RQyg3ufjABOXA/nVLaiqXYhx/CawYfmVdSjmczA15TW uoIxy3iB3o9DBm5uusklH6KWb/o9nMqPJipvEpJ4xJVQyes0bhgKHmuawdu1ztLkhGhj3Y GWujwnWm8VKassEU2m8LauIvNyahVIY1g2tES4ByxtaSPa1fM+7++YbLZk9IfCMQHs3fj2 Dyv4OnHtNDS/Br/KNVsyghq37Gk9ewnGv+QTCsfGRY+IxYs7syW2ZFb9i2TLgA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1682409636; a=rsa-sha256; cv=none; b=R8uIMbBiMHewtX40xcG+JhnY8sK8p/LEfwUFUGzwbghGq9m9NwadMGhp1kBKle+5pZPNqp mGbziGD1EfUw4GQsQUwxmRZ3ojkOMtbHgEKK4Ses94Z7YCzxu2fT1RcNW0dNCgfgrX62ah 2EjXZLvZpg9ckHjcu9PbHVqeCjwDiYcSla7oL8qLXpmUO+xCbShXsryDmpSRAdGTZgmFrb ZHid2SJw2CA1oSomfLEtPBdooJjZuB2TSHIb7COb1CZrYbGE657VlcOx6nnHkefwb4jF7z 0KS3rGEhxR7GzY8YM1CDg7qBqIexLl7K38uuBzfeDWYepmRoJNy9Laoiu9VsWg== 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 4Q5DvS1qlTz105h; Tue, 25 Apr 2023 08:00:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 33P80aoQ091520; Tue, 25 Apr 2023 08:00:36 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33P80a57091519; Tue, 25 Apr 2023 08:00:36 GMT (envelope-from git) Date: Tue, 25 Apr 2023 08:00:36 GMT Message-Id: <202304250800.33P80a57091519@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: =?utf-8?Q?Stefan=20E=C3=9Fer?= Subject: git: 0728695c63ef - main - fs/msdosfs: Fix potential panic and size calculations List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: se X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 0728695c63efda298feccefb3615c23cb6682929 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by se: URL: https://cgit.FreeBSD.org/src/commit/?id=0728695c63efda298feccefb3615c23cb6682929 commit 0728695c63efda298feccefb3615c23cb6682929 Author: Stefan Eßer AuthorDate: 2023-04-25 06:35:16 +0000 Commit: Stefan Eßer CommitDate: 2023-04-25 07:58:29 +0000 fs/msdosfs: Fix potential panic and size calculations Some combinations of FAT12 file system parameters could cause a kernel panic due to an unmapped access if the size of the FAT was larger than the CPU page size. The reason is that FAT12 uses 3 bytes to store 2 FAT pointers, leading to partial FAT pointers at the end of buffers of a size that is not a multiple of 3. With a typical page size of 4 KB, this caused the FAT entry at byte offsets 4095 and 4096 to cross the page boundary, with only the first page mapped. This was fixed by adjusting the mapping to always cover both bytes of each FAT entry. Testing revealed 2 other inconsistencies that are fixed by this commit: 1) The calculation of the size of the data area did not take into account the fact that the first two data block numbers are reserved and that the data area starts with block 2. This could cause a FAT12 file system created with the maximum supported number of blocks to be incorrectly identified as FAT16. 2) The root directory does not take up space in the data area of a FAT12 or FAT16 file system, since it is placed into a reserved area outside of that data area. This commits makes stat() report the logical size of the root directory, but with 0 blocks allocated from the data area. PR: 270587 Reviewed by: mckusick Differential Revision: https://reviews.freebsd.org/D39386 --- sys/fs/msdosfs/msdosfs_fat.c | 12 +++++++++--- sys/fs/msdosfs/msdosfs_vfsops.c | 15 +++++++++------ sys/fs/msdosfs/msdosfs_vnops.c | 7 +++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index e6d9b671e7d7..2d50d30f33b3 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -89,11 +89,17 @@ static void fatblock(struct msdosfsmount *pmp, u_long ofs, u_long *bnp, u_long *sizep, u_long *bop) { - u_long bn, size; + u_long bn, size, fatblocksec; + fatblocksec = pmp->pm_fatblocksec; + if (FAT12(pmp) && fatblocksec % 3 != 0) { + fatblocksec *= 3; + if (fatblocksec % 6 == 0) + fatblocksec /= 2; + } bn = ofs / pmp->pm_fatblocksize * pmp->pm_fatblocksec; - size = min(pmp->pm_fatblocksec, pmp->pm_FATsecs - bn) - * DEV_BSIZE; + size = roundup(min(fatblocksec, pmp->pm_FATsecs - bn) * DEV_BSIZE, + pmp->pm_BlkPerSec * DEV_BSIZE); bn += pmp->pm_fatblk + pmp->pm_curfat * pmp->pm_FATsecs; if (bnp) diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index e2b1fd6b91f5..87e150e0e18a 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -700,11 +700,14 @@ mountmsdosfs(struct vnode *odevvp, struct mount *mp) } pmp->pm_maxcluster = (pmp->pm_HugeSectors - pmp->pm_firstcluster) / SecPerClust + 1; - pmp->pm_fatsize = pmp->pm_FATsecs * DEV_BSIZE; /* XXX not used? */ + pmp->pm_fatsize = pmp->pm_FATsecs * DEV_BSIZE; if (pmp->pm_fatmask == 0) { - if (pmp->pm_maxcluster <= ((CLUST_RSRVD - CLUST_FIRST) & - FAT12_MASK)) { + /* + * The last 10 (or 16?) clusters are reserved and must not + * be allocated for data. + */ + if (pmp->pm_maxcluster < (CLUST_RSRVD & FAT12_MASK)) { /* * This will usually be a floppy disk. This size makes * sure that one FAT entry will not be split across @@ -720,11 +723,11 @@ mountmsdosfs(struct vnode *odevvp, struct mount *mp) } } - clusters = (pmp->pm_fatsize / pmp->pm_fatmult) * pmp->pm_fatdiv; + clusters = (pmp->pm_fatsize / pmp->pm_fatmult) * pmp->pm_fatdiv ; if (pmp->pm_maxcluster >= clusters) { #ifdef MSDOSFS_DEBUG printf("Warning: number of clusters (%ld) exceeds FAT " - "capacity (%ld)\n", pmp->pm_maxcluster + 1, clusters); + "capacity (%ld)\n", pmp->pm_maxcluster - 1, clusters); #endif pmp->pm_maxcluster = clusters - 1; } @@ -1045,7 +1048,7 @@ msdosfs_statfs(struct mount *mp, struct statfs *sbp) pmp = VFSTOMSDOSFS(mp); sbp->f_bsize = pmp->pm_bpcluster; sbp->f_iosize = pmp->pm_bpcluster; - sbp->f_blocks = pmp->pm_maxcluster + 1; + sbp->f_blocks = pmp->pm_maxcluster - CLUST_FIRST + 1; sbp->f_bfree = pmp->pm_freeclustercount; sbp->f_bavail = pmp->pm_freeclustercount; sbp->f_files = howmany(pmp->pm_rootdirsize * DEV_BSIZE, diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index f095a4abea62..bc47f9dde574 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -313,8 +313,11 @@ msdosfs_getattr(struct vop_getattr_args *ap) vap->va_flags |= UF_SYSTEM; vap->va_gen = 0; vap->va_blocksize = pmp->pm_bpcluster; - vap->va_bytes = - (dep->de_FileSize + pmp->pm_crbomask) & ~pmp->pm_crbomask; + if (dep->de_StartCluster != MSDOSFSROOT) + vap->va_bytes = + (dep->de_FileSize + pmp->pm_crbomask) & ~pmp->pm_crbomask; + else + vap->va_bytes = 0; /* FAT12/FAT16 root dir in reserved area */ vap->va_type = ap->a_vp->v_type; vap->va_filerev = dep->de_modrev; return (0);