cxl/test: Verify cmd->size_in before accessing payload

Several mock mailbox handlers access input payload fields before
verifying that cmd->size_in is large enough for the corresponding
structure.

To ensure invalid commands are rejected before any payload data is
consumed, add missing size checks and move existing checks ahead of
the first payload field access.

[dj: Updated commit log per Alison's comments. ]

Fixes: 7d3eb23c4c ("tools/testing/cxl: Introduce a mock memory device + driver")
Fixes: d1dca858f0 ("cxl/test: Add generic mock events")
Fixes: f6448cb5f2 ("tools/testing/cxl: add firmware update emulation to CXL memdevs")
Fixes: e77e9c1079 ("cxl/test: Add Get Feature support to cxl_test")
Link: https://lore.kernel.org/linux-cxl/20260605143748.235271F00893@smtp.kernel.org/
Suggested-by: sashiko-bot
Tested-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
This commit is contained in:
Dave Jiang 2026-06-05 11:15:08 -07:00
parent 0e7041eb96
commit 71a1def165

View File

@ -312,12 +312,17 @@ static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd)
static int mock_clear_event(struct device *dev, struct cxl_mbox_cmd *cmd)
{
struct cxl_mbox_clear_event_payload *pl = cmd->payload_in;
struct cxl_mbox_clear_event_payload *pl;
struct mock_event_log *log;
u8 log_type = pl->event_log;
u8 log_type;
u16 handle;
int nr;
if (cmd->size_in < sizeof(*pl))
return -EINVAL;
pl = cmd->payload_in;
log_type = pl->event_log;
if (log_type >= CXL_EVENT_TYPE_MAX)
return -EINVAL;
@ -574,14 +579,19 @@ static int mock_gsl(struct cxl_mbox_cmd *cmd)
static int mock_get_log(struct cxl_memdev_state *mds, struct cxl_mbox_cmd *cmd)
{
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
struct cxl_mbox_get_log *gl = cmd->payload_in;
u32 offset = le32_to_cpu(gl->offset);
u32 length = le32_to_cpu(gl->length);
uuid_t uuid = DEFINE_CXL_CEL_UUID;
struct cxl_mbox_get_log *gl;
void *data = &mock_cel;
u32 offset;
u32 length;
if (cmd->size_in < sizeof(*gl))
return -EINVAL;
gl = cmd->payload_in;
offset = le32_to_cpu(gl->offset);
length = le32_to_cpu(gl->length);
if (length > cxl_mbox->payload_size)
return -EINVAL;
if (offset + length > sizeof(mock_cel))
@ -1336,10 +1346,14 @@ static int mock_fw_info(struct cxl_mockmem_data *mdata,
static int mock_transfer_fw(struct cxl_mockmem_data *mdata,
struct cxl_mbox_cmd *cmd)
{
struct cxl_mbox_transfer_fw *transfer = cmd->payload_in;
struct cxl_mbox_transfer_fw *transfer;
void *fw = mdata->fw;
size_t offset, length;
if (cmd->size_in < sizeof(*transfer))
return -EINVAL;
transfer = cmd->payload_in;
offset = le32_to_cpu(transfer->offset) * CXL_FW_TRANSFER_ALIGNMENT;
length = cmd->size_in - sizeof(*transfer);
if (offset + length > FW_SIZE)
@ -1415,11 +1429,18 @@ static int mock_get_test_feature(struct cxl_mockmem_data *mdata,
struct cxl_mbox_cmd *cmd)
{
struct vendor_test_feat *output = cmd->payload_out;
struct cxl_mbox_get_feat_in *input = cmd->payload_in;
u16 offset = le16_to_cpu(input->offset);
u16 count = le16_to_cpu(input->count);
struct cxl_mbox_get_feat_in *input;
u16 offset;
u16 count;
u8 *ptr;
if (cmd->size_in < sizeof(*input))
return -EINVAL;
input = cmd->payload_in;
offset = le16_to_cpu(input->offset);
count = le16_to_cpu(input->count);
if (offset > sizeof(*output)) {
cmd->return_code = CXL_MBOX_CMD_RC_INPUT;
return -EINVAL;