[Spice-devel] [PATCH 18/18] Make QXLMessage handling safe
Frediano Ziglio
fziglio at redhat.com
Mon Sep 26 08:12:51 UTC 2016
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/memslot.c | 14 ++++++++++++++
server/memslot.h | 3 +++
server/red-parse-qxl.c | 11 +++++++++++
server/red-parse-qxl.h | 1 +
server/red-worker.c | 3 +--
5 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/server/memslot.c b/server/memslot.c
index 99c63e4..75cb75f 100644
--- a/server/memslot.c
+++ b/server/memslot.c
@@ -71,6 +71,20 @@ int memslot_validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
return 1;
}
+unsigned long memslot_max_size_virt(RedMemSlotInfo *info,
+ unsigned long virt, int slot_id,
+ uint32_t group_id)
+{
+ MemSlot *slot;
+
+ slot = &info->mem_slots[group_id][slot_id];
+
+ if (virt < slot->virt_start_addr || virt > slot->virt_end_addr) {
+ return 0;
+ }
+ return slot->virt_end_addr - virt;
+}
+
/*
* return virtual address if successful, which may be 0.
* returns 0 and sets error to 1 if an error condition occurs.
diff --git a/server/memslot.h b/server/memslot.h
index a29837c..5046d0f 100644
--- a/server/memslot.h
+++ b/server/memslot.h
@@ -55,6 +55,9 @@ static inline int memslot_get_generation(RedMemSlotInfo *info, uint64_t addr)
int memslot_validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
uint32_t add_size, uint32_t group_id);
+unsigned long memslot_max_size_virt(RedMemSlotInfo *info,
+ unsigned long virt, int slot_id,
+ uint32_t group_id);
unsigned long memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size,
int group_id, int *error);
diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c
index d75e27e..77533ca 100644
--- a/server/red-parse-qxl.c
+++ b/server/red-parse-qxl.c
@@ -1300,6 +1300,9 @@ int red_get_message(RedMemSlotInfo *slots, int group_id,
{
QXLMessage *qxl;
int error;
+ int memslot_id;
+ unsigned long len;
+ uint8_t *end;
/*
* security alert:
@@ -1314,6 +1317,14 @@ int red_get_message(RedMemSlotInfo *slots, int group_id,
red->release_info_ext.info = &qxl->release_info;
red->release_info_ext.group_id = group_id;
red->data = qxl->data;
+ memslot_id = memslot_get_id(slots, addr+sizeof(*qxl));
+ len = memslot_max_size_virt(slots, ((intptr_t) qxl)+sizeof(*qxl), memslot_id, group_id);
+ len = MIN(len, 100000);
+ end = (uint8_t *)memchr(qxl->data, 0, len);
+ if (end == NULL) {
+ return 1;
+ }
+ red->len = end - qxl->data;
return 0;
}
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index 0da20ad..e174ccc 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -74,6 +74,7 @@ typedef struct RedUpdateCmd {
typedef struct RedMessage {
QXLReleaseInfoExt release_info_ext;
+ int len;
uint8_t *data;
} RedMessage;
diff --git a/server/red-worker.c b/server/red-worker.c
index 7c7eafe..a3a127f 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -265,8 +265,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
break;
}
#ifdef DEBUG
- /* alert: accessing message.data is insecure */
- spice_warning("MESSAGE: %s", message.data);
+ spice_warning("MESSAGE: %.*s", message.len, message.data);
#endif
red_qxl_release_resource(worker->qxl, message.release_info_ext);
red_put_message(&message);
--
2.7.4
More information about the Spice-devel
mailing list