]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cxl/test: Verify cmd->size_in before accessing payload
authorDave Jiang <dave.jiang@intel.com>
Fri, 5 Jun 2026 18:15:08 +0000 (11:15 -0700)
committerDave Jiang <dave.jiang@intel.com>
Wed, 10 Jun 2026 17:50:35 +0000 (10:50 -0700)
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: 7d3eb23c4ccf ("tools/testing/cxl: Introduce a mock memory device + driver")
Fixes: d1dca858f058 ("cxl/test: Add generic mock events")
Fixes: f6448cb5f2f3 ("tools/testing/cxl: add firmware update emulation to CXL memdevs")
Fixes: e77e9c107978 ("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>
tools/testing/cxl/test/mem.c

index 271c7ad8cc32c9e8d74455f0037e977a85fe5c64..2e9a5f151e983dd8e56aa9000a529561fa2eebc3 100644 (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;