grub/grub-core/loader/i386
Daniel Kiper 5826e32c37 chainloader: Fix wrong break condition (must be AND not, OR)
The definition of bpb's num_total_sectors_16 and num_total_sectors_32
is that either the 16-bit field is non-zero and is used (in which case
eg mkfs.fat sets the 32-bit field to zero), or it is zero and the
32-bit field is used. Therefore, a BPB is invalid only if *both*
fields are zero; having one field as zero and the other as non-zero is
the case to be expected. (Indeed, according to Microsoft's specification
one of the fields *must* be zero, and the other non-zero.)

This affects all users of grub_chainloader_patch_bpb which are in
chainloader.c, freedos.c, and ntldr.c

Some descriptions of the semantics of these two fields:

https://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html

  The old 2-byte fields "total number of sectors" and "number of
  sectors per FAT" are now zero; this information is now found in
  the new 4-byte fields.

(Here given in the FAT32 EBPB section but the total sectors 16/32 bit
fields semantic is true of FAT12 and FAT16 too.)

https://wiki.osdev.org/FAT#BPB_.28BIOS_Parameter_Block.29

  19 | 2 | The total sectors in the logical volume. If this value is 0,
  it means there are more than 65535 sectors in the volume, and the actual
  count is stored in "Large Sectors (bytes 32-35).

  32 | 4 | Large amount of sector on media. This field is set if there
  are more than 65535 sectors in the volume.

(Doesn't specify what the "large" field is set to when unused, but as
mentioned mkfs.fat sets it to zero then.)

https://technet.microsoft.com/en-us/library/cc976796.aspx

  0x13 | WORD | 0x0000 |
  Small Sectors . The number of sectors on the volume represented in 16
  bits (< 65,536). For volumes larger than 65,536 sectors, this field
  has a value of zero and the Large Sectors field is used instead.

  0x20 | DWORD | 0x01F03E00 |
  Large Sectors . If the value of the Small Sectors field is zero, this
  field contains the total number of sectors in the FAT16 volume. If the
  value of the Small Sectors field is not zero, the value of this field
  is zero.

https://staff.washington.edu/dittrich/misc/fatgen103.pdf page 10

  BPB_TotSec16 | 19 | 2 |
  This field is the old 16-bit total count of sectors on the volume.
  This count includes the count of all sectors in all four regions of the
  volume. This field can be 0; if it is 0, then BPB_TotSec32 must be
  non-zero. For FAT32 volumes, this field must be 0. For FAT12 and
  FAT16 volumes, this field contains the sector count, and
  BPB_TotSec32 is 0 if the total sector count “fits” (is less than
  0x10000).

  BPB_TotSec32 | 32 | 4 |
  This field is the new 32-bit total count of sectors on the volume.
  This count includes the count of all sectors in all four regions of the
  volume. This field can be 0; if it is 0, then BPB_TotSec16 must be
  non-zero. For FAT32 volumes, this field must be non-zero. For
  FAT12/FAT16 volumes, this field contains the sector count if
  BPB_TotSec16 is 0 (count is greater than or equal to 0x10000).

(This specifies that an unused BPB_TotSec32 field is set to zero.)

By the way fix offsets in include/grub/fat.h.

Tested with lDebug booted in qemu via grub2's
FreeDOS direct loading support, refer to
https://bitbucket.org/ecm/ldosboot + https://bitbucket.org/ecm/ldebug

Signed-off-by: C. Masloch <pushbx@38.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
..
coreboot Fix remaining cases of gcc 7 fallthrough warning. 2017-04-12 01:42:38 +00:00
efi loader: Move verity-hash.h to include 2017-01-25 14:54:46 -08:00
pc chainloader: Fix wrong break condition (must be AND not, OR) 2020-09-21 12:16:25 -04:00
bsd.c bsd: Ensure that kernel is loaded before loading module. 2016-02-27 13:35:36 +01:00
bsd32.c automake commit without merge history 2010-05-06 11:34:04 +05:30
bsd64.c automake commit without merge history 2010-05-06 11:34:04 +05:30
bsd_pagetable.c * grub-core/commands/legacycfg.c (grub_cmd_legacy_kernel): 2010-10-16 22:16:52 +02:00
bsdXX.c loader/bsd: Fix signed/unsigned comparison 2016-01-16 20:40:55 +00:00
linux.c loader/i386: fix out of bound memory copy on non-UEFI linux 2019-10-24 16:59:37 +02:00
multiboot_mbi.c multiboot: disentangle multiboot and multiboot2. 2020-09-21 12:02:37 -04:00
xen.c Merge branch 'gnu' into sync 2017-04-27 12:05:22 -07:00
xen_file.c Merge branch 'gnu' into sync 2017-04-27 12:05:22 -07:00
xen_file32.c Add new ports: i386-xen and x86_64-xen. This allows running GRUB in 2013-11-09 21:29:11 +01:00
xen_file64.c Add new ports: i386-xen and x86_64-xen. This allows running GRUB in 2013-11-09 21:29:11 +01:00
xen_fileXX.c xen: add capability to load p2m list outside of kernel mapping 2016-10-27 16:22:06 +02:00
xnu.c xnu: Supply random seed. 2016-02-12 12:40:10 +01:00