Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: fix EFI file system to fit partition size #2528

Merged

Conversation

markusboehme
Copy link
Member

@markusboehme markusboehme commented Oct 27, 2022

Issue number: n/a

Description of changes: rpm2img creates the various file systems comprising a Bottlerocket image, among them the FAT file system that serves as the EFI System Partition (ESP). rpm2img invokes mkfs.vfat to create the ESP, but accidentally causes it to size the file system structures for double the size of the actual ESP.

The mistake is mostly harmless as proven by working images and current mode of operation that is essentially read-only. However, it can lead to unexpected problems when trying to write to the ESP. Depending on the attempted action, failure modes include receiving SIGBUS, receiving EIO, receiving EINVAL, corrupting files, seeing messages like "lost async page write" or "attempt to access beyond end of device" in the kernel log.

The cause of the bug is a somewhat unfortunate interpretation of the file system size by mkfs.vfat. While its second argument is referred to as a block count, it is not actually related to the requested sector size, but always expressed in units of 1 KiB. rpm2img expressed the file system size in units of sectors (512 bytes), thereby oversizing the file system by a factor of two.

Testing done: I built images of the metal-dev variant with and without this patch. Setting up a loopback device with the resulting image and looking at the EFI System Partition produces the following output for...

...the image created without the patch

$ sudo file -s /dev/loop0p2
/dev/loop0p2: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, reserved sectors 4, root entries 512, sectors 20480 (volumes <=32 MB), Media descriptor 0xf8, sectors/FAT 20, sectors/track 32, serial number 0x3d1d549f, unlabeled, FAT (16 bit)

...and the image created with the patch

$ sudo file -s /dev/loop1p2
/dev/loop1p2: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, reserved sectors 4, root entries 512, sectors 10240 (volumes <=32 MB), Media descriptor 0xf8, sectors/FAT 8, sectors/track 32, serial number 0xdf82f540, unlabeled, FAT (12 bit)

Note that the file system is believed to have 20480 sectors in the image created without the patch instead of 10240 sectors in the image created with the patch. Since each sector contains 512 bytes, and the ESP is only allocated 5 MiB, the file system for the ESP is wrongly sized to fit a 10 MiB partition without the patch.

Terms of contribution:

By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.

rpm2img creates the various file systems comprising a Bottlerocket
image, among them the FAT file system that serves as the EFI System
Partition (ESP). rpm2img invokes mkfs.vfat to create the ESP, but
accidentally causes it to size the file system structures for double the
size of the actual ESP.

The mistake is mostly harmless as proven by working images and current
mode of operation that is essentially read-only. However, it can lead to
unexpected problems when trying to write to the ESP. Depending on the
attempted action, failure modes include receiving SIGBUS, receiving EIO,
receiving EINVAL, corrupting files, seeing messages like "lost async
page write" or "attempt to access beyond end of device" in the kernel
log.

The cause of the bug is a somewhat unfortunate interpretation of the
file system size by mkfs.vfat. While its second argument is referred to
as a block count, it is not actually related to the requested sector
size, but always expressed in units of 1 KiB. rpm2img expressed the file
system size in units of sectors (512 bytes), thereby oversizing the file
system by a factor of two.

Signed-off-by: Markus Boehme <[email protected]>
Copy link
Contributor

@bcressey bcressey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice catch!

Copy link
Contributor

@arnaldo2792 arnaldo2792 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So insightful! 🎉

Copy link
Contributor

@stmcginnis stmcginnis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch!

@markusboehme markusboehme merged commit 338c1cf into bottlerocket-os:develop Oct 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants