[PATCH] lib: sbi_mpxy: fix integer overflow in attribute range endpoint

liutong liutong at iscas.ac.cn
Sun Jun 28 07:27:15 PDT 2026


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 <liutong at iscas.ac.cn>
---
 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




More information about the opensbi mailing list