The branch main has been updated by delphij: URL: https://cgit.FreeBSD.org/src/commit/?id=18094609d301540526d3d57e92705bc989d29986
commit 18094609d301540526d3d57e92705bc989d29986 Author: Chris Suter <[email protected]> AuthorDate: 2026-09-03 05:23:46 +0000 Commit: Xin LI <[email protected]> CommitDate: 2026-09-03 06:51:19 +0000 fsck_msdosfs: avoid signed integer overflow in readboot() readboot() decoded the 32-bit little-endian BIOS Parameter Block and FSInfo fields by shifting the individual bytes of a u_char array into place. The u_char operands are promoted to signed int, so shifting a most significant byte of 0x80 or greater left by 24 overflows int, which is undefined behavior. Use le32dec() from <sys/endian.h> instead, which is both well defined and easier to read. No functional change intended. MFC after: 1 week Pull Request: https://github.com/freebsd/freebsd-src/pull/2350 --- sbin/fsck_msdosfs/boot.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/sbin/fsck_msdosfs/boot.c b/sbin/fsck_msdosfs/boot.c index f91609470ad7..ec59c3e02dde 100644 --- a/sbin/fsck_msdosfs/boot.c +++ b/sbin/fsck_msdosfs/boot.c @@ -32,6 +32,7 @@ __RCSID("$NetBSD: boot.c,v 1.22 2020/01/11 16:29:07 christos Exp $"); #endif /* not lint */ #include <sys/param.h> +#include <sys/endian.h> #include <stdint.h> #include <stdlib.h> @@ -127,12 +128,10 @@ readboot(int dosfs, struct bootblock *boot) boot->bpbHeads = block[26] + (block[27] << 8); /* Hidden sectors: ignored */ - boot->bpbHiddenSecs = block[28] + (block[29] << 8) + - (block[30] << 16) + (block[31] << 24); + boot->bpbHiddenSecs = le32dec(&block[28]); /* Total sectors (32 bits) */ - boot->bpbHugeSectors = block[32] + (block[33] << 8) + - (block[34] << 16) + (block[35] << 24); + boot->bpbHugeSectors = le32dec(&block[32]); if (boot->bpbHugeSectors == 0) { if (boot->flags & FAT32) { pfatal("FAT32 with sector count of zero"); @@ -158,8 +157,7 @@ readboot(int dosfs, struct bootblock *boot) } /* 32-bit count of sectors per FAT */ - boot->FATsecs = block[36] + (block[37] << 8) - + (block[38] << 16) + (block[39] << 24); + boot->FATsecs = le32dec(&block[36]); if (block[40] & 0x80) boot->ValidFat = block[40] & 0x0f; @@ -176,8 +174,7 @@ readboot(int dosfs, struct bootblock *boot) * * Should be 2 but do not require it. */ - boot->bpbRootClust = block[44] + (block[45] << 8) - + (block[46] << 16) + (block[47] << 24); + boot->bpbRootClust = le32dec(&block[44]); /* Sector number of the FSInfo structure, usually 1 */ boot->bpbFSInfo = block[48] + (block[49] << 8); @@ -236,12 +233,8 @@ readboot(int dosfs, struct bootblock *boot) boot->bpbFSInfo = 0; } else { /* We appear to have a valid FSInfo block, decode */ - boot->FSFree = fsinfo[0x1e8] + (fsinfo[0x1e9] << 8) - + (fsinfo[0x1ea] << 16) - + (fsinfo[0x1eb] << 24); - boot->FSNext = fsinfo[0x1ec] + (fsinfo[0x1ed] << 8) - + (fsinfo[0x1ee] << 16) - + (fsinfo[0x1ef] << 24); + boot->FSFree = le32dec(&fsinfo[0x1e8]); + boot->FSNext = le32dec(&fsinfo[0x1ec]); } } else { /* !FAT32: FAT12/FAT16 */
