Skip to content

Conversation

@Cyanoxygen
Copy link

Some partitioning tools like ones based on libparted (parted and GParted) don't wipe the entire GPT partition name field before writing new partition names. Additionally, it is not guaranteed to be properly zeroed since the UEFI specification does not clearly state that.

Current checksuming logic uses processed partition names which ignores garbage data after the null terminator, and reports an CRC error if such partition table is encountered:

image

(This test program uses gptman to scan for ESP partition(s).)

You can easily recreate this issue using either parted or GParted, first name a partition with a longer name, then rename it with a shorter name. You can see the remining bytes are not zeroed:

image

Use a dedicated raw buffer which directly read or write to the disk to perform checksums without explicit string handling.

@Cyanoxygen Cyanoxygen force-pushed the fix-partition-entry-chksums branch 2 times, most recently from 5362d64 to c14da28 Compare December 11, 2025 06:07
@cecton
Copy link
Member

cecton commented Dec 11, 2025

Hello and thank you so much for your contribution 🙏

I like it thanks! But I think you got the wrong approach on fixing this issue. The partition name is store in a public struct called PartitionName for which we have the entire control over the implementation. I think we should leverage that and improve this struct to also store the original 72 bytes in it so we can checksum the original bytes. This approach will also avoid breaking the API and I can even make a patch release for this.

What do you think about it?

/// A wrapper type for `String` that represents a partition's name.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PartitionName(String); // <-- 2 fields, one for the parsed string, one for the original bytes

impl PartitionName {
    /// Extracts a string slice containing the entire `PartitionName`.
    pub fn as_str(&self) -> &str {
        self.0.as_str() // <-- keep returning the parsed string normally
    }
}

impl From<&str> for PartitionName {
    fn from(value: &str) -> PartitionName {
        PartitionName(value.to_string()) // <-- also generate the field for the UTF-16 bytes
    }
}

impl Serialize for PartitionName {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
// ... serialize the byte fields instead of the string
    }
}

@Cyanoxygen
Copy link
Author

I think we should leverage that and improve this struct to also store the original 72 bytes in it so we can checksum the original bytes. This approach will also avoid breaking the API and I can even make a patch release for this.

Yes, sure! I thought it probably would be better for it to store a copy of the raw bytes so it keeps exactly what it is. Now that you are okay with just leveraging PartitionName (and since dumped contents are actually packed), I'll try to do what you suggested!

@Cyanoxygen Cyanoxygen force-pushed the fix-partition-entry-chksums branch from c14da28 to 0d6ef41 Compare December 11, 2025 14:21
@Cyanoxygen
Copy link
Author

Hi @cecton,

I've updated the code according your suggestion. It takes a rather dirty (I think) approach to deserialize UTF-16 characters.

@Cyanoxygen Cyanoxygen force-pushed the fix-partition-entry-chksums branch 2 times, most recently from 52b067d to 98a4a20 Compare December 12, 2025 16:38
@Cyanoxygen
Copy link
Author

@cecton PR has been updated. Thanks!

Copy link
Member

@cecton cecton left a comment

Choose a reason for hiding this comment

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

Last bit sorry 🙏

@Cyanoxygen
Copy link
Author

Cyanoxygen commented Dec 14, 2025

Last bit sorry 🙏

It's okay. I'll update it tomorrow.

@Cyanoxygen Cyanoxygen force-pushed the fix-partition-entry-chksums branch from 98a4a20 to 267cf40 Compare December 15, 2025 07:35
Some partitioning tools like ones based on libparted (parted and
GParted) don't wipe the entire GPT partition name field before writing
new partition names. Additionally, it is not guaranteed to be properly
zeroed since the UEFI specification does not clearly state that.

Use a dedicated raw buffer holding the entire partition name field
without any conversion for performing checksums and serializations.

Signed-off-by: Xinhui Yang <[email protected]>
disk3.img contains a label written with 512-byte sector size. disk4.img
contains a label with 4096-byte sector size. This test makes sure
the CRC checksum performs correctly when the partition table contains
such name fields. Both labels contains a partition with (intended)
trailing garbage in its name:

 0000: af 3d c6 0f 83 84 72 47  8e 79 3d 69 d8 47 7d e4   .=....rG .y=i.G}.
 0010: 84 d6 89 47 76 ba 4e 45  b2 50 e0 65 2a 5a 4f 76   ...Gv.NE .P.e*ZOv
 0020: 32 00 00 00 00 00 00 00  41 00 00 00 00 00 00 00   2....... A.......
 0030: 00 00 00 00 00 00 00 00  4e 00 61 00 6d 00 65 00   ........ N.a.m.e.
 0040: 20 00 77 00 69 00 74 00  68 00 20 00 67 00 61 00    .w.i.t. h. .g.a.
 0050: 72 00 62 00 61 00 67 00  65 00 00 00 2d 00 3e 00   r.b.a.g. e...-.>.
 0060: 20 00 67 00 61 00 72 00  62 00 61 00 67 00 65 00    .g.a.r. b.a.g.e.
 0070: 20 00 68 00 65 00 72 00  65 00 21 00 00 00 00 00    .h.e.r. e.!.....
@Cyanoxygen Cyanoxygen force-pushed the fix-partition-entry-chksums branch from 267cf40 to 0eb054f Compare December 15, 2025 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants