RT-Thread Version
master (verified on commit 2b58dec87b584aa7ded6e8c736498716f8d29cd0)
Hardware Type/Architectures
any BSP using the new block partition probing path with EFI/GPT enabled
Develop Toolchain
GCC
Describe the bug
GPT Partition Entry Underflow in RT-Thread EFI/GPT Parser
Affected Components
| Field |
Detail |
| File 1 |
components/drivers/block/partitions/efi.c |
| File 2 |
components/drivers/block/blk_partition.c |
| Function 1 |
rt_inline rt_bool_t is_pte_valid(const gpt_entry *pte, const rt_size_t lastlba) |
| Function 2 |
rt_err_t efi_partition(struct rt_blk_disk *disk) |
| Function 3 |
rt_err_t blk_put_partition(struct rt_blk_disk *disk, const char *type, rt_size_t start, rt_size_t count, int partno) |
Vulnerability Details
1. GPT entries accepted without checking ending_lba >= starting_lba
In efi.c, GPT entries are considered valid by is_pte_valid() if:
partition_type_guid is not NULL_GUID
starting_lba <= lastlba
ending_lba <= lastlba
Current code:
rt_inline rt_bool_t is_pte_valid(const gpt_entry *pte, const rt_size_t lastlba)
{
if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) ||
rt_le64_to_cpu(pte->starting_lba) > lastlba ||
rt_le64_to_cpu(pte->ending_lba) > lastlba)
{
return RT_FALSE;
}
return RT_TRUE;
}
There is no check that ending_lba >= starting_lba. So a malformed GPT entry with:
starting_lba inside disk bounds
ending_lba inside disk bounds
- but
ending_lba < starting_lba
is still accepted as valid.
2. Partition size calculation underflows
efi_partition() computes the partition length as:
rt_uint64_t start = rt_le64_to_cpu(ptes[i].starting_lba);
rt_uint64_t size = rt_le64_to_cpu(ptes[i].ending_lba) -
rt_le64_to_cpu(ptes[i].starting_lba) + 1ULL;
If ending_lba < starting_lba, the subtraction underflows in unsigned arithmetic and produces a very large wrapped size.
That underflowed size is then passed to blk_put_partition():
blk_put_partition(disk, "gpt", start, size, i)
and stored into the logical partition device:
blk->sector_start = start;
blk->sector_count = count;
blk->partition.offset = start;
blk->partition.size = count;
As a result, a malformed GPT entry can create a logical partition object with an attacker-controlled start and a huge wrapped size.
Trigger Condition
The bug is reached during normal GPT partition probing:
rt_blk_disk_probe_partition()
-> efi_partition()
-> find_valid_gpt()
-> iterate GPT entries
-> is_pte_valid()
-> size = ending_lba - starting_lba + 1ULL
-> blk_put_partition(...)
No local code changes are required. A crafted GPT image with valid headers/CRCs and a malformed partition entry is sufficient.
ℹ️ This appears to be distinct from the already reported GPT allocation bug in #11260.
Proof of Concept
A PoC can be implemented with a crafted GPT disk image used by any block backend that reaches rt_blk_disk_probe_partition().
PoC Shape
Create a disk image with:
- A valid PMBR
- A valid primary GPT header
- A valid GPT entry array CRC
- At least one GPT partition entry satisfying:
partition_type_guid != NULL_GUID
starting_lba <= lastlba
ending_lba <= lastlba
ending_lba < starting_lba
For example:
starting_lba = 0x1000
ending_lba = 0x0FFF
Both fields are inside disk bounds, but the end is before the start.
Expected Result
During partition probing:
is_pte_valid() accepts the entry
efi_partition() computes:
size = 0x0FFF - 0x1000 + 1
which underflows to a huge rt_uint64_t value.
blk_put_partition() registers a logical partition with that wrapped size.
Minimal Reproduction Steps
- Enable the new block partition probing path with EFI/GPT support.
- Supply the crafted GPT image through any disk backend.
- Trigger
rt_blk_disk_probe_partition().
- Observe that the malformed partition is accepted and a partition with a huge wrapped size is created.
Impact
The immediate impact is that malformed GPT metadata can create an invalid logical partition with a huge sector count. This can break the partition abstraction and may enable later incorrect reads/writes, boundary confusion, or other follow-on faults in code that trusts the partition object's stored geometry.
So even though the trigger is a malformed GPT image, the root cause is a missing semantic validity check in the parser.
Upstream / Downstream Impact
Upstream
Verified on current master in the new block EFI/GPT parser implementation.
Downstream
Any downstream product based on current master that includes the new block partition subsystem and parses untrusted or externally supplied GPT media/images may be affected.
Suggested Fix
Reject GPT entries where the end LBA is before the start LBA:
rt_inline rt_bool_t is_pte_valid(const gpt_entry *pte, const rt_size_t lastlba)
{
rt_uint64_t start = rt_le64_to_cpu(pte->starting_lba);
rt_uint64_t end = rt_le64_to_cpu(pte->ending_lba);
if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) ||
start > lastlba ||
end > lastlba ||
end < start)
{
return RT_FALSE;
}
return RT_TRUE;
}
Optionally, efi_partition() may also defensively re-check the relation before computing size = end - start + 1ULL, to avoid similar bugs if future validation changes.
Kindly let me know if you intend to request a CVE ID upon confirmation of the vulnerability.
Other additional context
No response
RT-Thread Version
master (verified on commit
2b58dec87b584aa7ded6e8c736498716f8d29cd0)Hardware Type/Architectures
any BSP using the new block partition probing path with EFI/GPT enabled
Develop Toolchain
GCC
Describe the bug
GPT Partition Entry Underflow in RT-Thread EFI/GPT Parser
Affected Components
components/drivers/block/partitions/efi.ccomponents/drivers/block/blk_partition.crt_inline rt_bool_t is_pte_valid(const gpt_entry *pte, const rt_size_t lastlba)rt_err_t efi_partition(struct rt_blk_disk *disk)rt_err_t blk_put_partition(struct rt_blk_disk *disk, const char *type, rt_size_t start, rt_size_t count, int partno)Vulnerability Details
1. GPT entries accepted without checking
ending_lba >= starting_lbaIn
efi.c, GPT entries are considered valid byis_pte_valid()if:partition_type_guidis notNULL_GUIDstarting_lba <= lastlbaending_lba <= lastlbaCurrent code:
There is no check that
ending_lba >= starting_lba. So a malformed GPT entry with:starting_lbainside disk boundsending_lbainside disk boundsending_lba < starting_lbais still accepted as valid.
2. Partition size calculation underflows
efi_partition()computes the partition length as:If
ending_lba < starting_lba, the subtraction underflows in unsigned arithmetic and produces a very large wrapped size.That underflowed size is then passed to
blk_put_partition():and stored into the logical partition device:
As a result, a malformed GPT entry can create a logical partition object with an attacker-controlled start and a huge wrapped size.
Trigger Condition
The bug is reached during normal GPT partition probing:
No local code changes are required. A crafted GPT image with valid headers/CRCs and a malformed partition entry is sufficient.
Proof of Concept
A PoC can be implemented with a crafted GPT disk image used by any block backend that reaches
rt_blk_disk_probe_partition().PoC Shape
Create a disk image with:
partition_type_guid != NULL_GUIDstarting_lba <= lastlbaending_lba <= lastlbaending_lba < starting_lbaFor example:
Both fields are inside disk bounds, but the end is before the start.
Expected Result
During partition probing:
is_pte_valid()accepts the entryefi_partition()computes:which underflows to a huge
rt_uint64_tvalue.blk_put_partition()registers a logical partition with that wrapped size.Minimal Reproduction Steps
rt_blk_disk_probe_partition().Impact
The immediate impact is that malformed GPT metadata can create an invalid logical partition with a huge sector count. This can break the partition abstraction and may enable later incorrect reads/writes, boundary confusion, or other follow-on faults in code that trusts the partition object's stored geometry.
So even though the trigger is a malformed GPT image, the root cause is a missing semantic validity check in the parser.
Upstream / Downstream Impact
Upstream
Verified on current
masterin the new block EFI/GPT parser implementation.Downstream
Any downstream product based on current
masterthat includes the new block partition subsystem and parses untrusted or externally supplied GPT media/images may be affected.Suggested Fix
Reject GPT entries where the end LBA is before the start LBA:
Optionally,
efi_partition()may also defensively re-check the relation before computingsize = end - start + 1ULL, to avoid similar bugs if future validation changes.Kindly let me know if you intend to request a CVE ID upon confirmation of the vulnerability.
Other additional context
No response