https://bugs.kde.org/show_bug.cgi?id=523706

            Bug ID: 523706
           Summary: NTFS boot sector corrupted when moving a partition
                    that starts beyond 2 TiB: 64-bit start LBA written
                    into the 32-bit hidden_sectors field, overflowing into
                    large_sectors (0x20)
    Classification: Applications
           Product: partitionmanager
      Version First 23.08.5
       Reported In:
          Platform: Ubuntu
                OS: Linux
            Status: REPORTED
          Severity: critical
          Priority: NOR
         Component: general
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

Versions

  - partitionmanager 23.08.5
  - libkpmcore12 23.08.5
  - Backend plugin: pmsfdiskbackendplugin
  - Ubuntu 24.04.4 LTS, kernel 6.8.0-136-generic
  - util-linux 2.39.3, ntfs-3g 2022.10.3, plasma-desktop 5.27.12

  Setup

  - 3 TB SATA HDD, GPT, 512 logical / 4096 physical sector size
  - Drive health clean: 0 reallocated, 0 pending, 0 offline uncorrectable, 0
UDMA CRC errors, no ATA errors logged
  - NTFS partition, type GUID EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
  - After the move: start LBA 4801347584, size 409600000 sectors

  Operation

  Move the NTFS partition left by ~202 GiB, then grow it into the freed space.
The move reported success; the grow failed.

  New start LBA 4801347584 > 2³² (4294967296).

  Observed corruption

  Boot sector bytes 0x1C–0x23, identical in primary (LBA 0) and backup (last
sector):

  0x1C:  00 c0 2e 1e   01 00 00 00

  - Read as u64 LE = 4801347584 = the new start LBA, exactly
  - 0x1C hidden_sectors (u32) = 506380288 = 4801347584 mod 2³² — correct
  - 0x20 large_sectors (u32) = 1 = 4801347584 >> 32 — must be 0 per NTFS

  An 8-byte write was issued at offset 0x1C, where the field is 4 bytes. The
high dword landed on large_sectors.                                             

  Trigger condition

  Partition start LBA ≥ 2³² sectors (≥ 2 TiB at 512-byte logical sectors).
Below that the high dword is 0, so the overspill writes zeros over an
already-zero field and is a silent no-op. That is likely
  why this has gone unreported.

  Suspected code

  src/fs/ntfs.cpp, ntfs::updateBootSector() — the sector number passed to
writeData(..., 0x1c) is 64-bit; only its low 32 bits belong at 0x1C.

  Consequences

  - ntfs-3g refuses to open the volume: Reserved fields aren't zero (0, 0, 0,
0, 1, 0). — the 5th printed value is large_sectors
  - ntfsresize, ntfsfix, ntfsinfo all fail in ntfs_boot_sector_is_ntfs();
ntfsfix cannot repair because it cannot parse the volume
  - libblkid reports no TYPE= at all, only PTTYPE="dos" (falling back to the
0x55AA at 0x1FE), so a plain mount fails with unknown filesystem type
  - wipefs reports only dos at offset 0x1fe
  - Windows presents the volume as RAW and prompts to format —
NtfsIsBootSectorNtfs() validates the same six fields
  - The Linux ntfs3 kernel driver mounts and reads the volume normally; it does
not check the legacy FAT-compat BPB fields

  Filesystem is otherwise intact

  - total_sectors = 409599999 (correct, partition size − 1)
  - bytes/sector 512, sectors/cluster 8, media 0xF8, jump eb 52 90, OEM NTFS   
, signature 55AA — all correct
  - $MFT and $MFTMirr both start with FILE; first four records byte-identical
  - Primary and backup boot sectors byte-identical — both received the bad
write

  Consequential failure

  The grow step failed immediately after the move because it invokes
ntfsresize, which can no longer open the volume that was just corrupted. The
resize from 409,600,000 to 833,904,640 sectors aborted
  and the partition size was reverted. Net result: the partition moved, the
filesystem did not grow, and the volume became unreadable to Windows and to all
ntfs-3g tooling.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to