[PATCH] hw/cxl: Fix heap buffer overflow in Set Feature cleanup path
Junjie Cao <[email protected]>
| Newsgroups | org.kernel.vger.linux-cxl,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
cmd_features_set_feature() uses set_feat_info->data_size as the memset
length when zeroing write-attribute buffers on Finish/Abort. data_size
accumulates bytes_to_copy across transfer parts but is only reset on
INITIATE. Since QEMU never returns Feature Transfer Out of Order,
repeated transfers at the same offset grow data_size past sizeof(struct),
and the final memset overflows the target buffer.
b71a179148 bounded the per-transfer memcpy against sizeof, but the
cleanup memset still runs on the accumulated data_size, so the overflow
survives that fix.
Pass sizeof() of the target struct to memset instead of data_size.
Fixes: d88f66741410 ("hw/cxl/cxl-mailbox-utils: Add device patrol scrub control feature")
Fixes: 2d41ce38fb9a ("hw/cxl/cxl-mailbox-utils: Add device DDR5 ECS control feature")
Fixes: 5e5a86bab830 ("hw/cxl: Add support for Maintenance command and Post Package Repair (PPR)")
Fixes: da5cafdc4ddd ("hw/cxl: Add emulation for memory sparing control feature")
Cc: [email protected]
Signed-off-by: Junjie Cao <[email protected]>
---
hw/cxl/cxl-mailbox-utils.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index ec18338b42..f81b7b3303 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -1947,22 +1947,28 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
data_transfer_flag == CXL_SET_FEATURE_FLAG_ABORT_DATA_TRANSFER) {
memset(&set_feat_info->uuid, 0, sizeof(QemuUUID));
if (qemu_uuid_is_equal(&hdr->uuid, &patrol_scrub_uuid)) {
- memset(&ct3d->patrol_scrub_wr_attrs, 0, set_feat_info->data_size);
+ memset(&ct3d->patrol_scrub_wr_attrs, 0,
+ sizeof(ct3d->patrol_scrub_wr_attrs));
} else if (qemu_uuid_is_equal(&hdr->uuid, &ecs_uuid)) {
- memset(&ct3d->ecs_wr_attrs, 0, set_feat_info->data_size);
+ memset(&ct3d->ecs_wr_attrs, 0, sizeof(ct3d->ecs_wr_attrs));
} else if (qemu_uuid_is_equal(&hdr->uuid, &soft_ppr_uuid)) {
- memset(&ct3d->soft_ppr_wr_attrs, 0, set_feat_info->data_size);
+ memset(&ct3d->soft_ppr_wr_attrs, 0,
+ sizeof(ct3d->soft_ppr_wr_attrs));
} else if (qemu_uuid_is_equal(&hdr->uuid, &hard_ppr_uuid)) {
- memset(&ct3d->hard_ppr_wr_attrs, 0, set_feat_info->data_size);
+ memset(&ct3d->hard_ppr_wr_attrs, 0,
+ sizeof(ct3d->hard_ppr_wr_attrs));
} else if (qemu_uuid_is_equal(&hdr->uuid, &cacheline_sparing_uuid)) {
memset(&ct3d->cacheline_sparing_wr_attrs, 0,
- set_feat_info->data_size);
+ sizeof(ct3d->cacheline_sparing_wr_attrs));
} else if (qemu_uuid_is_equal(&hdr->uuid, &row_sparing_uuid)) {
- memset(&ct3d->row_sparing_wr_attrs, 0, set_feat_info->data_size);
+ memset(&ct3d->row_sparing_wr_attrs, 0,
+ sizeof(ct3d->row_sparing_wr_attrs));
} else if (qemu_uuid_is_equal(&hdr->uuid, &bank_sparing_uuid)) {
- memset(&ct3d->bank_sparing_wr_attrs, 0, set_feat_info->data_size);
+ memset(&ct3d->bank_sparing_wr_attrs, 0,
+ sizeof(ct3d->bank_sparing_wr_attrs));
} else if (qemu_uuid_is_equal(&hdr->uuid, &rank_sparing_uuid)) {
- memset(&ct3d->rank_sparing_wr_attrs, 0, set_feat_info->data_size);
+ memset(&ct3d->rank_sparing_wr_attrs, 0,
+ sizeof(ct3d->rank_sparing_wr_attrs));
}
set_feat_info->data_transfer_flag = 0;
set_feat_info->data_saved_across_reset = false;
base-commit: af06b5df2610fe5de6c02d17c17bced9e9f0d47d
--
2.43.0