summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Maier <tamiko@gentoo.org>2016-06-13 23:39:52 -0500
committerMatthias Maier <tamiko@gentoo.org>2016-06-14 00:46:46 -0500
commite78aee5d6b747e4dd0c6aed30b959107957a7c17 (patch)
tree8a266d3e3cf56a1f69193e5534e8bde7e1bd791c /app-emulation/spice
parentdev-ruby/activerecord: add missing test-unit dependency, bug 578140 (diff)
downloadgentoo-e78aee5d6b747e4dd0c6aed30b959107957a7c17.tar.gz
gentoo-e78aee5d6b747e4dd0c6aed30b959107957a7c17.tar.bz2
gentoo-e78aee5d6b747e4dd0c6aed30b959107957a7c17.zip
app-emulation/spice: fix vuln 0.12.7, bug #584126
Apply the following patches to 0.12.7: CVE-2016-2150: 0067-create-a-function-to-validate-surface-parameters.patch 0068-improve-primary-surface-parameter-checks.patch CVE-2016-0749: 0065-smartcard-add-a-ref-to-item-before-adding-to-pipe.patch 0066-smartcard-allocate-msg-with-the-expected-size.patch Gentoo-Bug: 584126 Package-Manager: portage-2.2.28 Signed-off-by: Matthias Maier <tamiko@gentoo.org>
Diffstat (limited to 'app-emulation/spice')
-rw-r--r--app-emulation/spice/files/0.12.6-CVE-2016-0749-p1.patch89
-rw-r--r--app-emulation/spice/files/0.12.6-CVE-2016-0749-p2.patch61
-rw-r--r--app-emulation/spice/files/0.12.6-CVE-2016-2150-p1.patch121
-rw-r--r--app-emulation/spice/files/0.12.6-CVE-2016-2150-p2.patch33
-rw-r--r--app-emulation/spice/spice-0.12.7-r1.ebuild76
5 files changed, 380 insertions, 0 deletions
diff --git a/app-emulation/spice/files/0.12.6-CVE-2016-0749-p1.patch b/app-emulation/spice/files/0.12.6-CVE-2016-0749-p1.patch
new file mode 100644
index 000000000000..2d79fbb536af
--- /dev/null
+++ b/app-emulation/spice/files/0.12.6-CVE-2016-0749-p1.patch
@@ -0,0 +1,89 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Marc-Andre Lureau <marcandre.lureau@redhat.com>
+Date: Thu, 17 Dec 2015 18:13:47 +0100
+Subject: [PATCH] smartcard: add a ref to item before adding to pipe
+
+There is an unref when the message is sent.
+
+==17204== ERROR: AddressSanitizer: heap-use-after-free on address 0x6008000144a8 at pc 0x7fffee0ce245 bp 0x7fffffffc630 sp 0x7fffffffc620
+READ of size 4 at 0x6008000144a8 thread T0
+ #0 0x7fffee0ce244 in smartcard_unref_vsc_msg_item /home/elmarco/src/spice/spice/server/smartcard.c:608
+ #1 0x7fffee0cb451 in smartcard_unref_msg_to_client /home/elmarco/src/spice/spice/server/smartcard.c:178
+ #2 0x7fffedfcdf14 in spice_char_device_read_from_device /home/elmarco/src/spice/spice/server/char-device.c:330
+ #3 0x7fffedfd1763 in spice_char_device_wakeup /home/elmarco/src/spice/spice/server/char-device.c:901
+ #4 0x7fffee05da98 in spice_server_char_device_wakeup /home/elmarco/src/spice/spice/server/reds.c:2990
+ #5 0x55555593fa34 in spice_chr_write /home/elmarco/src/qemu/spice-qemu-char.c:189
+ #6 0x5555559375f1 in qemu_chr_fe_write /home/elmarco/src/qemu/qemu-char.c:220
+ #7 0x555555b3b682 in ccid_card_vscard_send_msg.isra.2 /home/elmarco/src/qemu/hw/usb/ccid-card-passthru.c:76
+ #8 0x555555b3c466 in ccid_card_vscard_send_error /home/elmarco/src/qemu/hw/usb/ccid-card-passthru.c:91
+ #9 0x555555b3c466 in ccid_card_vscard_handle_message /home/elmarco/src/qemu/hw/usb/ccid-card-passthru.c:242
+ #10 0x555555b3c466 in ccid_card_vscard_read /home/elmarco/src/qemu/hw/usb/ccid-card-passthru.c:289
+ #11 0x55555593f169 in vmc_write /home/elmarco/src/qemu/spice-qemu-char.c:41
+ #12 0x7fffedfcee6d in spice_char_device_write_to_device /home/elmarco/src/spice/spice/server/char-device.c:477
+ #13 0x7fffedfcfd31 in spice_char_device_write_buffer_add /home/elmarco/src/spice/spice/server/char-device.c:629
+ #14 0x7fffee0ce9df in smartcard_channel_write_to_reader /home/elmarco/src/spice/spice/server/smartcard.c:675
+ #15 0x7fffee0cc7db in smartcard_char_device_notify_reader_add /home/elmarco/src/spice/spice/server/smartcard.c:341
+ #16 0x7fffee0ce4f3 in smartcard_add_reader /home/elmarco/src/spice/spice/server/smartcard.c:648
+ #17 0x7fffee0cf2e2 in smartcard_channel_handle_message /home/elmarco/src/spice/spice/server/smartcard.c:763
+ #18 0x7fffedffe21f in red_peer_handle_incoming /home/elmarco/src/spice/spice/server/red-channel.c:307
+ #19 0x7fffedffe4f6 in red_channel_client_receive /home/elmarco/src/spice/spice/server/red-channel.c:325
+ #20 0x7fffee00726c in red_channel_client_event /home/elmarco/src/spice/spice/server/red-channel.c:1566
+ #21 0x555555c3c53d in qemu_iohandler_poll /home/elmarco/src/qemu/iohandler.c:143
+ #22 0x555555c3b800 in main_loop_wait /home/elmarco/src/qemu/main-loop.c:504
+ #23 0x5555556f160c in main_loop /home/elmarco/src/qemu/vl.c:1818
+ #24 0x5555556f160c in main /home/elmarco/src/qemu/vl.c:4394
+ #25 0x7fffed7d0b14 in __libc_start_main /usr/src/debug/glibc-2.17-c758a686/csu/libc-start.c:274
+ #26 0x5555556f9c20 in _start (/home/elmarco/src/qemu/x86_64-softmmu/qemu-system-x86_64+0x1a5c20)
+0x6008000144a8 is located 24 bytes inside of 40-byte region [0x600800014490,0x6008000144b8)
+freed by thread T0 here:
+ #0 0x7ffff4e61009 in __interceptor_free /usr/src/debug/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/x86_64-redhat-linux/libsanitizer/asan/../../../../libsanitizer/asan/asan_malloc_linux.cc:61
+ #1 0x7fffee0ce2a1 in smartcard_unref_vsc_msg_item /home/elmarco/src/spice/spice/server/smartcard.c:610
+ #2 0x7fffee0cdd58 in smartcard_channel_release_pipe_item /home/elmarco/src/spice/spice/server/smartcard.c:548
+ #3 0x7fffee000668 in red_channel_client_release_item /home/elmarco/src/spice/spice/server/red-channel.c:602
+ #4 0x7fffee0006ef in red_channel_client_release_sent_item /home/elmarco/src/spice/spice/server/red-channel.c:609
+ #5 0x7fffee0007b5 in red_channel_peer_on_out_msg_done /home/elmarco/src/spice/spice/server/red-channel.c:620
+ #6 0x7fffedffed7e in red_peer_handle_outgoing /home/elmarco/src/spice/spice/server/red-channel.c:385
+ #7 0x7fffee0057bb in red_channel_client_send /home/elmarco/src/spice/spice/server/red-channel.c:1294
+ #8 0x7fffee0076e6 in red_channel_client_begin_send_message /home/elmarco/src/spice/spice/server/red-channel.c:1605
+ #9 0x7fffee0cdccd in smartcard_channel_send_item /home/elmarco/src/spice/spice/server/smartcard.c:541
+ #10 0x7fffee000570 in red_channel_client_send_item /home/elmarco/src/spice/spice/server/red-channel.c:588
+ #11 0x7fffee005bfb in red_channel_client_push /home/elmarco/src/spice/spice/server/red-channel.c:1347
+ #12 0x7fffee007ef7 in red_channel_client_pipe_add_push /home/elmarco/src/spice/spice/server/red-channel.c:1673
+ #13 0x7fffee0cde4d in smartcard_channel_client_pipe_add_push /home/elmarco/src/spice/spice/server/smartcard.c:571
+ #14 0x7fffee0cb567 in smartcard_send_msg_to_client /home/elmarco/src/spice/spice/server/smartcard.c:187
+ #15 0x7fffedfcdba2 in spice_char_device_send_msg_to_clients /home/elmarco/src/spice/spice/server/char-device.c:282
+ #16 0x7fffedfcdea4 in spice_char_device_read_from_device /home/elmarco/src/spice/spice/server/char-device.c:329
+ #17 0x7fffedfd1763 in spice_char_device_wakeup /home/elmarco/src/spice/spice/server/char-device.c:901
+ #18 0x7fffee05da98 in spice_server_char_device_wakeup /home/elmarco/src/spice/spice/server/reds.c:2990
+ #19 0x55555593fa34 in spice_chr_write /home/elmarco/src/qemu/spice-qemu-char.c:189
+
+Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
+---
+ server/smartcard.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/server/smartcard.c b/server/smartcard.c
+index aad22aa..8d529fe 100644
+--- a/server/smartcard.c
++++ b/server/smartcard.c
+@@ -172,14 +172,17 @@ static void smartcard_unref_msg_to_client(SpiceCharDeviceMsgToClient *msg,
+ smartcard_unref_vsc_msg_item((MsgItem *)msg);
+ }
+
+-static void smartcard_send_msg_to_client(SpiceCharDeviceMsgToClient *msg,
++static void smartcard_send_msg_to_client(SpiceCharDeviceMsgToClient *message,
+ RedClient *client,
+ void *opaque)
+ {
+ SmartCardDeviceState *dev = opaque;
+- spice_assert(dev->scc && dev->scc->base.client == client);
+- smartcard_channel_client_pipe_add_push(&dev->scc->base, &((MsgItem *)msg)->base);
++ MsgItem *msg = (MsgItem *)message;
++ PipeItem *item = &msg->base;
+
++ spice_assert(dev->scc && dev->scc->base.client == client);
++ smartcard_ref_vsc_msg_item(msg);
++ smartcard_channel_client_pipe_add_push(&dev->scc->base, item);
+ }
+
+ static void smartcard_send_tokens_to_client(RedClient *client, uint32_t tokens, void *opaque)
diff --git a/app-emulation/spice/files/0.12.6-CVE-2016-0749-p2.patch b/app-emulation/spice/files/0.12.6-CVE-2016-0749-p2.patch
new file mode 100644
index 000000000000..671fc4382ed6
--- /dev/null
+++ b/app-emulation/spice/files/0.12.6-CVE-2016-0749-p2.patch
@@ -0,0 +1,61 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Marc-Andre Lureau <marcandre.lureau@redhat.com>
+Date: Thu, 17 Dec 2015 18:16:22 +0100
+Subject: [PATCH] smartcard: allocate msg with the expected size
+
+==529== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60040009c098 at pc 0x7fffee0eda6d bp 0x7fffffffcd00 sp 0x7fffffffccf0
+WRITE of size 4 at 0x60040009c098 thread T0
+ #0 0x7fffee0eda6c in smartcard_char_device_notify_reader_add /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:334
+ #1 0x7fffee0ef783 in smartcard_add_reader /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:642
+ #2 0x7fffee0f0568 in smartcard_channel_handle_message /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:757
+ #3 0x7fffee032f3f in red_peer_handle_incoming /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:304
+ #4 0x7fffee033216 in red_channel_client_receive /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:322
+ #5 0x7fffee03bf1f in red_channel_client_event /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:1561
+ #6 0x555555c3c53d in qemu_iohandler_poll /home/elmarco/src/qemu/iohandler.c:143
+ #7 0x555555c3b800 in main_loop_wait /home/elmarco/src/qemu/main-loop.c:504
+ #8 0x5555556f160c in main_loop /home/elmarco/src/qemu/vl.c:1818
+ #9 0x5555556f160c in main /home/elmarco/src/qemu/vl.c:4394
+ #10 0x7fffed80eb14 in __libc_start_main /usr/src/debug/glibc-2.17-c758a686/csu/libc-start.c:274
+ #11 0x5555556f9c20 in _start (/home/elmarco/src/qemu/x86_64-softmmu/qemu-system-x86_64+0x1a5c20)
+0x60040009c098 is located 0 bytes to the right of 8-byte region [0x60040009c090,0x60040009c098)
+allocated by thread T0 here:
+ #0 0x7ffff4e612be in __interceptor_realloc /usr/src/debug/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/x86_64-redhat-linux/libsanitizer/asan/../../../../libsanitizer/asan/asan_malloc_linux.cc:92
+ #1 0x7fffee121308 in spice_realloc /home/elmarco/pkg/spice/spice-0.12.4/spice-common/common/mem.c:123
+ #2 0x7fffee004a48 in __spice_char_device_write_buffer_get /home/elmarco/pkg/spice/spice-0.12.4/server/char_device.c:516
+ #3 0x7fffee004e87 in spice_char_device_write_buffer_get /home/elmarco/pkg/spice/spice-0.12.4/server/char_device.c:557
+ #4 0x7fffee0ed8b9 in smartcard_char_device_notify_reader_add /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:325
+ #5 0x7fffee0ef783 in smartcard_add_reader /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:642
+ #6 0x7fffee0f0568 in smartcard_channel_handle_message /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:757
+ #7 0x7fffee032f3f in red_peer_handle_incoming /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:304
+ #8 0x7fffee033216 in red_channel_client_receive /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:322
+ #9 0x7fffee03bf1f in red_channel_client_event /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:1561
+ #10 0x555555c3c53d in qemu_iohandler_poll /home/elmarco/src/qemu/iohandler.c:143
+SUMMARY: AddressSanitizer: heap-buffer-overflow /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:334 smartcard_char_device_notify_reader_add
+
+Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
+---
+ server/smartcard.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/server/smartcard.c b/server/smartcard.c
+index 8d529fe..3043ad1 100644
+--- a/server/smartcard.c
++++ b/server/smartcard.c
+@@ -325,7 +325,7 @@ static void smartcard_char_device_notify_reader_add(SmartCardDeviceState *st)
+ SpiceCharDeviceWriteBuffer *write_buf;
+ VSCMsgHeader *vheader;
+
+- write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(vheader));
++ write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(*vheader));
+ if (!write_buf) {
+ spice_error("failed to allocate write buffer");
+ return;
+@@ -372,7 +372,7 @@ static void smartcard_char_device_notify_reader_remove(SmartCardDeviceState *st)
+ spice_debug("reader add was never sent to the device");
+ return;
+ }
+- write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(vheader));
++ write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(*vheader));
+ if (!write_buf) {
+ spice_error("failed to allocate write buffer");
+ return;
diff --git a/app-emulation/spice/files/0.12.6-CVE-2016-2150-p1.patch b/app-emulation/spice/files/0.12.6-CVE-2016-2150-p1.patch
new file mode 100644
index 000000000000..a1f0c64b9713
--- /dev/null
+++ b/app-emulation/spice/files/0.12.6-CVE-2016-2150-p1.patch
@@ -0,0 +1,121 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Frediano Ziglio <fziglio@redhat.com>
+Date: Mon, 29 Feb 2016 14:24:03 +0000
+Subject: [PATCH] create a function to validate surface parameters
+
+Make possible to reuse it outside red-parse-qxl.c
+
+Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
+---
+ server/red_parse_qxl.c | 50 ++++++++++++++++++++++++++++++++------------------
+ server/red_parse_qxl.h | 5 +++++
+ 2 files changed, 37 insertions(+), 18 deletions(-)
+
+diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
+index bd0c408..7dc6a4d 100644
+--- a/server/red_parse_qxl.c
++++ b/server/red_parse_qxl.c
+@@ -19,7 +19,6 @@
+ #include <config.h>
+ #endif
+
+-#include <stdbool.h>
+ #include <inttypes.h>
+ #include <glib.h>
+ #include "common/lz_common.h"
+@@ -1306,13 +1305,41 @@ static unsigned int surface_format_to_bpp(uint32_t format)
+ return 0;
+ }
+
++bool red_validate_surface(uint32_t width, uint32_t height,
++ int32_t stride, uint32_t format)
++{
++ unsigned int bpp;
++ uint64_t size;
++
++ bpp = surface_format_to_bpp(format);
++
++ /* check if format is valid */
++ if (!bpp) {
++ return false;
++ }
++
++ /* check stride is larger than required bytes */
++ size = ((uint64_t) width * bpp + 7u) / 8u;
++ /* the uint32_t conversion is here to avoid problems with -2^31 value */
++ if (stride == G_MININT32 || size > (uint32_t) abs(stride)) {
++ return false;
++ }
++
++ /* the multiplication can overflow, also abs(-2^31) may return a negative value */
++ size = (uint64_t) height * abs(stride);
++ if (size > MAX_DATA_CHUNK) {
++ return false;
++ }
++
++ return true;
++}
++
+ 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);
+@@ -1331,26 +1358,13 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
+ 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) {
++ if (!red_validate_surface(red->u.surface_create.width, red->u.surface_create.height,
++ red->u.surface_create.stride, red->u.surface_create.format)) {
+ 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) {
+- return 1;
+- }
++ size = red->u.surface_create.height * abs(red->u.surface_create.stride);
+ red->u.surface_create.data =
+ (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id, &error);
+ if (error) {
+diff --git a/server/red_parse_qxl.h b/server/red_parse_qxl.h
+index 3adc9fa..e18d8d0 100644
+--- a/server/red_parse_qxl.h
++++ b/server/red_parse_qxl.h
+@@ -19,6 +19,8 @@
+ #ifndef RED_ABI_TRANSLATE_H
+ #define RED_ABI_TRANSLATE_H
+
++#include <stdbool.h>
++
+ #include <spice/qxl_dev.h>
+ #include "red_common.h"
+ #include "red_memslots.h"
+@@ -128,6 +130,9 @@ int red_get_message(RedMemSlotInfo *slots, int group_id,
+ RedMessage *red, QXLPHYSICAL addr);
+ void red_put_message(RedMessage *red);
+
++bool red_validate_surface(uint32_t width, uint32_t height,
++ int32_t stride, uint32_t format);
++
+ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
+ RedSurfaceCmd *red, QXLPHYSICAL addr);
+ void red_put_surface_cmd(RedSurfaceCmd *red);
diff --git a/app-emulation/spice/files/0.12.6-CVE-2016-2150-p2.patch b/app-emulation/spice/files/0.12.6-CVE-2016-2150-p2.patch
new file mode 100644
index 000000000000..8005e063f0d8
--- /dev/null
+++ b/app-emulation/spice/files/0.12.6-CVE-2016-2150-p2.patch
@@ -0,0 +1,33 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Frediano Ziglio <fziglio@redhat.com>
+Date: Mon, 29 Feb 2016 14:34:49 +0000
+Subject: [PATCH] improve primary surface parameter checks
+
+Primary surface, as additional surfaces, can be used to access
+host memory from the guest using invalid parameters.
+
+Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
+---
+ server/red_worker.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/server/red_worker.c b/server/red_worker.c
+index a7eaab9..f9179a6 100644
+--- a/server/red_worker.c
++++ b/server/red_worker.c
+@@ -11380,6 +11380,15 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
+ spice_warn_if(((uint64_t)abs(surface.stride) * (uint64_t)surface.height) !=
+ abs(surface.stride) * surface.height);
+
++ /* surface can arrive from guest unchecked so make sure
++ * guest is not a malicious one and drop invalid requests
++ */
++ if (!red_validate_surface(surface.width, surface.height,
++ surface.stride, surface.format)) {
++ spice_warning("wrong primary surface creation request");
++ return;
++ }
++
+ line_0 = (uint8_t*)get_virt(&worker->mem_slots, surface.mem,
+ surface.height * abs(surface.stride),
+ surface.group_id, &error);
diff --git a/app-emulation/spice/spice-0.12.7-r1.ebuild b/app-emulation/spice/spice-0.12.7-r1.ebuild
new file mode 100644
index 000000000000..c5b93f6bc451
--- /dev/null
+++ b/app-emulation/spice/spice-0.12.7-r1.ebuild
@@ -0,0 +1,76 @@
+# Copyright 1999-2016 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+EAPI=5
+
+PYTHON_COMPAT=( python2_7 python3_4 )
+
+inherit eutils python-any-r1
+
+DESCRIPTION="SPICE server"
+HOMEPAGE="http://spice-space.org/"
+SRC_URI="http://spice-space.org/download/releases/${P}.tar.bz2"
+
+LICENSE="LGPL-2.1"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+IUSE="libressl sasl smartcard static-libs"
+
+# the libspice-server only uses the headers of libcacard
+RDEPEND="
+ >=dev-libs/glib-2.22:2[static-libs(+)?]
+ >=media-libs/celt-0.5.1.1:0.5.1[static-libs(+)?]
+ media-libs/opus[static-libs(+)?]
+ sys-libs/zlib[static-libs(+)?]
+ virtual/jpeg:0=[static-libs(+)?]
+ >=x11-libs/pixman-0.17.7[static-libs(+)?]
+ !libressl? ( dev-libs/openssl:0[static-libs(+)?] )
+ libressl? ( dev-libs/libressl[static-libs(+)?] )
+ sasl? ( dev-libs/cyrus-sasl[static-libs(+)?] )"
+
+DEPEND="
+ ~app-emulation/spice-protocol-0.12.11
+ virtual/pkgconfig
+ $(python_gen_any_dep '
+ >=dev-python/pyparsing-1.5.6-r2[${PYTHON_USEDEP}]
+ dev-python/six[${PYTHON_USEDEP}]
+ ')
+ smartcard? ( app-emulation/qemu[smartcard] )
+ ${RDEPEND}"
+
+python_check_deps() {
+ has_version ">=dev-python/pyparsing-1.5.6-r2[${PYTHON_USEDEP}]"
+ has_version "dev-python/six[${PYTHON_USEDEP}]"
+}
+
+pkg_setup() {
+ [[ ${MERGE_TYPE} != binary ]] && python-any-r1_pkg_setup
+}
+
+# maintainer notes:
+# * opengl support is currently broken
+
+src_prepare() {
+ epatch \
+ "${FILESDIR}"/0.11.0-gold.patch \
+ "${FILESDIR}"/0.12.6-CVE-2016-0749-p1.patch \
+ "${FILESDIR}"/0.12.6-CVE-2016-0749-p2.patch \
+ "${FILESDIR}"/0.12.6-CVE-2016-2150-p1.patch \
+ "${FILESDIR}"/0.12.6-CVE-2016-2150-p2.patch
+
+ epatch_user
+}
+
+src_configure() {
+ econf \
+ $(use_enable static-libs static) \
+ $(use_with sasl) \
+ $(use_enable smartcard) \
+ --disable-gui
+}
+
+src_install() {
+ default
+ use static-libs || prune_libtool_files
+}