Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP3:Update
exfatprogs.27900
mkfs-fix-boot-sector-checksum-when-the-sector-s...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File mkfs-fix-boot-sector-checksum-when-the-sector-size-i.patch of Package exfatprogs.27900
From f570d7828ec8f993f947bccc8b65ef4aaed08bd7 Mon Sep 17 00:00:00 2001 From: Christophe Vu-Brugier <christophe.vu-brugier@seagate.com> Date: Tue, 11 May 2021 09:40:49 +0200 Subject: [PATCH] mkfs: fix boot sector checksum when the sector size is 4 KB "4K native" HDDs advertise a physical sector size and a logical sector size of 4 KB. A sector size of 4 KB is supported according to the exFAT specification. From section 3.1.14: > The valid range of values for [BytesPerSectorShift] shall be: > * At least 9 (sector size of 512 bytes), which is the smallest > sector possible for an exFAT volume > * At most 12 (sector size of 4096 bytes), which is the memory page > size of CPUs common in personal computers Unfortunately, several bugs in `mkfs.exfat` prevent it from properly formatting devices whose logical sector size is 4 KB. The Linux kernel reports the following error at `mount` time: $ sudo mount /dev/vda /mnt/ [ 262.063000] exFAT-fs (vda): Invalid boot checksum (boot checksum : 0x8455546b, checksum : 0xfedcaae5) [ 262.068991] exFAT-fs (vda): invalid boot region [ 262.071618] exFAT-fs (vda): failed to recognize exfat type mount: /mnt: wrong fs type, bad option, bad superblock on /dev/vda, missing codepage or helper program, or other error. There are 3 issues in `mkfs.exfat:` 1. it truncates some volume structures that should fill an entire sector (4 KB for 4Kn HDDs) to 512 bytes when writing them. 2. it computes the main and backup boot checksums using only 512 bytes for some sectors. Hence the error reported by Linux. 3. it writes the extended boot signature at offset 510 bytes whatever the sector size is. This is fixed by using `bd->sector_size` to allocate, clear, and checksum the sectors. Moreover, the extended boot signature is now placed in the last two bytes of the extended boot sectors. This patch fixes issue #163. Signed-off-by: Christophe Vu-Brugier <christophe.vu-brugier@seagate.com> (cherry picked from commit 1e3163a68d3b73ad8d55df12c5a8b639003de188) [ddiss: rebase without b4d9c9 ("exfatlabel: add get/set volume serial")] Acked-by: David Disseldorp <ddiss@suse.de> --- include/exfat_ondisk.h | 11 ----------- mkfs/mkfs.c | 30 ++++++++++++++++++++---------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/include/exfat_ondisk.h b/include/exfat_ondisk.h index 163bef0..bfbdb1a 100644 --- a/include/exfat_ondisk.h +++ b/include/exfat_ondisk.h @@ -131,17 +131,6 @@ struct pbr { __le16 signature; }; -/* Extended Boot Sector */ -struct exbs { - __u8 zero[510]; - __le16 signature; -}; - -/* Extended Boot Record (8 sectors) */ -struct expbr { - struct exbs eb[8]; -}; - #define VOLUME_LABEL_MAX_LEN 11 #define ENTRY_NAME_MAX 15 diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index 9fff978..5b8e7fb 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -121,12 +121,12 @@ static int exfat_write_boot_sector(struct exfat_blk_dev *bd, if (is_backup) sec_idx += BACKUP_BOOT_SEC_IDX; - ppbr = malloc(sizeof(struct pbr)); + ppbr = malloc(bd->sector_size); if (!ppbr) { exfat_err("Cannot allocate pbr: out of memory\n"); return -1; } - memset(ppbr, 0, sizeof(struct pbr)); + memset(ppbr, 0, bd->sector_size); exfat_setup_boot_sector(ppbr, bd, ui); @@ -138,7 +138,7 @@ static int exfat_write_boot_sector(struct exfat_blk_dev *bd, goto free_ppbr; } - boot_calc_checksum((unsigned char *)ppbr, sizeof(struct pbr), + boot_calc_checksum((unsigned char *)ppbr, bd->sector_size, true, checksum); free_ppbr: @@ -149,26 +149,36 @@ free_ppbr: static int exfat_write_extended_boot_sectors(struct exfat_blk_dev *bd, unsigned int *checksum, bool is_backup) { - struct exbs eb; + char *peb; + __le16 *peb_signature; + int ret = 0; int i; unsigned int sec_idx = EXBOOT_SEC_IDX; + peb = malloc(bd->sector_size); + if (!peb) + return -1; + if (is_backup) sec_idx += BACKUP_BOOT_SEC_IDX; - memset(&eb, 0, sizeof(struct exbs)); - eb.signature = cpu_to_le16(PBR_SIGNATURE); + memset(peb, 0, bd->sector_size); + peb_signature = (__le16*) (peb + bd->sector_size - 2); + *peb_signature = cpu_to_le16(PBR_SIGNATURE); for (i = 0; i < EXBOOT_SEC_NUM; i++) { - if (exfat_write_sector(bd, &eb, sec_idx++)) { + if (exfat_write_sector(bd, peb, sec_idx++)) { exfat_err("extended boot sector write failed\n"); - return -1; + ret = -1; + goto free_peb; } - boot_calc_checksum((unsigned char *) &eb, sizeof(struct exbs), + boot_calc_checksum((unsigned char *) peb, bd->sector_size, false, checksum); } - return 0; +free_peb: + free(peb); + return ret; } static int exfat_write_oem_sector(struct exfat_blk_dev *bd, -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor