[Bug] integer overflow in GPT entry allocation causes OOB read on 32-bit targets
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 45/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 停滞
- 技术栈
- c
- 领域
- embedded-iot, security
调研方向
从 components/drivers/block/partitions/efi.c 开始,然后检查 include/rttypes.h 中的 rt_size_t 以及 components/drivers/sdio/dev_block.c 中的 max_partitions 设置。使用所述的构造头部在 32 位目标上验证 GPT 探测;当 overflow 被拒绝且迭代不能超过已分配的 GPT 条目数时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
RT-Thread Version
master (verified on commit 6a635e32d9f39ea015824927cee492620a05212f); also present in v5.2.2, v5.2.1, and v5.2.0
Hardware Type/Architectures
Any 32-bit BSP with GPT partition probing enabled (RT_BLK_PARTITION_EFI)
Develop Toolchain
Other
Describe the bug
This issue is independent from #11259, which reports a different bug in read_lba().
A 32-bit-only memory-safety issue exists in components/drivers/block/partitions/efi.c. The GPT parser computes the allocation size for the partition
entry array using rt_size_t, which is 32-bit on 32-bit builds, but later iterates over the entry array using the original untrusted on-disk entry count.
Affected code:
/* components/drivers/block/partitions/efi.c */
count = (rt_size_t)rt_le32_to_cpu(gpt->num_partition_entries) *
rt_le32_to_cpu(gpt->sizeof_partition_entry);
pte = rt_malloc(count);
Later:
/* components/drivers/block/partitions/efi.c */
entries_nr = rt_le32_to_cpu(gpt->num_partition_entries);
for (int i = 0; i < entries_nr && i < disk->max_partitions; ++i)
{
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 (!is_pte_valid(&ptes[i], last_lba(disk)))
{
continue;
}
...
}
On 32-bit RT-Thread builds, rt_size_t is 32-bit:
/* include/rttypes.h */
#ifdef ARCH_CPU_64BIT
typedef rt_uint64_t rt_ubase_t;
#else
typedef rt_uint32_t rt_ubase_t;
#endif
...
typedef rt_ubase_t rt_size_t;
The code also later enforces:
rt_le32_to_cpu((*gpt)->sizeof_partition_entry) == sizeof(gpt_entry)
So the allocation is effectively based on:
num_partition_entries * 128
This multiplication can wrap on 32-bit targets and produce a much smaller non-zero allocation.
For example, with a crafted GPT header:
- num_partition_entries = 0x02000004
- sizeof_partition_entry = 128
the true product is 0x100000200, but the 32-bit wrapped allocation size becomes 0x200 (512 bytes), which only holds 4 GPT entries.
However, efi_partition() still trusts the original entries_nr = 0x02000004 and iterates until i < disk->max_partitions.
Many common MMC/SD block devices default to 16 partitions:
/* components/drivers/sdio/dev_block.c */
#ifndef RT_MMCSD_MAX_PARTITION
#define RT_MMCSD_MAX_PARTITION 16
#endif
...
blk_dev->parent.max_partitions = RT_MMCSD_MAX_PARTITION;
As a result, on a common 32-bit MMC/SD configuration, the parser may allocate space for only 4 entries but still read ptes[4] through ptes[15], causing an
out-of-bounds read from heap memory.
Steps to reproduce the behavior
- Build RT-Thread for a 32-bit target with GPT partition probing enabled.
- Present a crafted GPT disk image or block device to the system.
- Set sizeof_partition_entry = 128.
- Set num_partition_entries = 0x02000004.
- Trigger normal partition probing.
Expected behavior
The parser should reject GPT headers when:
- num_partition_entries * sizeof_partition_entry overflows
- the computed allocation size cannot represent the claimed number of entries
- later iteration would exceed the actually allocated entry count
Actual behavior
The allocation size wraps on 32-bit builds, but later code still indexes the GPT entry array using the original untrusted entry count, leading to out-of-
bounds reads and undefined behavior. Depending on heap layout and target configuration, this may cause crashes or cause heap data to be interpreted as fake
GPT entries.
Suggested fix
- Reject integer overflow before allocation. For example, validate:
entries_nr = rt_le32_to_cpu(gpt->num_partition_entries);
entry_size = rt_le32_to_cpu(gpt->sizeof_partition_entry);
if (entry_size != sizeof(gpt_entry) ||
entries_nr == 0 ||
entries_nr > RT_SIZE_MAX / entry_size)
{
return RT_NULL;
}
- Use the validated entry count consistently after allocation instead of reusing the raw on-disk value.
- Bound the later iteration by the number of entries actually allocated, for example:
validated_entries = count / sizeof(gpt_entry);
for (i = 0; i < validated_entries && i < disk->max_partitions; ++i)
- More generally, avoid recomputing lengths from untrusted GPT header fields after allocation unless the same overflow checks are applied again.
Kindly let me know if you intend to request a CVE ID upon confirmation of the vulnerability.
Other additional context
No response
- 主要语言
- C
- 星标
- 12.3k
- 派生
- 5.5k
- 平均合并
- 3 天 14 小时
- 30 天内合并 PR
- 22
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
RT-Thread/rt-thread 的其他 Issue
-
[Bug] [netdev] ping crashes the shell with a division by zero when the target is unreachable (received == 0)可能已有人在做 @ymj0440 于 1 天前认领。 未关闭bug Component component: net in progress
难度 1/5 1 小时以内 新手友好度 90/100
RT-Thread/rt-thread#11852 · 3 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
[bsp][stm32][bluepill] README「快速上手」缺少重新生成 MDK 工程这一步,按文档操作无法编译通过可能已有人在做 @moment-NEW 于 9 天前认领。 未关闭in progress
难度 2/5 1-3 小时 新手友好度 75/100
RT-Thread/rt-thread#11818 · 4 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
BSP BSP: Loongson bug RT-Smart
难度 2/5 1-3 小时 新手友好度 72/100
RT-Thread/rt-thread#11717 · 2 条评论 ·
维护者通常 1 天内回复
-
Arch: RISC-V BSP BSP: HPMicro bug
难度 2/5 1-3 小时 新手友好度 72/100
RT-Thread/rt-thread#11687 · 3 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
RT-Thread/rt-thread#11472 · 1 条评论 ·
维护者通常 1 天内回复
查看 RT-Thread/rt-thread 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 63/100
维护者通常 1 天内回复
-
research-radar
难度 2/5 1-3 小时 新手友好度 63/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 65/100
-
"systemctl is-system-running --wait" may hang indefinitely for non-root users可能已有人在做 @alexonea 今天认领。 未关闭bug 🐛 systemctl
难度 2/5 1-3 小时 新手友好度 66/100
维护者通常 1 天内回复
-
testing: DISK test reads the wrong directory entry offset on H89可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭
难度 2/5 1-3 小时 新手友好度 76/100
FujiNetWIFI/fujinet-lib#115 · 1 条评论 ·
维护者通常 1 天内回复