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 */

Reply via email to