[PATCH] lib: sbi_mpxy: fix integer overflow in attribute range endpoint
liutong <[email protected]> Sun, 28 Jun 2026 22:27:15 +0800
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <[email protected]> |
sbi_mpxy_read_attrs() and sbi_mpxy_write_attrs() compute the attribute range endpoint as: u32 end_id = base_attr_id + attr_count - 1; When base_attr_id is close to UINT32_MAX (e.g. 0xFFFFFFFF with attr_count=2) the addition wraps around to a small value. The subsequent range check for the message protocol path compares end_id > SBI_MPXY_ATTR_MSGPROTO_ATTR_END (0xFFFFFFFF), which is always false for a u32 variable and therefore dead code. The wrapped end_id then passes through to the RPMI mailbox read callback, where attr_id2index() computes a large index (base_attr_id - 0x80000000), causing an out-of-bounds read from M-mode memory into S-mode shared memory. Fix by widening end_id to u64 before the arithmetic, consistent with the approach used in sbi_sse_attr_check(). Apply the same fix to the RPMI mailbox callbacks for defense in depth. Signed-off-by: liutong <[email protected]> --- lib/sbi/sbi_mpxy.c | 10 ++++++---- lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/sbi/sbi_mpxy.c b/lib/sbi/sbi_mpxy.c index 8daeb83d..01e7da17 100644 --- a/lib/sbi/sbi_mpxy.c +++ b/lib/sbi/sbi_mpxy.c @@ -444,7 +444,8 @@ int sbi_mpxy_read_attrs(u32 channel_id, u32 base_attr_id, u32 attr_count) { struct mpxy_state *ms = sbi_domain_mpxy_state_thishart_ptr(); int ret = SBI_SUCCESS; - u32 *attr_ptr, end_id; + u32 *attr_ptr; + u64 end_id; void *shmem_base; if (!mpxy_shmem_enabled(ms)) @@ -464,7 +465,7 @@ int sbi_mpxy_read_attrs(u32 channel_id, u32 base_attr_id, u32 attr_count) return SBI_ERR_INVALID_PARAM; shmem_base = hart_shmem_base(ms); - end_id = base_attr_id + attr_count - 1; + end_id = (u64)base_attr_id + attr_count - 1; sbi_hart_protection_map_range((unsigned long)hart_shmem_base(ms), mpxy_shmem_size); @@ -593,7 +594,8 @@ static void mpxy_write_std_attr(struct sbi_mpxy_channel *channel, u32 attr_id, int sbi_mpxy_write_attrs(u32 channel_id, u32 base_attr_id, u32 attr_count) { struct mpxy_state *ms = sbi_domain_mpxy_state_thishart_ptr(); - u32 *mem_ptr, attr_id, end_id, attr_val; + u32 *mem_ptr, attr_id, attr_val; + u64 end_id; struct sbi_mpxy_channel *channel; int ret, mem_idx; void *shmem_base; @@ -615,7 +617,7 @@ int sbi_mpxy_write_attrs(u32 channel_id, u32 base_attr_id, u32 attr_count) return SBI_ERR_INVALID_PARAM; shmem_base = hart_shmem_base(ms); - end_id = base_attr_id + attr_count - 1; + end_id = (u64)base_attr_id + attr_count - 1; sbi_hart_protection_map_range((unsigned long)shmem_base, mpxy_shmem_size); diff --git a/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c b/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c index 84b7a67d..5e27b61c 100644 --- a/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c +++ b/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c @@ -60,7 +60,7 @@ static int mpxy_mbox_read_attributes(struct sbi_mpxy_channel *channel, struct mpxy_rpmi_mbox *rmb = container_of(channel, struct mpxy_rpmi_mbox, channel); u32 *attr_array = (u32 *)&rmb->msgprot_attrs; - u32 end_id = base_attr_id + attr_count - 1; + u64 end_id = (u64)base_attr_id + attr_count - 1; if (end_id >= MPXY_MSGPROT_RPMI_ATTR_MAX_ID) return SBI_EBAD_RANGE; @@ -108,7 +108,7 @@ static int mpxy_mbox_write_attributes(struct sbi_mpxy_channel *channel, { struct mpxy_rpmi_mbox *rmb = container_of(channel, struct mpxy_rpmi_mbox, channel); - u32 end_id = base_attr_id + attr_count - 1; + u64 end_id = (u64)base_attr_id + attr_count - 1; u32 attr_val, idx; int ret, mem_idx; -- 2.34.1 -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi