Skip to content

[BUG] PhysicalDisk size wrong (saturates at 2 TiB) on 32-bit platforms for disks >2 TiB #2563

Description

@baracudaz

Describe the bug

On 32-bit platforms where unsigned long is 32 bits (e.g. armv5tel with ILP32), the PhysicalDisk module reports the wrong size for any disk larger than 2 TiB. Sizes above the 32-bit sector-count limit are silently clamped to ULONG_MAX sectors instead of the real value.

To Reproduce

On a 32-bit Linux system (getconf LONG_BIT32) with a disk larger than 2 TiB attached (in this case a 4 TB ST4000VN000-1H41 on Debian 13/trixie, armv5tel, Marvell Kirkwood):

$ fastfetch --structure PhysicalDisk --format json
[
  {
    "type": "PhysicalDisk",
    "result": [
      {
        "name": "ATA ST4000VN000-1H41",
        "devPath": "/dev/sda",
        ...
        "size": 2199023255040,
        ...
      }
    ]
  }
]

fastfetch --pipe false renders this as 2.00 TiB.

Ground truth from the kernel is correct — the drive really is ~4 TB:

$ cat /sys/block/sda/size
7814037168
$ blockdev --getsize64 /dev/sda
4000787030016
$ lsblk -b -o NAME,SIZE,MODEL
sda 4000787030016 ST4000VN000-1H4168

Root cause

In src/detection/physicaldisk/physicaldisk_linux.c, parsePhysicalDisk() parses the sysfs size file (a 512-byte-sector count, up to 64 bits wide) with strtoul:

char blkSize[32];
ssize_t fileSize = ffReadFileDataRelative(dfd, "size", ARRAY_SIZE(blkSize) - 1, blkSize);
if (fileSize > 0) {
    blkSize[fileSize] = 0;
    size = (uint64_t) strtoul(blkSize, nullptr, 10) * 512;
}

strtoul returns unsigned long. On this platform sizeof(unsigned long) == 4, so its max value is 4294967295. The real sector count (7814037168) overflows that, and per C99 7.20.1.4/7.24.1.4 strtoul on overflow returns ULONG_MAX (and sets errno = ERANGE, which isn't checked here). So the parsed value saturates at 4294967295 sectors:

4294967295 * 512 = 2199023255040  # exactly the reported "size" above

Disks whose sector count fits in 32 bits (e.g. a 1 TB drive, 1953525168 sectors) are unaffected, which matches what's observed — the second disk in the same box reports correctly.

Suggested fix

Use a 64-bit-safe parse, e.g. strtoull/strtoumax, regardless of host long width:

size = (uint64_t) strtoull(blkSize, nullptr, 10) * 512;

System info

  • fastfetch version: 2.40.4 (Debian trixie armhf/armv5tel build)
  • OS: Debian GNU/Linux 13 (trixie), armv5tel
  • getconf LONG_BIT: 32
  • Confirmed the same strtoul call is still present on dev as of commit ba18705d (2026-07-10).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions