[PATCH] hw/cxl: Check mailbox payload length does not exceed max size

sundayjiang(蒋浩天) posted 1 patch 1 week, 5 days ago
Failed in applying to current master (apply log)
 hw/cxl/cxl-device-utils.c | 22 +++++++++++++++-------
[PATCH] hw/cxl: Check mailbox payload length does not exceed max size
Posted by sundayjiang(蒋浩天) 1 week, 5 days ago
From 66a0976944d7d415bc7ed125e7c55f52d686b52f Mon Sep 17 00:00:00 2001From: Haotian Jiang <sundayjiang@tencent.com&gt;
Date: Thu, 9 Jul 2026 11:09:11 +0800
Subject: [PATCH] hw/cxl: reject mailbox commands with payload exceeding max
&nbsp;size


mailbox_reg_write() calls g_memdup2(pl, len_in) where len_in is
taken from the CXL_DEV_MAILBOX_CMD.LENGTH field, a 20-bit value
that can specify up to ~1 MB. The payload buffer pl points into
mbox_reg_state, which has only CXL_MAILBOX_MAX_PAYLOAD_SIZE (2048)
bytes of payload space. When len_in exceeds 2048, g_memdup2 reads
past the payload area into adjacent CXLDeviceState fields,
including host heap pointers in event_logs.


A guest can combine this with SET_LSA (variable-length, in=~0) to
write the over-read data into LSA backing memory, then read it back
with GET_LSA, leaking host heap addresses to the guest. This breaks
ASLR isolation between guest and host.


Reject commands with len_in &gt; CXL_MAILBOX_MAX_PAYLOAD_SIZE by
returning CXL_MBOX_INVALID_PAYLOAD_LENGTH before calling g_memdup2.


Fixes: c9460561ed ("hw/cxl/mbox: Generalize the CCI command processing")
Reported-by: Haotian Jiang of Tencent Security (Yunding Lab) <sundayjiang@tencent.com&gt;
Signed-off-by: Haotian Jiang <sundayjiang@tencent.com&gt;
Cc: qemu-stable@nongnu.org
Link: https://gitlab.com/qemu-project/qemu/-/work_items/3967
---
&nbsp;hw/cxl/cxl-device-utils.c | 22 +++++++++++++++-------
&nbsp;1 file changed, 15 insertions(+), 7 deletions(-)


diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index e150d74457..e4825f6ad6 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -202,14 +202,22 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bool bg_started = false;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int rc;
&nbsp;
- &nbsp; &nbsp; &nbsp; &nbsp;pl_in_copy = g_memdup2(pl, len_in);
- &nbsp; &nbsp; &nbsp; &nbsp;if (len_in == 0 || pl_in_copy) {
- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* Avoid stale data &nbsp;- including from earlier cmds */
- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;memset(pl, 0, CXL_MAILBOX_MAX_PAYLOAD_SIZE);
- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rc = cxl_process_cci_message(cci, cmd_set, cmd, len_in, pl_in_copy,
- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;len_out, pl, &amp;bg_started);
+ &nbsp; &nbsp; &nbsp; &nbsp;if (len_in &gt; CXL_MAILBOX_MAX_PAYLOAD_SIZE) {
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;qemu_log_mask(LOG_GUEST_ERROR,
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"CXL mailbox: payload length %lu exceeds max %u\n",
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(unsigned long)len_in, CXL_MAILBOX_MAX_PAYLOAD_SIZE);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rc = CXL_MBOX_INVALID_PAYLOAD_LENGTH;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} else {
- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rc = CXL_MBOX_INTERNAL_ERROR;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pl_in_copy = g_memdup2(pl, len_in);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (len_in == 0 || pl_in_copy) {
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* Avoid stale data &nbsp;- including from earlier cmds */
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;memset(pl, 0, CXL_MAILBOX_MAX_PAYLOAD_SIZE);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rc = cxl_process_cci_message(cci, cmd_set, cmd, len_in,
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pl_in_copy, &amp;len_out, pl,
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;bg_started);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} else {
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rc = CXL_MBOX_INTERNAL_ERROR;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* Set bg and the return code */
-- 
2.34.1