diff --git a/Makefile b/Makefile index cdcc410..a2c9e66 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ RELEASE=4.0 PACKAGE=pve-libspice-server1 -PKGVERSION=0.12.5 -PKGRELEASE=2 +PKGVERSION=0.12.8 +PKGRELEASE=1 PKGDIR=spice-${PKGVERSION} PKGSRC=${PKGDIR}.tar.bz2 @@ -40,15 +40,7 @@ download: .PHONY: upload upload: ${DEBS} - umount /pve/${RELEASE}; mount /pve/${RELEASE} -o rw - mkdir -p /pve/${RELEASE}/extra - rm -f /pve/${RELEASE}/extra/Packages* - rm -f /pve/${RELEASE}/extra/pve-libspice-server1_*.deb - rm -f /pve/${RELEASE}/extra/pve-libspice-server-dev_*.deb - rm -f /pve/${RELEASE}/extra/pve-libspice-server1_*.deb - cp ${DEBS} /pve/${RELEASE}/extra - cd /pve/${RELEASE}/extra; dpkg-scanpackages . /dev/null > Packages; gzip -9c Packages > Packages.gz - umount /pve/${RELEASE}; mount /pve/${RELEASE} -o ro + tar cf - ${DEBS}|ssh repoman@repo.proxmox.com upload distclean: clean diff --git a/debian/changelog b/debian/changelog index eef21d0..b44ea46 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +pve-libspice-server (0.12.8-1) unstable; urgency=medium + + * update to 0.12.8 (Fix CVE-2016-0749, CVE-2016-2150) + + -- Proxmox Support Team Thu, 14 Jul 2016 06:35:24 +0200 + pve-libspice-server (0.12.5-2) unstable; urgency=medium * fix CVE-2015-3247, CVE-2015-5260, CVE-2015-5261 diff --git a/debian/patches/CVE-2015-3247.patch b/debian/patches/CVE-2015-3247.patch deleted file mode 100644 index 9c1014c..0000000 --- a/debian/patches/CVE-2015-3247.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 524eef10c6c6c2f3f30be28c56b8f96adc7901f0 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 9 Jun 2015 08:50:46 +0100 -Subject: [PATCH] Avoid race conditions reading monitor configs from guest - -For security reasons do not assume guest do not change structures it -pass to Qemu. -Guest could change count field while Qemu is copying QXLMonitorsConfig -structure leading to heap corruption. -This patch avoid it reading count only once. - -Signed-off-by: Frediano Ziglio ---- - server/red_worker.c | 46 ++++++++++++++++++++++++++++++++-------------- - 1 file changed, 32 insertions(+), 14 deletions(-) - ---- a/server/red_worker.c -+++ b/server/red_worker.c -@@ -11051,7 +11051,8 @@ static inline void red_monitors_config_i - } - - static void worker_update_monitors_config(RedWorker *worker, -- QXLMonitorsConfig *dev_monitors_config) -+ QXLMonitorsConfig *dev_monitors_config, -+ uint16_t count, uint16_t max_allowed) - { - int heads_size; - MonitorsConfig *monitors_config; -@@ -11060,22 +11061,22 @@ static void worker_update_monitors_confi - monitors_config_decref(worker->monitors_config); - - spice_debug("monitors config %d(%d)", -- dev_monitors_config->count, -- dev_monitors_config->max_allowed); -- for (i = 0; i < dev_monitors_config->count; i++) { -+ count, -+ max_allowed); -+ for (i = 0; i < count; i++) { - spice_debug("+%d+%d %dx%d", - dev_monitors_config->heads[i].x, - dev_monitors_config->heads[i].y, - dev_monitors_config->heads[i].width, - dev_monitors_config->heads[i].height); - } -- heads_size = dev_monitors_config->count * sizeof(QXLHead); -+ heads_size = count * sizeof(QXLHead); - worker->monitors_config = monitors_config = - spice_malloc(sizeof(*monitors_config) + heads_size); - monitors_config->refs = 1; - monitors_config->worker = worker; -- monitors_config->count = dev_monitors_config->count; -- monitors_config->max_allowed = dev_monitors_config->max_allowed; -+ monitors_config->count = count; -+ monitors_config->max_allowed = max_allowed; - memcpy(monitors_config->heads, dev_monitors_config->heads, heads_size); - } - -@@ -11459,33 +11460,50 @@ void handle_dev_display_migrate(void *op - red_migrate_display(worker, rcc); - } - -+static inline uint32_t qxl_monitors_config_size(uint32_t heads) -+{ -+ return sizeof(QXLMonitorsConfig) + sizeof(QXLHead) * heads; -+} -+ - static void handle_dev_monitors_config_async(void *opaque, void *payload) - { - RedWorkerMessageMonitorsConfigAsync *msg = payload; - RedWorker *worker = opaque; -- int min_size = sizeof(QXLMonitorsConfig) + sizeof(QXLHead); - int error; -+ uint16_t count, max_allowed; - QXLMonitorsConfig *dev_monitors_config = - (QXLMonitorsConfig*)get_virt(&worker->mem_slots, msg->monitors_config, -- min_size, msg->group_id, &error); -+ qxl_monitors_config_size(1), -+ msg->group_id, &error); - - if (error) { - /* TODO: raise guest bug (requires added QXL interface) */ - return; - } - worker->driver_cap_monitors_config = 1; -- if (dev_monitors_config->count == 0) { -+ count = dev_monitors_config->count; -+ max_allowed = dev_monitors_config->max_allowed; -+ if (count == 0) { - spice_warning("ignoring an empty monitors config message from driver"); - return; - } -- if (dev_monitors_config->count > dev_monitors_config->max_allowed) { -+ if (count > max_allowed) { - spice_warning("ignoring malformed monitors_config from driver, " - "count > max_allowed %d > %d", -- dev_monitors_config->count, -- dev_monitors_config->max_allowed); -+ count, -+ max_allowed); -+ return; -+ } -+ /* get pointer again to check virtual size */ -+ dev_monitors_config = -+ (QXLMonitorsConfig*)get_virt(&worker->mem_slots, msg->monitors_config, -+ qxl_monitors_config_size(count), -+ msg->group_id, &error); -+ if (error) { -+ /* TODO: raise guest bug (requires added QXL interface) */ - return; - } -- worker_update_monitors_config(worker, dev_monitors_config); -+ worker_update_monitors_config(worker, dev_monitors_config, count, max_allowed); - red_worker_push_monitors_config(worker); - } - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0001-worker-validate-correctly-surfaces.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0001-worker-validate-correctly-surfaces.patch deleted file mode 100644 index 4dea5a2..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0001-worker-validate-correctly-surfaces.patch +++ /dev/null @@ -1,117 +0,0 @@ -From dd558bb833254fb49069eca052b92ae1abe3e8ff Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Wed, 9 Sep 2015 12:42:09 +0100 -Subject: [PATCH 01/19] worker: validate correctly surfaces - -Do not just give warning and continue to use an invalid index into -an array. - -Resolves: CVE-2015-5260 - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_worker.c | 33 ++++++++++++++++++--------------- - 1 file changed, 18 insertions(+), 15 deletions(-) - ---- a/server/red_worker.c -+++ b/server/red_worker.c -@@ -1036,6 +1036,7 @@ typedef struct BitmapData { - SpiceRect lossy_rect; - } BitmapData; - -+static inline int validate_surface(RedWorker *worker, uint32_t surface_id); - static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable); - static void red_current_flush(RedWorker *worker, int surface_id); - #ifdef DRAW_ALL -@@ -1245,14 +1246,12 @@ static inline int is_primary_surface(Red - return FALSE; - } - --static inline void __validate_surface(RedWorker *worker, uint32_t surface_id) --{ -- spice_warn_if(surface_id >= worker->n_surfaces); --} -- - static inline int validate_surface(RedWorker *worker, uint32_t surface_id) - { -- spice_warn_if(surface_id >= worker->n_surfaces); -+ if SPICE_UNLIKELY(surface_id >= worker->n_surfaces) { -+ spice_warning("invalid surface_id %u", surface_id); -+ return 0; -+ } - if (!worker->surfaces[surface_id].context.canvas) { - spice_warning("canvas address is %p for %d (and is NULL)\n", - &(worker->surfaces[surface_id].context.canvas), surface_id); -@@ -4230,12 +4229,14 @@ static inline void red_create_surface(Re - static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface, - uint32_t group_id, int loadvm) - { -- int surface_id; -+ uint32_t surface_id; - RedSurface *red_surface; - uint8_t *data; - - surface_id = surface->surface_id; -- __validate_surface(worker, surface_id); -+ if SPICE_UNLIKELY(surface_id >= worker->n_surfaces) { -+ goto exit; -+ } - - red_surface = &worker->surfaces[surface_id]; - -@@ -4271,6 +4272,7 @@ static inline void red_process_surface(R - default: - spice_error("unknown surface command"); - }; -+exit: - red_put_surface_cmd(surface); - free(surface); - } -@@ -10865,7 +10867,7 @@ void handle_dev_update(void *opaque, voi - { - RedWorker *worker = opaque; - RedWorkerMessageUpdate *msg = payload; -- SpiceRect *rect = spice_new0(SpiceRect, 1); -+ SpiceRect *rect; - RedSurface *surface; - uint32_t surface_id = msg->surface_id; - const QXLRect *qxl_area = msg->qxl_area; -@@ -10873,17 +10875,16 @@ void handle_dev_update(void *opaque, voi - QXLRect *qxl_dirty_rects = msg->qxl_dirty_rects; - uint32_t clear_dirty_region = msg->clear_dirty_region; - -+ VALIDATE_SURFACE_RET(worker, surface_id); -+ -+ rect = spice_new0(SpiceRect, 1); - surface = &worker->surfaces[surface_id]; - red_get_rect_ptr(rect, qxl_area); - flush_display_commands(worker); - - spice_assert(worker->running); - -- if (validate_surface(worker, surface_id)) { -- red_update_area(worker, rect, surface_id); -- } else { -- rendering_incorrect(__func__); -- } -+ red_update_area(worker, rect, surface_id); - free(rect); - - surface_dirty_region_to_rects(surface, qxl_dirty_rects, num_dirty_rects, -@@ -10922,6 +10923,7 @@ void handle_dev_del_memslot(void *opaque - * surface_id == 0, maybe move the assert upward and merge the two functions? */ - static inline void destroy_surface_wait(RedWorker *worker, int surface_id) - { -+ VALIDATE_SURFACE_RET(worker, surface_id); - if (!worker->surfaces[surface_id].context.canvas) { - return; - } -@@ -11186,6 +11188,7 @@ void handle_dev_create_primary_surface(v - - static void dev_destroy_primary_surface(RedWorker *worker, uint32_t surface_id) - { -+ VALIDATE_SURFACE_RET(worker, surface_id); - spice_warn_if(surface_id != 0); - - spice_debug(NULL); diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0002-worker-avoid-double-free-or-double-create-of-surface.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0002-worker-avoid-double-free-or-double-create-of-surface.patch deleted file mode 100644 index 09199f4..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0002-worker-avoid-double-free-or-double-create-of-surface.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 097c638b121e595d9daf79285c447088027a58e2 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Wed, 9 Sep 2015 12:45:06 +0100 -Subject: [PATCH 02/19] worker: avoid double free or double create of surfaces - -A driver can overwrite surface state creating a surface with the same -id of a previous one. -Also can try to destroy surfaces that are not created. -Both requests cause invalid internal states that could lead to crashes -or memory corruptions. - -Signed-off-by: Frediano Ziglio ---- - server/red_worker.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/server/red_worker.c -+++ b/server/red_worker.c -@@ -4246,6 +4246,10 @@ static inline void red_process_surface(R - int32_t stride = surface->u.surface_create.stride; - int reloaded_surface = loadvm || (surface->flags & QXL_SURF_FLAG_KEEP_DATA); - -+ if (red_surface->refs) { -+ spice_warning("avoiding creating a surface twice"); -+ break; -+ } - data = surface->u.surface_create.data; - if (stride < 0) { - data -= (int32_t)(stride * (height - 1)); -@@ -4259,7 +4263,10 @@ static inline void red_process_surface(R - break; - } - case QXL_SURFACE_CMD_DESTROY: -- spice_warn_if(!red_surface->context.canvas); -+ if (!red_surface->refs) { -+ spice_warning("avoiding destroying a surface twice"); -+ break; -+ } - set_surface_release_info(worker, surface_id, 0, surface->release_info, group_id); - red_handle_depends_on_target_surface(worker, surface_id); - /* note that red_handle_depends_on_target_surface must be called before red_current_clear. diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0003-Define-a-constant-to-limit-data-from-guest.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0003-Define-a-constant-to-limit-data-from-guest.patch deleted file mode 100644 index 2f4bd0f..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0003-Define-a-constant-to-limit-data-from-guest.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0205a6ce63f50af9eda03f14d93b3a2517c42fae Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 11:58:11 +0100 -Subject: [PATCH 03/19] Define a constant to limit data from guest. - -This limit will prevent guest trying to do nasty things and DoS to host. - -Signed-off-by: Frediano Ziglio ---- - server/red_parse_qxl.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index 5b1befa..3ffa57b 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -21,11 +21,22 @@ - - #include - #include -+#include - #include "common/lz_common.h" - #include "red_common.h" - #include "red_memslots.h" - #include "red_parse_qxl.h" - -+/* Max size in bytes for any data field used in a QXL command. -+ * This will for example be useful to prevent the guest from saturating the -+ * host memory if it tries to send overlapping chunks. -+ * This value should be big enough for all requests but limited -+ * to 32 bits. Even better if it fits on 31 bits to detect integer overflows. -+ */ -+#define MAX_DATA_CHUNK 0x7ffffffflu -+ -+G_STATIC_ASSERT(MAX_DATA_CHUNK <= G_MAXINT32); -+ - #if 0 - static void hexdump_qxl(RedMemSlotInfo *slots, int group_id, - QXLPHYSICAL addr, uint8_t bytes) --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0004-Fix-some-integer-overflow-causing-large-memory-alloc.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0004-Fix-some-integer-overflow-causing-large-memory-alloc.patch deleted file mode 100644 index 0d481a4..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0004-Fix-some-integer-overflow-causing-large-memory-alloc.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ac5f64a80ae637742ed95fd6c98f66281b3e15c6 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Thu, 17 Sep 2015 15:00:22 +0100 -Subject: [PATCH 04/19] Fix some integer overflow causing large memory - allocations - -Prevent integer overflow when computing image sizes. -Image index computations are done using 32 bit so this can cause easily -security issues. MAX_DATA_CHUNK is larger than the virtual -card limit, so this is not going to cause change in behaviours. -Comparing size calculation results with MAX_DATA_CHUNK will allow us to -catch overflows. -Prevent guest from allocating large amount of memory. - -Signed-off-by: Frediano Ziglio ---- - server/red_parse_qxl.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -384,7 +384,7 @@ static SpiceImage *red_get_image(RedMemS - QXLImage *qxl; - SpiceImage *red = NULL; - SpicePalette *rp = NULL; -- size_t bitmap_size, size; -+ uint64_t bitmap_size, size; - uint8_t qxl_flags; - int error; - -@@ -460,7 +460,10 @@ static SpiceImage *red_get_image(RedMemS - red->u.bitmap.palette = rp; - red->u.bitmap.palette_id = rp->unique; - } -- bitmap_size = red->u.bitmap.y * abs(red->u.bitmap.stride); -+ bitmap_size = (uint64_t) red->u.bitmap.y * abs(red->u.bitmap.stride); -+ if (bitmap_size > MAX_DATA_CHUNK) { -+ goto error; -+ } - if (qxl_flags & QXL_BITMAP_DIRECT) { - red->u.bitmap.data = red_get_image_data_flat(slots, group_id, - qxl->bitmap.data, -@@ -1221,7 +1224,7 @@ int red_get_surface_cmd(RedMemSlotInfo * - RedSurfaceCmd *red, QXLPHYSICAL addr) - { - QXLSurfaceCmd *qxl; -- size_t size; -+ uint64_t size; - int error; - - qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id, -@@ -1241,7 +1244,11 @@ int red_get_surface_cmd(RedMemSlotInfo * - red->u.surface_create.width = qxl->u.surface_create.width; - red->u.surface_create.height = qxl->u.surface_create.height; - red->u.surface_create.stride = qxl->u.surface_create.stride; -- size = red->u.surface_create.height * abs(red->u.surface_create.stride); -+ /* the multiplication can overflow, also abs(-2^31) may return a negative value */ -+ size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride); -+ if (size > MAX_DATA_CHUNK || red->u.surface_create.stride == G_MININT32) { -+ return 1; -+ } - red->u.surface_create.data = - (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id, &error); - if (error) { diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0005-Check-properly-surface-to-be-created.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0005-Check-properly-surface-to-be-created.patch deleted file mode 100644 index 2e0ae6c..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0005-Check-properly-surface-to-be-created.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 1eb93baa3c594e1214b1c92bbad8a06e9c7e2d12 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 16:02:59 +0100 -Subject: [PATCH 05/19] Check properly surface to be created - -Check format is valid. -Check stride is at least the size of required bytes for a row. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 35 ++++++++++++++++++++++++++++++++++- - 1 file changed, 34 insertions(+), 1 deletion(-) - ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -1220,12 +1220,30 @@ void red_put_message(RedMessage *red) - /* nothing yet */ - } - -+static unsigned int surface_format_to_bpp(uint32_t format) -+{ -+ switch (format) { -+ case SPICE_SURFACE_FMT_1_A: -+ return 1; -+ case SPICE_SURFACE_FMT_8_A: -+ return 8; -+ case SPICE_SURFACE_FMT_16_555: -+ case SPICE_SURFACE_FMT_16_565: -+ return 16; -+ case SPICE_SURFACE_FMT_32_xRGB: -+ case SPICE_SURFACE_FMT_32_ARGB: -+ return 32; -+ } -+ return 0; -+} -+ - int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id, - RedSurfaceCmd *red, QXLPHYSICAL addr) - { - QXLSurfaceCmd *qxl; - uint64_t size; - int error; -+ unsigned int bpp; - - qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id, - &error); -@@ -1244,9 +1262,24 @@ int red_get_surface_cmd(RedMemSlotInfo * - red->u.surface_create.width = qxl->u.surface_create.width; - red->u.surface_create.height = qxl->u.surface_create.height; - red->u.surface_create.stride = qxl->u.surface_create.stride; -+ bpp = surface_format_to_bpp(red->u.surface_create.format); -+ -+ /* check if format is valid */ -+ if (!bpp) { -+ return 1; -+ } -+ -+ /* check stride is larger than required bytes */ -+ size = ((uint64_t) red->u.surface_create.width * bpp + 7u) / 8u; -+ /* the uint32_t conversion is here to avoid problems with -2^31 value */ -+ if (red->u.surface_create.stride == G_MININT32 -+ || size > (uint32_t) abs(red->u.surface_create.stride)) { -+ return 1; -+ } -+ - /* the multiplication can overflow, also abs(-2^31) may return a negative value */ - size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride); -- if (size > MAX_DATA_CHUNK || red->u.surface_create.stride == G_MININT32) { -+ if (size > MAX_DATA_CHUNK) { - return 1; - } - red->u.surface_create.data = diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0006-Fix-buffer-reading-overflow.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0006-Fix-buffer-reading-overflow.patch deleted file mode 100644 index c07eab2..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0006-Fix-buffer-reading-overflow.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 68a742aaa8d692940ac15d021799b702412887e5 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 10:00:37 +0100 -Subject: [PATCH 06/19] Fix buffer reading overflow - -Not security risk as just for read. -However, this could be used to attempt integer overflows in the -following lines. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index bdd5917..e2f95e4 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -361,7 +361,14 @@ static const int MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[] = {0, 1, 1, 4, 4, 8, 16, 24, - - static int bitmap_consistent(SpiceBitmap *bitmap) - { -- int bpp = MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[bitmap->format]; -+ int bpp; -+ -+ if (bitmap->format >= SPICE_N_ELEMENTS(MAP_BITMAP_FMT_TO_BITS_PER_PIXEL)) { -+ spice_warning("wrong format specified for image\n"); -+ return FALSE; -+ } -+ -+ bpp = MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[bitmap->format]; - - if (bitmap->stride < ((bitmap->x * bpp + 7) / 8)) { - spice_warning("image stride too small for width: %d < ((%d * %d + 7) / 8) (%s=%d)\n", --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0007-Prevent-32-bit-integer-overflow-in-bitmap_consistent.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0007-Prevent-32-bit-integer-overflow-in-bitmap_consistent.patch deleted file mode 100644 index cbe6029..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0007-Prevent-32-bit-integer-overflow-in-bitmap_consistent.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0f58e9da56e0cbbe4349eefcbb300b6f285e0423 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 13:09:35 +0100 -Subject: [PATCH 07/19] Prevent 32 bit integer overflow in bitmap_consistent - -The overflow may lead to buffer overflow as the row size computed from -width (bitmap->x) can be bigger than the size in bytes (bitmap->stride). -This can make spice-server accept the invalid sizes. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index e2f95e4..40c1c99 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -357,11 +357,12 @@ static const char *bitmap_format_to_string(int format) - return "unknown"; - } - --static const int MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[] = {0, 1, 1, 4, 4, 8, 16, 24, 32, 32, 8}; -+static const unsigned int MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[] = -+ {0, 1, 1, 4, 4, 8, 16, 24, 32, 32, 8}; - - static int bitmap_consistent(SpiceBitmap *bitmap) - { -- int bpp; -+ unsigned int bpp; - - if (bitmap->format >= SPICE_N_ELEMENTS(MAP_BITMAP_FMT_TO_BITS_PER_PIXEL)) { - spice_warning("wrong format specified for image\n"); -@@ -370,7 +371,7 @@ static int bitmap_consistent(SpiceBitmap *bitmap) - - bpp = MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[bitmap->format]; - -- if (bitmap->stride < ((bitmap->x * bpp + 7) / 8)) { -+ if (bitmap->stride < (((uint64_t) bitmap->x * bpp + 7u) / 8u)) { - spice_warning("image stride too small for width: %d < ((%d * %d + 7) / 8) (%s=%d)\n", - bitmap->stride, bitmap->x, bpp, - bitmap_format_to_string(bitmap->format), --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0008-Fix-race-condition-on-red_get_clip_rects.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0008-Fix-race-condition-on-red_get_clip_rects.patch deleted file mode 100644 index 9f8a763..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0008-Fix-race-condition-on-red_get_clip_rects.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 3dfd1a08286d524a742d51952595fcfb6f0c6f1b Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 10:01:51 +0100 -Subject: [PATCH 08/19] Fix race condition on red_get_clip_rects - -Do not read multiple time an array size that can be changed. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index 40c1c99..a9f3ca1 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -273,6 +273,7 @@ static SpiceClipRects *red_get_clip_rects(RedMemSlotInfo *slots, int group_id, - size_t size; - int i; - int error; -+ uint32_t num_rects; - - qxl = (QXLClipRects *)get_virt(slots, addr, sizeof(*qxl), group_id, &error); - if (error) { -@@ -284,9 +285,10 @@ static SpiceClipRects *red_get_clip_rects(RedMemSlotInfo *slots, int group_id, - data = red_linearize_chunk(&chunks, size, &free_data); - red_put_data_chunks(&chunks); - -- spice_assert(qxl->num_rects * sizeof(QXLRect) == size); -- red = spice_malloc(sizeof(*red) + qxl->num_rects * sizeof(SpiceRect)); -- red->num_rects = qxl->num_rects; -+ num_rects = qxl->num_rects; -+ spice_assert(num_rects * sizeof(QXLRect) == size); -+ red = spice_malloc(sizeof(*red) + num_rects * sizeof(SpiceRect)); -+ red->num_rects = num_rects; - - start = (QXLRect*)data; - for (i = 0; i < red->num_rects; i++) { --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0009-Fix-race-in-red_get_image.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0009-Fix-race-in-red_get_image.patch deleted file mode 100644 index 370c0cd..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0009-Fix-race-in-red_get_image.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 9235c84e0fbbf5c19305e82fc1607393b35b74ef Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 10:04:10 +0100 -Subject: [PATCH 09/19] Fix race in red_get_image - -Do not read multiple times data from guest as this could be changed -by other vcpu threads. -This causes races and security problems if these data are used for -buffer allocation or checks. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -397,6 +397,7 @@ static SpiceImage *red_get_image(RedMemS - uint64_t bitmap_size, size; - uint8_t qxl_flags; - int error; -+ QXLPHYSICAL palette; - - if (addr == 0) { - return NULL; -@@ -422,12 +423,16 @@ static SpiceImage *red_get_image(RedMemS - switch (red->descriptor.type) { - case SPICE_IMAGE_TYPE_BITMAP: - red->u.bitmap.format = qxl->bitmap.format; -- if (!bitmap_fmt_is_rgb(qxl->bitmap.format) && !qxl->bitmap.palette && !is_mask) { -+ red->u.bitmap.x = qxl->bitmap.x; -+ red->u.bitmap.y = qxl->bitmap.y; -+ red->u.bitmap.stride = qxl->bitmap.stride; -+ palette = qxl->bitmap.palette; -+ if (!bitmap_fmt_is_rgb(red->u.bitmap.format) && !palette && !is_mask) { - spice_warning("guest error: missing palette on bitmap format=%d\n", - red->u.bitmap.format); - goto error; - } -- if (qxl->bitmap.x == 0 || qxl->bitmap.y == 0) { -+ if (red->u.bitmap.x == 0 || red->u.bitmap.y == 0) { - spice_warning("guest error: zero area bitmap\n"); - goto error; - } -@@ -435,23 +440,20 @@ static SpiceImage *red_get_image(RedMemS - if (qxl_flags & QXL_BITMAP_TOP_DOWN) { - red->u.bitmap.flags = SPICE_BITMAP_FLAGS_TOP_DOWN; - } -- red->u.bitmap.x = qxl->bitmap.x; -- red->u.bitmap.y = qxl->bitmap.y; -- red->u.bitmap.stride = qxl->bitmap.stride; - if (!bitmap_consistent(&red->u.bitmap)) { - goto error; - } -- if (qxl->bitmap.palette) { -+ if (palette) { - QXLPalette *qp; - int i, num_ents; -- qp = (QXLPalette *)get_virt(slots, qxl->bitmap.palette, -+ qp = (QXLPalette *)get_virt(slots, palette, - sizeof(*qp), group_id, &error); - if (error) { - goto error; - } - num_ents = qp->num_ents; - if (!validate_virt(slots, (intptr_t)qp->ents, -- get_memslot_id(slots, qxl->bitmap.palette), -+ get_memslot_id(slots, palette), - num_ents * sizeof(qp->ents[0]), group_id)) { - goto error; - } diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0010-Fix-race-condition-in-red_get_string.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0010-Fix-race-condition-in-red_get_string.patch deleted file mode 100644 index fa6e9cc..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0010-Fix-race-condition-in-red_get_string.patch +++ /dev/null @@ -1,57 +0,0 @@ -From dfaedec7890069b35f513e4a8ab4071ca54259ff Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 10:05:20 +0100 -Subject: [PATCH 10/19] Fix race condition in red_get_string - -Do not read multiple time an array size that can be changed. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -810,6 +810,7 @@ static SpiceString *red_get_string(RedMe - size_t chunk_size, qxl_size, red_size, glyph_size; - int glyphs, bpp = 0, i; - int error; -+ uint16_t qxl_flags, qxl_length; - - qxl = (QXLString *)get_virt(slots, addr, sizeof(*qxl), group_id, &error); - if (error) { -@@ -826,13 +827,15 @@ static SpiceString *red_get_string(RedMe - red_put_data_chunks(&chunks); - - qxl_size = qxl->data_size; -+ qxl_flags = qxl->flags; -+ qxl_length = qxl->length; - spice_assert(chunk_size == qxl_size); - -- if (qxl->flags & SPICE_STRING_FLAGS_RASTER_A1) { -+ if (qxl_flags & SPICE_STRING_FLAGS_RASTER_A1) { - bpp = 1; -- } else if (qxl->flags & SPICE_STRING_FLAGS_RASTER_A4) { -+ } else if (qxl_flags & SPICE_STRING_FLAGS_RASTER_A4) { - bpp = 4; -- } else if (qxl->flags & SPICE_STRING_FLAGS_RASTER_A8) { -+ } else if (qxl_flags & SPICE_STRING_FLAGS_RASTER_A8) { - bpp = 8; - } - spice_assert(bpp != 0); -@@ -849,11 +852,11 @@ static SpiceString *red_get_string(RedMe - start = (QXLRasterGlyph*)(&start->data[glyph_size]); - } - spice_assert(start <= end); -- spice_assert(glyphs == qxl->length); -+ spice_assert(glyphs == qxl_length); - - red = spice_malloc(red_size); -- red->length = qxl->length; -- red->flags = qxl->flags; -+ red->length = qxl_length; -+ red->flags = qxl_flags; - - start = (QXLRasterGlyph*)data; - end = (QXLRasterGlyph*)(data + chunk_size); diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0011-Fix-integer-overflow-computing-glyph_size-in-red_get.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0011-Fix-integer-overflow-computing-glyph_size-in-red_get.patch deleted file mode 100644 index 48dbb5b..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0011-Fix-integer-overflow-computing-glyph_size-in-red_get.patch +++ /dev/null @@ -1,58 +0,0 @@ -From caec52dc77af6ebdac3219a1b10fe2293af21208 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 10:13:24 +0100 -Subject: [PATCH 11/19] Fix integer overflow computing glyph_size in - red_get_string - -If bpp is int the formula can lead to weird overflows. width and height -are uint16_t so the formula is: - - size_t = u16 * (u16 * int + const_int) / const_int; - -so it became - - size_t = (int) u16 * ((int) u16 * int + const_int) / const_int; - -However the (int) u16 * (int) u16 can then became negative to overflow. -Under 64 bit architectures size_t is 64 and int usually 32 so converting -this negative 32 bit number to a unsigned 64 bit lead to a very big -number as the signed is extended and then converted to unsigned. -Using unsigned arithmetic prevent extending the sign. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -808,7 +808,9 @@ static SpiceString *red_get_string(RedMe - uint8_t *data; - bool free_data; - size_t chunk_size, qxl_size, red_size, glyph_size; -- int glyphs, bpp = 0, i; -+ int glyphs, i; -+ /* use unsigned to prevent integer overflow in multiplication below */ -+ unsigned int bpp = 0; - int error; - uint16_t qxl_flags, qxl_length; - -@@ -847,7 +849,7 @@ static SpiceString *red_get_string(RedMe - while (start < end) { - spice_assert((QXLRasterGlyph*)(&start->data[0]) <= end); - glyphs++; -- glyph_size = start->height * ((start->width * bpp + 7) / 8); -+ glyph_size = start->height * ((start->width * bpp + 7u) / 8u); - red_size += sizeof(SpiceRasterGlyph *) + SPICE_ALIGN(sizeof(SpiceRasterGlyph) + glyph_size, 4); - start = (QXLRasterGlyph*)(&start->data[glyph_size]); - } -@@ -868,7 +870,7 @@ static SpiceString *red_get_string(RedMe - glyph->height = start->height; - red_get_point_ptr(&glyph->render_pos, &start->render_pos); - red_get_point_ptr(&glyph->glyph_origin, &start->glyph_origin); -- glyph_size = glyph->height * ((glyph->width * bpp + 7) / 8); -+ glyph_size = glyph->height * ((glyph->width * bpp + 7u) / 8u); - spice_assert((QXLRasterGlyph*)(&start->data[glyph_size]) <= end); - memcpy(glyph->data, start->data, glyph_size); - start = (QXLRasterGlyph*)(&start->data[glyph_size]); diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0012-Fix-race-condition-in-red_get_data_chunks_ptr.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0012-Fix-race-condition-in-red_get_data_chunks_ptr.patch deleted file mode 100644 index b696bc0..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0012-Fix-race-condition-in-red_get_data_chunks_ptr.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 3738478ed7065fe05f3ee4848f8a7fcdf40aa920 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 12:12:19 +0100 -Subject: [PATCH 12/19] Fix race condition in red_get_data_chunks_ptr - -Do not read multiple times data from guest as this can be changed by -other guest vcpus. This causes races and security problems if these -data are used for buffer allocation or checks. - -Actually, the 'data' member can't change during read as it is just a -pointer to a fixed array contained in qxl. However, this change will -make it clear that there can be no race condition. - -Signed-off-by: Frediano Ziglio ---- - server/red_parse_qxl.c | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index cfa21f9..2863ae2 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -102,30 +102,33 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id, - RedDataChunk *red_prev; - size_t data_size = 0; - int error; -+ QXLPHYSICAL next_chunk; - - red->data_size = qxl->data_size; - data_size += red->data_size; -- if (!validate_virt(slots, (intptr_t)qxl->data, memslot_id, red->data_size, group_id)) { -+ red->data = qxl->data; -+ if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) { -+ red->data = NULL; - return 0; - } -- red->data = qxl->data; - red->prev_chunk = NULL; - -- while (qxl->next_chunk) { -+ while ((next_chunk = qxl->next_chunk) != 0) { - red_prev = red; - red = spice_new(RedDataChunk, 1); -- memslot_id = get_memslot_id(slots, qxl->next_chunk); -- qxl = (QXLDataChunk *)get_virt(slots, qxl->next_chunk, sizeof(*qxl), group_id, -+ memslot_id = get_memslot_id(slots, next_chunk); -+ qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), group_id, - &error); - if (error) { - return 0; - } - red->data_size = qxl->data_size; - data_size += red->data_size; -- if (!validate_virt(slots, (intptr_t)qxl->data, memslot_id, red->data_size, group_id)) { -+ red->data = qxl->data; -+ if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) { -+ red->data = NULL; - return 0; - } -- red->data = qxl->data; - red->prev_chunk = red_prev; - red_prev->next_chunk = red; - } --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0013-Prevent-memory-leak-if-red_get_data_chunks_ptr-fails.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0013-Prevent-memory-leak-if-red_get_data_chunks_ptr-fails.patch deleted file mode 100644 index a9eb640..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0013-Prevent-memory-leak-if-red_get_data_chunks_ptr-fails.patch +++ /dev/null @@ -1,75 +0,0 @@ -From f3605979ce3b33d60c33b59334b53618e6d8662a Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 12:14:55 +0100 -Subject: [PATCH 13/19] Prevent memory leak if red_get_data_chunks_ptr fails - -Free linked list if client tries to do nasty things - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 31 ++++++++++++++++++++----------- - 1 file changed, 20 insertions(+), 11 deletions(-) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index 2863ae2..f425869 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -107,34 +107,43 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id, - red->data_size = qxl->data_size; - data_size += red->data_size; - red->data = qxl->data; -+ red->prev_chunk = red->next_chunk = NULL; - if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) { - red->data = NULL; - return 0; - } -- red->prev_chunk = NULL; - - while ((next_chunk = qxl->next_chunk) != 0) { - red_prev = red; -- red = spice_new(RedDataChunk, 1); -+ red = spice_new0(RedDataChunk, 1); -+ red->prev_chunk = red_prev; -+ red_prev->next_chunk = red; -+ - memslot_id = get_memslot_id(slots, next_chunk); - qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), group_id, - &error); -- if (error) { -- return 0; -- } -+ if (error) -+ goto error; - red->data_size = qxl->data_size; - data_size += red->data_size; - red->data = qxl->data; -- if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) { -- red->data = NULL; -- return 0; -- } -- red->prev_chunk = red_prev; -- red_prev->next_chunk = red; -+ if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) -+ goto error; - } - - red->next_chunk = NULL; - return data_size; -+ -+error: -+ while (red->prev_chunk) { -+ red_prev = red->prev_chunk; -+ free(red); -+ red = red_prev; -+ } -+ red->data_size = 0; -+ red->next_chunk = NULL; -+ red->data = NULL; -+ return 0; - } - - static size_t red_get_data_chunks(RedMemSlotInfo *slots, int group_id, --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0014-Prevent-DoS-from-guest-trying-to-allocate-too-much-d.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0014-Prevent-DoS-from-guest-trying-to-allocate-too-much-d.patch deleted file mode 100644 index 1df492b..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0014-Prevent-DoS-from-guest-trying-to-allocate-too-much-d.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 7d69184037d0abb4fcfd5625c765b822aa458808 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 12:28:54 +0100 -Subject: [PATCH 14/19] Prevent DoS from guest trying to allocate too much data - on host for chunks - -Limit number of chunks to a given amount to avoid guest trying to -allocate too much memory. Using circular or nested chunks lists -guest could try to allocate huge amounts of memory. -Considering the list can be infinite and guest can change data this -also prevents strange security attacks from guest. - -Signed-off-by: Frediano Ziglio ---- - server/red_parse_qxl.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 41 insertions(+), 8 deletions(-) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index f425869..5513e82 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -37,6 +37,13 @@ - - G_STATIC_ASSERT(MAX_DATA_CHUNK <= G_MAXINT32); - -+/* Limit number of chunks. -+ * The guest can attempt to make host allocate too much memory -+ * just with a large number of small chunks. -+ * Prevent that the chunk list take more memory than the data itself. -+ */ -+#define MAX_CHUNKS (MAX_DATA_CHUNK/1024u) -+ - #if 0 - static void hexdump_qxl(RedMemSlotInfo *slots, int group_id, - QXLPHYSICAL addr, uint8_t bytes) -@@ -100,9 +107,11 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id, - RedDataChunk *red, QXLDataChunk *qxl) - { - RedDataChunk *red_prev; -- size_t data_size = 0; -+ uint64_t data_size = 0; -+ uint32_t chunk_data_size; - int error; - QXLPHYSICAL next_chunk; -+ unsigned num_chunks = 0; - - red->data_size = qxl->data_size; - data_size += red->data_size; -@@ -114,19 +123,43 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id, - } - - while ((next_chunk = qxl->next_chunk) != 0) { -+ /* somebody is trying to use too much memory using a lot of chunks. -+ * Or made a circular list of chunks -+ */ -+ if (++num_chunks >= MAX_CHUNKS) { -+ spice_warning("data split in too many chunks, avoiding DoS\n"); -+ goto error; -+ } -+ -+ memslot_id = get_memslot_id(slots, next_chunk); -+ qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), -+ group_id, &error); -+ if (error) -+ goto error; -+ -+ /* do not waste space for empty chunks. -+ * This could be just a driver issue or an attempt -+ * to allocate too much memory or a circular list. -+ * All above cases are handled by the check for number -+ * of chunks. -+ */ -+ chunk_data_size = qxl->data_size; -+ if (chunk_data_size == 0) -+ continue; -+ - red_prev = red; - red = spice_new0(RedDataChunk, 1); -+ red->data_size = chunk_data_size; - red->prev_chunk = red_prev; -+ red->data = qxl->data; - red_prev->next_chunk = red; - -- memslot_id = get_memslot_id(slots, next_chunk); -- qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), group_id, -- &error); -- if (error) -+ data_size += chunk_data_size; -+ /* this can happen if client is sending nested chunks */ -+ if (data_size > MAX_DATA_CHUNK) { -+ spice_warning("too much data inside chunks, avoiding DoS\n"); - goto error; -- red->data_size = qxl->data_size; -- data_size += red->data_size; -- red->data = qxl->data; -+ } - if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) - goto error; - } --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0015-Fix-some-possible-overflows-in-red_get_string-for-32.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0015-Fix-some-possible-overflows-in-red_get_string-for-32.patch deleted file mode 100644 index 979bfe4..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0015-Fix-some-possible-overflows-in-red_get_string-for-32.patch +++ /dev/null @@ -1,36 +0,0 @@ -From a447c4f2ac19a1fa36330ffc90ee70b953b82050 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 8 Sep 2015 13:06:03 +0100 -Subject: [PATCH 15/19] Fix some possible overflows in red_get_string for 32 - bit - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -896,6 +896,11 @@ static SpiceString *red_get_string(RedMe - glyphs++; - glyph_size = start->height * ((start->width * bpp + 7u) / 8u); - red_size += sizeof(SpiceRasterGlyph *) + SPICE_ALIGN(sizeof(SpiceRasterGlyph) + glyph_size, 4); -+ /* do the test correctly, we know end - start->data[0] cannot -+ * overflow, don't use start->data[glyph_size] to test for -+ * buffer overflow as this on 32 bit can cause overflow -+ * on the pointer arithmetic */ -+ spice_assert(glyph_size <= (char*) end - (char*) &start->data[0]); - start = (QXLRasterGlyph*)(&start->data[glyph_size]); - } - spice_assert(start <= end); -@@ -916,7 +921,8 @@ static SpiceString *red_get_string(RedMe - red_get_point_ptr(&glyph->render_pos, &start->render_pos); - red_get_point_ptr(&glyph->glyph_origin, &start->glyph_origin); - glyph_size = glyph->height * ((glyph->width * bpp + 7u) / 8u); -- spice_assert((QXLRasterGlyph*)(&start->data[glyph_size]) <= end); -+ /* see above for similar test */ -+ spice_assert(glyph_size <= (char*) end - (char*) &start->data[0]); - memcpy(glyph->data, start->data, glyph_size); - start = (QXLRasterGlyph*)(&start->data[glyph_size]); - glyph = (SpiceRasterGlyph*) diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0016-Make-sure-we-can-read-QXLPathSeg-structures.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0016-Make-sure-we-can-read-QXLPathSeg-structures.patch deleted file mode 100644 index b34f9a9..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0016-Make-sure-we-can-read-QXLPathSeg-structures.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2693e0497e5626642250cff47a59b3b4b2cd432d Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 15 Sep 2015 16:25:17 +0100 -Subject: [PATCH 16/19] Make sure we can read QXLPathSeg structures - -start pointer points to a QXLPathSeg structure. -Before reading from the structure, make sure the structure is contained -in the memory range checked. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index f21bfa5..281faad 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -256,7 +256,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id, - - start = (QXLPathSeg*)data; - end = (QXLPathSeg*)(data + size); -- while (start < end) { -+ while (start+1 < end) { - n_segments++; - count = start->count; - segment_size = sizeof(SpicePathSeg) + count * sizeof(SpicePointFix); -@@ -272,7 +272,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id, - seg = (SpicePathSeg*)&red->segments[n_segments]; - n_segments = 0; - mem_size2 = sizeof(*red); -- while (start < end) { -+ while (start+1 < end) { - red->segments[n_segments++] = seg; - count = start->count; - --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0017-Avoid-race-condition-copying-segments-in-red_get_pat.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0017-Avoid-race-condition-copying-segments-in-red_get_pat.patch deleted file mode 100644 index 06b6908..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0017-Avoid-race-condition-copying-segments-in-red_get_pat.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2b6695f1222f68690ea230e4e37ded7e07188f06 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Tue, 15 Sep 2015 16:38:23 +0100 -Subject: [PATCH 17/19] Avoid race condition copying segments in red_get_path - -The guest can attempt to increase the number of segments while -spice-server is reading them. -Make sure we don't copy more then the allocated segments. - -Signed-off-by: Frediano Ziglio -Acked-by: Christophe Fergeau ---- - server/red_parse_qxl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c -index 281faad..c7f8650 100644 ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -272,7 +272,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id, - seg = (SpicePathSeg*)&red->segments[n_segments]; - n_segments = 0; - mem_size2 = sizeof(*red); -- while (start+1 < end) { -+ while (start+1 < end && n_segments < red->num_segments) { - red->segments[n_segments++] = seg; - count = start->count; - --- -2.6.1 - diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0018-Prevent-data_size-to-be-set-independently-from-data.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0018-Prevent-data_size-to-be-set-independently-from-data.patch deleted file mode 100644 index 614f237..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0018-Prevent-data_size-to-be-set-independently-from-data.patch +++ /dev/null @@ -1,24 +0,0 @@ -From b3be589ab3b32af3e470a9dec19a61fb086f72fc Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Thu, 17 Sep 2015 14:28:36 +0100 -Subject: [PATCH 18/19] Prevent data_size to be set independently from data - -There was not check for data_size field so one could set data to -a small set of data and data_size much bigger than size of data -leading to buffer overflow. - -Signed-off-by: Frediano Ziglio ---- - server/red_parse_qxl.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -1392,6 +1392,7 @@ static int red_get_cursor(RedMemSlotInfo - size = red_get_data_chunks_ptr(slots, group_id, - get_memslot_id(slots, addr), - &chunks, &qxl->chunk); -+ red->data_size = MIN(red->data_size, size); - data = red_linearize_chunk(&chunks, size, &free_data); - red_put_data_chunks(&chunks); - if (free_data) { diff --git a/debian/patches/CVE-2015-5260_CVE-2015-5261/0019-Prevent-leak-if-size-from-red_get_data_chunks-don-t-.patch b/debian/patches/CVE-2015-5260_CVE-2015-5261/0019-Prevent-leak-if-size-from-red_get_data_chunks-don-t-.patch deleted file mode 100644 index 030038c..0000000 --- a/debian/patches/CVE-2015-5260_CVE-2015-5261/0019-Prevent-leak-if-size-from-red_get_data_chunks-don-t-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 6e3547f8b192f5b01d478ca222bf46736f5c700c Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Thu, 17 Sep 2015 15:01:05 +0100 -Subject: [PATCH 19/19] Prevent leak if size from red_get_data_chunks don't - match in red_get_image - -Signed-off-by: Frediano Ziglio ---- - server/red_parse_qxl.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/server/red_parse_qxl.c -+++ b/server/red_parse_qxl.c -@@ -530,6 +530,7 @@ static SpiceImage *red_get_image(RedMemS - &chunks, qxl->bitmap.data); - spice_assert(size == bitmap_size); - if (size != bitmap_size) { -+ red_put_data_chunks(&chunks); - goto error; - } - red->u.bitmap.data = red_get_image_data_chunked(slots, group_id, -@@ -550,6 +551,7 @@ static SpiceImage *red_get_image(RedMemS - &chunks, (QXLDataChunk *)qxl->quic.data); - spice_assert(size == red->u.quic.data_size); - if (size != red->u.quic.data_size) { -+ red_put_data_chunks(&chunks); - goto error; - } - red->u.quic.data = red_get_image_data_chunked(slots, group_id, diff --git a/debian/patches/allow-to-set-sasl-callbacks.patch b/debian/patches/allow-to-set-sasl-callbacks.patch index f2eaa2d..46d0a89 100644 --- a/debian/patches/allow-to-set-sasl-callbacks.patch +++ b/debian/patches/allow-to-set-sasl-callbacks.patch @@ -10,11 +10,11 @@ Index: new/server/spice-server.syms spice_server_get_best_playback_rate; spice_server_set_playback_rate; spice_server_get_best_record_rate; -Index: new/server/spice.h +Index: new/server/spice-server.h =================================================================== ---- new.orig/server/spice.h -+++ new/server/spice.h -@@ -457,6 +457,7 @@ int spice_server_set_exit_on_disconnect( +--- new.orig/server/spice-server.h ++++ new/server/spice-server.h +@@ -53,6 +53,7 @@ int spice_server_set_exit_on_disconnect( int spice_server_set_noauth(SpiceServer *s); int spice_server_set_sasl(SpiceServer *s, int enabled); int spice_server_set_sasl_appname(SpiceServer *s, const char *appname); @@ -45,7 +45,7 @@ Index: new/server/reds_stream.c typedef struct RedsSASL { sasl_conn_t *conn; -@@ -966,7 +978,7 @@ bool reds_sasl_start_auth(RedsStream *st +@@ -976,7 +988,7 @@ bool reds_sasl_start_auth(RedsStream *st NULL, /* User realm */ localAddr, remoteAddr, diff --git a/debian/patches/series b/debian/patches/series index 29d4ffe..247f05d 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,21 +1 @@ allow-to-set-sasl-callbacks.patch -CVE-2015-3247.patch -CVE-2015-5260_CVE-2015-5261/0001-worker-validate-correctly-surfaces.patch -CVE-2015-5260_CVE-2015-5261/0002-worker-avoid-double-free-or-double-create-of-surface.patch -CVE-2015-5260_CVE-2015-5261/0003-Define-a-constant-to-limit-data-from-guest.patch -CVE-2015-5260_CVE-2015-5261/0004-Fix-some-integer-overflow-causing-large-memory-alloc.patch -CVE-2015-5260_CVE-2015-5261/0005-Check-properly-surface-to-be-created.patch -CVE-2015-5260_CVE-2015-5261/0006-Fix-buffer-reading-overflow.patch -CVE-2015-5260_CVE-2015-5261/0007-Prevent-32-bit-integer-overflow-in-bitmap_consistent.patch -CVE-2015-5260_CVE-2015-5261/0008-Fix-race-condition-on-red_get_clip_rects.patch -CVE-2015-5260_CVE-2015-5261/0009-Fix-race-in-red_get_image.patch -CVE-2015-5260_CVE-2015-5261/0010-Fix-race-condition-in-red_get_string.patch -CVE-2015-5260_CVE-2015-5261/0011-Fix-integer-overflow-computing-glyph_size-in-red_get.patch -CVE-2015-5260_CVE-2015-5261/0012-Fix-race-condition-in-red_get_data_chunks_ptr.patch -CVE-2015-5260_CVE-2015-5261/0013-Prevent-memory-leak-if-red_get_data_chunks_ptr-fails.patch -CVE-2015-5260_CVE-2015-5261/0014-Prevent-DoS-from-guest-trying-to-allocate-too-much-d.patch -CVE-2015-5260_CVE-2015-5261/0015-Fix-some-possible-overflows-in-red_get_string-for-32.patch -CVE-2015-5260_CVE-2015-5261/0016-Make-sure-we-can-read-QXLPathSeg-structures.patch -CVE-2015-5260_CVE-2015-5261/0017-Avoid-race-condition-copying-segments-in-red_get_pat.patch -CVE-2015-5260_CVE-2015-5261/0018-Prevent-data_size-to-be-set-independently-from-data.patch -CVE-2015-5260_CVE-2015-5261/0019-Prevent-leak-if-size-from-red_get_data_chunks-don-t-.patch diff --git a/spice-0.12.5.tar.bz2 b/spice-0.12.5.tar.bz2 deleted file mode 100644 index bb8046a..0000000 Binary files a/spice-0.12.5.tar.bz2 and /dev/null differ diff --git a/spice-0.12.8.tar.bz2 b/spice-0.12.8.tar.bz2 new file mode 100644 index 0000000..c0fb188 Binary files /dev/null and b/spice-0.12.8.tar.bz2 differ