Add fixes from upstream for CVE-2015-1779 #544328 by Agostino Sarubbo.
authorMike Frysinger <vapier@gentoo.org>
Sun, 12 Apr 2015 00:29:24 +0000 (00:29 +0000)
committerMike Frysinger <vapier@gentoo.org>
Sun, 12 Apr 2015 00:29:24 +0000 (00:29 +0000)
Package-Manager: portage-2.2.18/cvs/Linux x86_64
Manifest-Sign-Key: 0xD2E96200

app-emulation/qemu/ChangeLog
app-emulation/qemu/Manifest
app-emulation/qemu/files/qemu-2.2.1-CVE-2015-1779-1.patch [new file with mode: 0644]
app-emulation/qemu/files/qemu-2.2.1-CVE-2015-1779-2.patch [new file with mode: 0644]
app-emulation/qemu/qemu-2.2.1-r1.ebuild [new file with mode: 0644]

index b57805bcedb2d5e2d2a12fc0376dc07a1b19d216..3c83df8e8e736894a41d9f1a269066535f346706 100644 (file)
@@ -1,6 +1,13 @@
 # ChangeLog for app-emulation/qemu
 # Copyright 1999-2015 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu/ChangeLog,v 1.321 2015/04/08 07:30:33 mgorny Exp $
+# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu/ChangeLog,v 1.322 2015/04/12 00:29:22 vapier Exp $
+
+*qemu-2.2.1-r1 (12 Apr 2015)
+
+  12 Apr 2015; Mike Frysinger <vapier@gentoo.org>
+  +files/qemu-2.2.1-CVE-2015-1779-1.patch,
+  +files/qemu-2.2.1-CVE-2015-1779-2.patch, +qemu-2.2.1-r1.ebuild:
+  Add fixes from upstream for CVE-2015-1779 #544328 by Agostino Sarubbo.
 
   08 Apr 2015; Michał Górny <mgorny@gentoo.org> qemu-2.1.2-r2.ebuild,
   qemu-2.1.3.ebuild, qemu-2.2.0.ebuild, qemu-2.2.1.ebuild:
index 87fee64ac94de4543de5ec13a919ab300b828141..c6c239494bf3b482eb4081ab75aa03c43d0b4290 100644 (file)
@@ -6,6 +6,8 @@ AUX bridge.conf 454 SHA256 a51850dd39923f3482e4c575b48ad9fef9c9ebb2f2176225da399
 AUX qemu-1.7.0-cflags.patch 300 SHA256 8f35e55c4bae93e82f9580eabe2d6a2d4660bd05343e1f4e6c33815deeede91e SHA512 54446cb555b623b2306f8a323713e4dfb1b8b7bbf3af3771d5b62e164e0672cc21cbe44f08ca8b58052523e8d629e16355a44ebb544a999a44d11ac3af671f1c WHIRLPOOL b903b4abefeeb09a2ab2d1ee224de5d3694f99f50aacfe33882fce0c1c87c23dae4d57b001d1c35cc96fffa93d43fac4a8ab30a3e45fe1f380580162c0332e78
 AUX qemu-2.1.1-readlink-self.patch 2933 SHA256 3133ec1a0f0126d3362c9420602a1fdfc76fafacac8b41f5bd755e7542ee4188 SHA512 7ee06e119007e6dc08f254cbfdcc6de1c914181f60e69434190fe507a80b7d0f9e8682f0213d447481f39e145fcb0be2e118516238addb5c4326533fc0db143f WHIRLPOOL 54edcb4510546c69dedf78a2070f22e7ef2809b35a66dc2e5d356f2f1b22eea8baa5b17ed4a4d9860ee6b864fac92eb9d1bbb6daeb6e2d80e3cc702f32039996
 AUX qemu-2.1.2-vnc-sanitize-bits.patch 1279 SHA256 ef1e748fd9ffa0eb8ef412e6ea3cc96522e0ca91cf7201e6702d260ca50cbac5 SHA512 7e1a744928eb8edb76b18e58cf94da38ad1030f49ceb38f5e081d852573f8f314f998639c8e97fee27a53f51abe495b27406daa02b670a620ab2db165a47429e WHIRLPOOL bc024286739b56038bfebd6c2ad71addd9565a833f21a7a48cadbe7403c3e93c889cb2223d044448634cc93b6dc45a268299ea1b5b18c09b3477bb6e12fb0506
+AUX qemu-2.2.1-CVE-2015-1779-1.patch 8631 SHA256 17ea04bb0571f3a346eb25ce2d61fd7053515767adedfde567fd39205993c600 SHA512 191dde0754b9466d87cf99a578ac07f0902f373156f4d5ff98540b9099a6fa8e29ba4ca9d4a5a21ae5dbba2b80c36600ea0bd2c31fa0c8734926514015166ab8 WHIRLPOOL 2be2f490eb32857b2b218761df3580bc31eb5a89bf1b289a048e9fd489cdb024869399481345b5ecb09a45c4fbf1ee4639062ae1fdbee9781e66ca6cc8af4cac
+AUX qemu-2.2.1-CVE-2015-1779-2.patch 2318 SHA256 4c0966520bf09df25d99c883f94037e765406dd4097dd704e66361bb07f73679 SHA512 7a85bc8e00c60c6c36790d1169f0d84d2c75fe81c1700b4f764ddcb0d0587d4b6d228d80e65fead035e3ab99449aad2f559071edf9145ff7a755506f3ff05b0e WHIRLPOOL 078388c50367d41c810a02aa795b6ad0df381582bdd2725ae125243ee5921aa4057494f063a7de49da6b6f6343f37a3c83d96ef6d92c22e722972c8e4ea968dc
 AUX qemu-9999-cflags.patch 347 SHA256 fe3bcbe83e81225b2c722578a0a976fcb724419d5208bbd6d02fb543e80b7e12 SHA512 e1b8be744170d61a2155b23a8394db01f8af6dc70ec033e71b2ff46f72975704836d42b96d7904e5d462289c5f8f24317f2fb28698f18a77ab1de02829e585eb WHIRLPOOL 2d972c7e40292f424fd37a4c1af04d2be095c215211ec2e1d15d8457df553342ffc02a7d39985f817fbbf5342e422d30e439c35a925341cf9b852ca7ff15a308
 AUX qemu-9999-virtfs-proxy-helper-accept.patch 973 SHA256 91cc9e024aa09ea3dd23ec52c561047656acc89f0ad0d5ddccce354c1ac4d282 SHA512 031cb1c35b479b18032f56a07fa2fa6d392a7f0919acd3636bf122ab7f75dcfbb5fc0e26e18a8a31a9888409f81c2e08438a1af999232418d940167c5031a92b WHIRLPOOL ea4dc08230289a147fd55d0bd9e32896cd4491130084fc45b4043f41caf611f07d4587cc485e6d25ba3f6fbc66939ed8faf3c2017bf33ab10e1885277fa3f6ff
 AUX qemu-binfmt.initd-r1 8078 SHA256 2560f1d12374a2dea74e18365ac3d759c2eab35eb9a77b989e1bb8346d9bc3f8 SHA512 82d8ebdb5a4c452f03281c28f074ea52acfb730f1c3ddf68de2ce496c7ca23fd379041948371b021355f00f9c260383fdecf47218ddf2764ab75d6ec8a7a2715 WHIRLPOOL a0f54e133fbda2fd050ef8168fee676a763bb94a890f8c1d99d44e37e4a29322d513d9f5ddad9247f44e3ee0ac779050a3b06cf909678fdfb9f46777701de492
@@ -18,26 +20,25 @@ DIST qemu-2.2.1.tar.bz2 24483500 SHA256 4617154c6ef744b83e10b744e392ad111dd351d4
 EBUILD qemu-2.1.2-r2.ebuild 18526 SHA256 ce5e0c44d8ddc830e8703b32de979e70a9e3675ddcb1509febff684d9a805436 SHA512 5d74ec3a48eab6952ef96204f9bfb0ebf1dee7664848809f468689d6e97e9461182e345aa09082fccd33e9ddf90ecc7617d2dc9232180fcbd3436676eece35c2 WHIRLPOOL a38dd61c267cd19d28ccbb1004b136e4b92d50bf0b2f182e047b4d601aca006beedd47fc4c34b4ce7f526d1cfa7292f2713c18782a625f1917936057be8c5488
 EBUILD qemu-2.1.3.ebuild 18450 SHA256 e209f9cc11ac9a40d2e8e19a7a763fac5f2a5acd41cea19ff0092ecb2312ee00 SHA512 01990f68c31b5643aa70c3bc3e813cc9ae1bbec718d2056f8cb4e2826b910804fd58533e370a8ec9d554f48f79822707dbdfa69378c24c868962a35b180b4ea2 WHIRLPOOL 22206434005207e6788c254e378d2df704738177219667f947427c1384a08c6c81a52aca373ca666c3c4acc298a7822658c5ec4a24d03d0991b385091b0c8da4
 EBUILD qemu-2.2.0.ebuild 18321 SHA256 738a09c193c78a6cb49bfddd98294ca7b629594b0af4e927cb5d0a1a3d593570 SHA512 37ad4912b0ff335938afc94feb4f94413e7fb8bd9be4578de89dfbfc2d57f3524a2da68802a834cb9e5fd2fb07bed0ab9df3521a296f1c30830bbbb5e9e5a0e9 WHIRLPOOL adeb66e57b126d6a9448c2f9a0755a7b4a3f055190e5151c20111d7ca12a3231798628218290d62645440e0b7accfedb53e19f4af126d7a377ccec0c86b0032a
+EBUILD qemu-2.2.1-r1.ebuild 18461 SHA256 26a60f02d369162e331faeaa52bb7d93a2e1198a495ea28de6593f6f27f05b44 SHA512 fefe928c9ef61717d834a496c7ad0ccf033a9b9deb3629a8c1a7dcd522b877a8e453ea5f27930f5a799e956885f73e5929c7371bbcfd542579a028a95ffaf372 WHIRLPOOL 396a88325ddb76e0a368452a58d31041bfeb25db362ec506e0dd42ee91a10e76a639bf830efbf2217fe485e611830cb35d9573a51b8261c216f090dba88dc738
 EBUILD qemu-2.2.1.ebuild 18336 SHA256 010e31805cae369a4fda875a9b6db9cf57ded71a594a3d62fc9a8dc28e35bdc1 SHA512 b068a1256a37864237c29f9e3e17d2a5f384bb58630ca968a307878f09d0022a95a5417dae9013cdfdc10ea13940c84fed42048a9d298c6180bab0545aa5cec4 WHIRLPOOL b448e8d41815c094519ca68315fd441d633e43dd038800a95d5c81a644532d698fb91fef977cb95016729213964cdd420e035ac317981ddbe1164d10cbf264ff
 EBUILD qemu-9999.ebuild 18669 SHA256 85fa1cb7f088ea7e3bdabf458eb412a5adced548e19d803bec69afe14d516f79 SHA512 45114c09beb9299c3fc94ebd5c152d730c63070f1d1e85ad4e7a93affc360ddd44e0f4552dc75c606b15d3f36683f3bfefd1621364d352cfe943a5f1d8b938df WHIRLPOOL 500eed367785006a0f83ad80b0cc30c30e2ec5dd1902639d68c85fa8b0f10b345fa7b685c95f5d335542be5e4d1ad3b7dc58035329d47dc7a3cecd93aaa89b33
-MISC ChangeLog 52789 SHA256 5c9e6869db70db817ab7acce59d86bbe4528c65e5e1b69ffb7ad1d2fe6bf7372 SHA512 23097a6d0aa9ca4bdac72c0629e97d717b5608c305e20e895b8982923fa511e6b9a5c0a2193076ca4f7e0adcb354773bd2861d1b91879c60af49883613bb9074 WHIRLPOOL 3d9f0d779215600f5bb510bd7c466e046cc9b66c065f9a2242b2ae1d27a36833624abdfa279199464bf034ef9a00cfb0cda0244012b3b3db11ad26400bb7b79a
+MISC ChangeLog 53052 SHA256 2e82523191d12045e2610bf8df7bc02a39f1e3314ffa63042e9dc166471ab482 SHA512 310ee54d0ee5c5ac20207a19060e7e7e6f1108ba61f7e636b7045da45f5ce2069e0fedebbe5b10e9109c2f16c6069fc737a11777d8501f1f13b2b469b1808dd4 WHIRLPOOL ad5ae01440823652aef8d26986a3b79e1730c1c89a4b4b1c6307be890c4638334c93049410bc2376c9d254bc51e21e2e271209fb5554c4d4816e1e6cae78617a
 MISC metadata.xml 3648 SHA256 d6c0a87cd95bf7e2b66bb4c9bd21bdac780f502e8921aa0bfb93ba301c978562 SHA512 b3aed4e6c67bb23312402b4e6832485e31c1e6e4c38055190603da80b3680262d8f876d6e9af2f1efbfce6072125f3093edeb712f4ad73246c08b1f77a466649 WHIRLPOOL 8d45f196554880858262886575374c109f621f45120e6278ca9c5a4f70f191b909782589b6c65b7aef0294c655bb8fc43dc382197e69b5c68b874c949bd4c286
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
-iQJ8BAEBCABmBQJVJNl4XxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25zLm9w
-ZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQ2REJCMDdDQzRGMERBRDA2RUEwQUZFNDFC
-MDdBMUFFQUVGQjQ0NjRFAAoJELB6GurvtEZOOKsP/0M956ACTp9+HkERridVBhiy
-VcYPef7Sdwr66kwMFiY+WylIte/PaiIZBggPod2wt4b5R1zIzBy4ah9SVOAznrv9
-+5pZFsqvIPCTx9X58R69nQw1wArpe4GJF0XbNAoVOHx7OAjVsI6IXSG1PHBdwNhV
-/vQoBw0OrX3HYbzdIvNDnJY1erVZia4v/rLYb773URsROriNx9/ahkFYeUvPBpt0
-CCfgK/K2RqqtVrNdhUsb0r0koSfbNgvAS6HArh5dhUEESpuJo1y6Sq5o15hyzskV
-BphE3C2HXkGMzhCaXhH1rnNfC1cvw/eoPamQlM2BV6YZlxJ7mbHHHGErGeHPu5Oj
-bbPVFYgAt+JJKr9BFjvqLkCONvRf1RZzFC4YTNSexjdAVV0Wcq1mTjjwkPHg29+W
-lbOHn+123Fa/ZhFsndco6gyfqJ08GnCHrPQLfCrozFSE6sdsTxyaw6VbE+Jh6deK
-ZpgPhi81+9DPvEwZd6PhnkHrn3+fYb++h+a0Bvb6ifFhDIBgOXv4FR0lTxu1X6VQ
-ozlHl4CKuCRi49s7TL/fxdwSvTaTr6sgvuTAc2KE/ow8GP31a+vSObc7Z3mApqPl
-BuqH38QpxGNRV8HuzhAzxKyxA3zEecVT1IMqkNOAvPh6tGtX05tE+nV81klO0f8C
-DzwTJgw20FocrPA0sRzN
-=5+9t
+iQIcBAEBCAAGBQJVKbxkAAoJEPGu1DbS6WIAL9kP/1EmCCUBPlFOc0unCyQR2qvs
+9sUK4ZP5SmU7F4TXKfVoOrL8/ThYa2yA4sE5VbQ0OuFfjuxthEIqP9JAxhJ4hAHB
+xy3FqISLIDUEHlvauV1k3LtgL9LFBz1IokRzUipAybPh3iCwRUiSYpLX1uqZe0T5
+R7VDoTeB7yfEzl5A9mISvQHLIaKqpEOcvXzUMn594eM67wAunXkjtA1qDKXAvGGz
+GFG3eUsRbQwV5uohlJdNjTh0XfnvyuFwDtf9vbhUSXWVa4GRsgnLXEEdpCNo7WPN
+j5sfAtYFKyPj5nWYNyya54Yi/tfyvbWBqviX5AHc2Mn7Mu9BeLjGB8E+Td9Dtw4X
+hDR2NY30SZdbGOuNxZ74TFvsqH3ewgkTVR6+36iWk59FH/hbudOz2UA0BSuoyN0A
+Zug7SqmBVHDs+0qqb8ce1eFHONBBylUg3/YCk3G/uNIeeOpntbqzunH7pguTg//Z
+m6gX348L5s3ck5swwnRIG7BHLD6CPE2Kpsz4QilLK/t6pRNT/fYixKI0DDGn2Hz7
+Mv3WiB3lUSJDynfNGBieQ66LbU1PyN1J9KeaUEMo6VwuTrooFF/nFlflKrgjj0mz
+cQG9bU2U/9K4TKLBBgWSmEJRtb8Vxy8DeDXcQHiImbjfeZFsoV2Dq2urQD77rBYj
+XobEOyApM14lkCZGVfdK
+=P6AQ
 -----END PGP SIGNATURE-----
diff --git a/app-emulation/qemu/files/qemu-2.2.1-CVE-2015-1779-1.patch b/app-emulation/qemu/files/qemu-2.2.1-CVE-2015-1779-1.patch
new file mode 100644 (file)
index 0000000..35ef8fd
--- /dev/null
@@ -0,0 +1,241 @@
+From a2bebfd6e09d285aa793cae3fb0fc3a39a9fee6e Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 23 Mar 2015 22:58:21 +0000
+Subject: [PATCH] CVE-2015-1779: incrementally decode websocket frames
+
+The logic for decoding websocket frames wants to fully
+decode the frame header and payload, before allowing the
+VNC server to see any of the payload data. There is no
+size limit on websocket payloads, so this allows a
+malicious network client to consume 2^64 bytes in memory
+in QEMU. It can trigger this denial of service before
+the VNC server even performs any authentication.
+
+The fix is to decode the header, and then incrementally
+decode the payload data as it is needed. With this fix
+the websocket decoder will allow at most 4k of data to
+be buffered before decoding and processing payload.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+
+[ kraxel: fix frequent spurious disconnects, suggested by Peter Maydell ]
+
+  @@ -361,7 +361,7 @@ int vncws_decode_frame_payload(Buffer *input,
+  -        *payload_size = input->offset;
+  +        *payload_size = *payload_remain;
+
+[ kraxel: fix 32bit build ]
+
+  @@ -306,7 +306,7 @@ struct VncState
+  -    uint64_t ws_payload_remain;
+  +    size_t ws_payload_remain;
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ ui/vnc-ws.c | 105 ++++++++++++++++++++++++++++++++++++++++--------------------
+ ui/vnc-ws.h |   9 ++++--
+ ui/vnc.h    |   2 ++
+ 3 files changed, 80 insertions(+), 36 deletions(-)
+
+diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
+index 85dbb7e..0b7de4e 100644
+--- a/ui/vnc-ws.c
++++ b/ui/vnc-ws.c
+@@ -107,7 +107,7 @@ long vnc_client_read_ws(VncState *vs)
+ {
+     int ret, err;
+     uint8_t *payload;
+-    size_t payload_size, frame_size;
++    size_t payload_size, header_size;
+     VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer,
+             vs->ws_input.capacity, vs->ws_input.offset);
+     buffer_reserve(&vs->ws_input, 4096);
+@@ -117,18 +117,39 @@ long vnc_client_read_ws(VncState *vs)
+     }
+     vs->ws_input.offset += ret;
+ 
+-    /* make sure that nothing is left in the ws_input buffer */
++    ret = 0;
++    /* consume as much of ws_input buffer as possible */
+     do {
+-        err = vncws_decode_frame(&vs->ws_input, &payload,
+-                              &payload_size, &frame_size);
+-        if (err <= 0) {
+-            return err;
++        if (vs->ws_payload_remain == 0) {
++            err = vncws_decode_frame_header(&vs->ws_input,
++                                            &header_size,
++                                            &vs->ws_payload_remain,
++                                            &vs->ws_payload_mask);
++            if (err <= 0) {
++                return err;
++            }
++
++            buffer_advance(&vs->ws_input, header_size);
+         }
++        if (vs->ws_payload_remain != 0) {
++            err = vncws_decode_frame_payload(&vs->ws_input,
++                                             &vs->ws_payload_remain,
++                                             &vs->ws_payload_mask,
++                                             &payload,
++                                             &payload_size);
++            if (err < 0) {
++                return err;
++            }
++            if (err == 0) {
++                return ret;
++            }
++            ret += err;
+ 
+-        buffer_reserve(&vs->input, payload_size);
+-        buffer_append(&vs->input, payload, payload_size);
++            buffer_reserve(&vs->input, payload_size);
++            buffer_append(&vs->input, payload, payload_size);
+ 
+-        buffer_advance(&vs->ws_input, frame_size);
++            buffer_advance(&vs->ws_input, payload_size);
++        }
+     } while (vs->ws_input.offset > 0);
+ 
+     return ret;
+@@ -265,15 +286,14 @@ void vncws_encode_frame(Buffer *output, const void *payload,
+     buffer_append(output, payload, payload_size);
+ }
+ 
+-int vncws_decode_frame(Buffer *input, uint8_t **payload,
+-                           size_t *payload_size, size_t *frame_size)
++int vncws_decode_frame_header(Buffer *input,
++                              size_t *header_size,
++                              size_t *payload_remain,
++                              WsMask *payload_mask)
+ {
+     unsigned char opcode = 0, fin = 0, has_mask = 0;
+-    size_t header_size = 0;
+-    uint32_t *payload32;
++    size_t payload_len;
+     WsHeader *header = (WsHeader *)input->buffer;
+-    WsMask mask;
+-    int i;
+ 
+     if (input->offset < WS_HEAD_MIN_LEN + 4) {
+         /* header not complete */
+@@ -283,7 +303,7 @@ int vncws_decode_frame(Buffer *input, uint8_t **payload,
+     fin = (header->b0 & 0x80) >> 7;
+     opcode = header->b0 & 0x0f;
+     has_mask = (header->b1 & 0x80) >> 7;
+-    *payload_size = header->b1 & 0x7f;
++    payload_len = header->b1 & 0x7f;
+ 
+     if (opcode == WS_OPCODE_CLOSE) {
+         /* disconnect */
+@@ -300,40 +320,57 @@ int vncws_decode_frame(Buffer *input, uint8_t **payload,
+         return -2;
+     }
+ 
+-    if (*payload_size < 126) {
+-        header_size = 6;
+-        mask = header->u.m;
+-    } else if (*payload_size == 126 && input->offset >= 8) {
+-        *payload_size = be16_to_cpu(header->u.s16.l16);
+-        header_size = 8;
+-        mask = header->u.s16.m16;
+-    } else if (*payload_size == 127 && input->offset >= 14) {
+-        *payload_size = be64_to_cpu(header->u.s64.l64);
+-        header_size = 14;
+-        mask = header->u.s64.m64;
++    if (payload_len < 126) {
++        *payload_remain = payload_len;
++        *header_size = 6;
++        *payload_mask = header->u.m;
++    } else if (payload_len == 126 && input->offset >= 8) {
++        *payload_remain = be16_to_cpu(header->u.s16.l16);
++        *header_size = 8;
++        *payload_mask = header->u.s16.m16;
++    } else if (payload_len == 127 && input->offset >= 14) {
++        *payload_remain = be64_to_cpu(header->u.s64.l64);
++        *header_size = 14;
++        *payload_mask = header->u.s64.m64;
+     } else {
+         /* header not complete */
+         return 0;
+     }
+ 
+-    *frame_size = header_size + *payload_size;
++    return 1;
++}
++
++int vncws_decode_frame_payload(Buffer *input,
++                               size_t *payload_remain, WsMask *payload_mask,
++                               uint8_t **payload, size_t *payload_size)
++{
++    size_t i;
++    uint32_t *payload32;
+ 
+-    if (input->offset < *frame_size) {
+-        /* frame not complete */
++    *payload = input->buffer;
++    /* If we aren't at the end of the payload, then drop
++     * off the last bytes, so we're always multiple of 4
++     * for purpose of unmasking, except at end of payload
++     */
++    if (input->offset < *payload_remain) {
++        *payload_size = input->offset - (input->offset % 4);
++    } else {
++        *payload_size = *payload_remain;
++    }
++    if (*payload_size == 0) {
+         return 0;
+     }
+-
+-    *payload = input->buffer + header_size;
++    *payload_remain -= *payload_size;
+ 
+     /* unmask frame */
+     /* process 1 frame (32 bit op) */
+     payload32 = (uint32_t *)(*payload);
+     for (i = 0; i < *payload_size / 4; i++) {
+-        payload32[i] ^= mask.u;
++        payload32[i] ^= payload_mask->u;
+     }
+     /* process the remaining bytes (if any) */
+     for (i *= 4; i < *payload_size; i++) {
+-        (*payload)[i] ^= mask.c[i % 4];
++        (*payload)[i] ^= payload_mask->c[i % 4];
+     }
+ 
+     return 1;
+diff --git a/ui/vnc-ws.h b/ui/vnc-ws.h
+index ef229b7..14d4230 100644
+--- a/ui/vnc-ws.h
++++ b/ui/vnc-ws.h
+@@ -83,7 +83,12 @@ long vnc_client_read_ws(VncState *vs);
+ void vncws_process_handshake(VncState *vs, uint8_t *line, size_t size);
+ void vncws_encode_frame(Buffer *output, const void *payload,
+             const size_t payload_size);
+-int vncws_decode_frame(Buffer *input, uint8_t **payload,
+-                               size_t *payload_size, size_t *frame_size);
++int vncws_decode_frame_header(Buffer *input,
++                              size_t *header_size,
++                              size_t *payload_remain,
++                              WsMask *payload_mask);
++int vncws_decode_frame_payload(Buffer *input,
++                               size_t *payload_remain, WsMask *payload_mask,
++                               uint8_t **payload, size_t *payload_size);
+ 
+ #endif /* __QEMU_UI_VNC_WS_H */
+diff --git a/ui/vnc.h b/ui/vnc.h
+index e19ac39..3f7c6a9 100644
+--- a/ui/vnc.h
++++ b/ui/vnc.h
+@@ -306,6 +306,8 @@ struct VncState
+ #ifdef CONFIG_VNC_WS
+     Buffer ws_input;
+     Buffer ws_output;
++    size_t ws_payload_remain;
++    WsMask ws_payload_mask;
+ #endif
+     /* current output mode information */
+     VncWritePixels *write_pixels;
+-- 
+2.3.5
+
diff --git a/app-emulation/qemu/files/qemu-2.2.1-CVE-2015-1779-2.patch b/app-emulation/qemu/files/qemu-2.2.1-CVE-2015-1779-2.patch
new file mode 100644 (file)
index 0000000..c7a8c8b
--- /dev/null
@@ -0,0 +1,58 @@
+From 2cdb5e142fb93e875fa53c52864ef5eb8d5d8b41 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 23 Mar 2015 22:58:22 +0000
+Subject: [PATCH] CVE-2015-1779: limit size of HTTP headers from websockets
+ clients
+
+The VNC server websockets decoder will read and buffer data from
+websockets clients until it sees the end of the HTTP headers,
+as indicated by \r\n\r\n. In theory this allows a malicious to
+trick QEMU into consuming an arbitrary amount of RAM. In practice,
+because QEMU runs g_strstr_len() across the buffered header data,
+it will spend increasingly long burning CPU time searching for
+the substring match and less & less time reading data. So while
+this does cause arbitrary memory growth, the bigger problem is
+that QEMU will be burning 100% of available CPU time.
+
+A novnc websockets client typically sends headers of around
+512 bytes in length. As such it is reasonable to place a 4096
+byte limit on the amount of data buffered while searching for
+the end of HTTP headers.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ ui/vnc-ws.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
+index 0b7de4e..62eb97f 100644
+--- a/ui/vnc-ws.c
++++ b/ui/vnc-ws.c
+@@ -81,8 +81,11 @@ void vncws_handshake_read(void *opaque)
+     VncState *vs = opaque;
+     uint8_t *handshake_end;
+     long ret;
+-    buffer_reserve(&vs->ws_input, 4096);
+-    ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096);
++    /* Typical HTTP headers from novnc are 512 bytes, so limiting
++     * total header size to 4096 is easily enough. */
++    size_t want = 4096 - vs->ws_input.offset;
++    buffer_reserve(&vs->ws_input, want);
++    ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want);
+ 
+     if (!ret) {
+         if (vs->csock == -1) {
+@@ -99,6 +102,9 @@ void vncws_handshake_read(void *opaque)
+         vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset);
+         buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer +
+                 strlen(WS_HANDSHAKE_END));
++    } else if (vs->ws_input.offset >= 4096) {
++        VNC_DEBUG("End of headers not found in first 4096 bytes\n");
++        vnc_client_error(vs);
+     }
+ }
+ 
+-- 
+2.3.5
+
diff --git a/app-emulation/qemu/qemu-2.2.1-r1.ebuild b/app-emulation/qemu/qemu-2.2.1-r1.ebuild
new file mode 100644 (file)
index 0000000..d745ed4
--- /dev/null
@@ -0,0 +1,603 @@
+# Copyright 1999-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu/qemu-2.2.1-r1.ebuild,v 1.1 2015/04/12 00:29:22 vapier Exp $
+
+EAPI=5
+
+PYTHON_COMPAT=( python2_7 )
+PYTHON_REQ_USE="ncurses,readline"
+
+inherit eutils flag-o-matic linux-info toolchain-funcs multilib python-r1 \
+       user udev fcaps readme.gentoo pax-utils
+
+BACKPORTS=
+
+if [[ ${PV} = *9999* ]]; then
+       EGIT_REPO_URI="git://git.qemu.org/qemu.git"
+       inherit git-2
+       SRC_URI=""
+       KEYWORDS=""
+else
+       SRC_URI="http://wiki.qemu-project.org/download/${P}.tar.bz2
+       ${BACKPORTS:+
+               http://dev.gentoo.org/~cardoe/distfiles/${P}-${BACKPORTS}.tar.xz}"
+       KEYWORDS="~amd64 ~ppc ~ppc64 ~x86 ~x86-fbsd"
+fi
+
+DESCRIPTION="QEMU + Kernel-based Virtual Machine userland tools"
+HOMEPAGE="http://www.qemu.org http://www.linux-kvm.org"
+
+LICENSE="GPL-2 LGPL-2 BSD-2"
+SLOT="0"
+IUSE="accessibility +aio alsa bluetooth +caps +curl debug +fdt glusterfs \
+gtk infiniband iscsi +jpeg \
+kernel_linux kernel_FreeBSD lzo ncurses nfs nls numa opengl +pin-upstream-blobs
++png pulseaudio python \
+rbd sasl +seccomp sdl selinux smartcard snappy spice ssh static static-softmmu \
+static-user systemtap tci test +threads tls usb usbredir +uuid vde +vhost-net \
+virtfs +vnc xattr xen xfs"
+
+COMMON_TARGETS="aarch64 alpha arm cris i386 m68k microblaze microblazeel mips
+mips64 mips64el mipsel or32 ppc ppc64 s390x sh4 sh4eb sparc sparc64 unicore32
+x86_64"
+IUSE_SOFTMMU_TARGETS="${COMMON_TARGETS} lm32 moxie ppcemb xtensa xtensaeb"
+IUSE_USER_TARGETS="${COMMON_TARGETS} armeb mipsn32 mipsn32el ppc64abi32 sparc32plus"
+
+use_targets="
+       $(printf ' qemu_softmmu_targets_%s' ${IUSE_SOFTMMU_TARGETS})
+       $(printf ' qemu_user_targets_%s' ${IUSE_USER_TARGETS})
+"
+IUSE+=" ${use_targets}"
+
+# Require at least one softmmu or user target.
+# Block USE flag configurations known to not work.
+REQUIRED_USE="|| ( ${use_targets} )
+       ${PYTHON_REQUIRED_USE}
+       qemu_softmmu_targets_arm? ( fdt )
+       qemu_softmmu_targets_microblaze? ( fdt )
+       qemu_softmmu_targets_ppc? ( fdt )
+       qemu_softmmu_targets_ppc64? ( fdt )
+       static? ( static-softmmu static-user )
+       static-softmmu? ( !alsa !pulseaudio !bluetooth !opengl !gtk )
+       virtfs? ( xattr )"
+
+# Yep, you need both libcap and libcap-ng since virtfs only uses libcap.
+#
+# The attr lib isn't always linked in (although the USE flag is always
+# respected).  This is because qemu supports using the C library's API
+# when available rather than always using the extranl library.
+COMMON_LIB_DEPEND=">=dev-libs/glib-2.0[static-libs(+)]
+       sys-libs/zlib[static-libs(+)]
+       xattr? ( sys-apps/attr[static-libs(+)] )"
+SOFTMMU_LIB_DEPEND="${COMMON_LIB_DEPEND}
+       >=x11-libs/pixman-0.28.0[static-libs(+)]
+       aio? ( dev-libs/libaio[static-libs(+)] )
+       caps? ( sys-libs/libcap-ng[static-libs(+)] )
+       curl? ( >=net-misc/curl-7.15.4[static-libs(+)] )
+       fdt? ( >=sys-apps/dtc-1.4.0[static-libs(+)] )
+       glusterfs? ( >=sys-cluster/glusterfs-3.4.0[static-libs(+)] )
+       infiniband? ( sys-infiniband/librdmacm:=[static-libs(+)] )
+       jpeg? ( virtual/jpeg:=[static-libs(+)] )
+       lzo? ( dev-libs/lzo:2[static-libs(+)] )
+       ncurses? ( sys-libs/ncurses[static-libs(+)] )
+       nfs? ( >=net-fs/libnfs-1.9.3[static-libs(+)] )
+       numa? ( sys-process/numactl[static-libs(+)] )
+       png? ( media-libs/libpng:0=[static-libs(+)] )
+       rbd? ( sys-cluster/ceph[static-libs(+)] )
+       sasl? ( dev-libs/cyrus-sasl[static-libs(+)] )
+       sdl? ( >=media-libs/libsdl-1.2.11[static-libs(+)] )
+       seccomp? ( >=sys-libs/libseccomp-2.1.0[static-libs(+)] )
+       snappy? ( app-arch/snappy[static-libs(+)] )
+       spice? ( >=app-emulation/spice-0.12.0[static-libs(+)] )
+       ssh? ( >=net-libs/libssh2-1.2.8[static-libs(+)] )
+       tls? ( net-libs/gnutls[static-libs(+)] )
+       usb? ( >=dev-libs/libusb-1.0.18[static-libs(+)] )
+       uuid? ( >=sys-apps/util-linux-2.16.0[static-libs(+)] )
+       vde? ( net-misc/vde[static-libs(+)] )
+       xfs? ( sys-fs/xfsprogs[static-libs(+)] )"
+USER_LIB_DEPEND="${COMMON_LIB_DEPEND}"
+X86_FIRMWARE_DEPEND="
+       >=sys-firmware/ipxe-1.0.0_p20130624
+       pin-upstream-blobs? (
+               ~sys-firmware/seabios-1.7.5
+               ~sys-firmware/sgabios-0.1_pre8
+               ~sys-firmware/vgabios-0.7a
+       )
+       !pin-upstream-blobs? (
+               sys-firmware/seabios
+               sys-firmware/sgabios
+               sys-firmware/vgabios
+       )"
+CDEPEND="!static-softmmu? ( ${SOFTMMU_LIB_DEPEND//\[static-libs(+)]} )
+       !static-user? ( ${USER_LIB_DEPEND//\[static-libs(+)]} )
+       qemu_softmmu_targets_i386? ( ${X86_FIRMWARE_DEPEND} )
+       qemu_softmmu_targets_x86_64? ( ${X86_FIRMWARE_DEPEND} )
+       accessibility? ( app-accessibility/brltty )
+       alsa? ( >=media-libs/alsa-lib-1.0.13 )
+       bluetooth? ( net-wireless/bluez )
+       gtk? (
+               x11-libs/gtk+:3
+               x11-libs/vte:2.90
+       )
+       iscsi? ( net-libs/libiscsi )
+       opengl? ( virtual/opengl )
+       pulseaudio? ( media-sound/pulseaudio )
+       python? ( ${PYTHON_DEPS} )
+       sdl? ( media-libs/libsdl[X] )
+       smartcard? ( dev-libs/nss !app-emulation/libcacard )
+       spice? ( >=app-emulation/spice-protocol-0.12.3 )
+       systemtap? ( dev-util/systemtap )
+       usbredir? ( >=sys-apps/usbredir-0.6 )
+       virtfs? ( sys-libs/libcap )
+       xen? ( app-emulation/xen-tools )"
+DEPEND="${CDEPEND}
+       dev-lang/perl
+       =dev-lang/python-2*
+       sys-apps/texinfo
+       virtual/pkgconfig
+       kernel_linux? ( >=sys-kernel/linux-headers-2.6.35 )
+       gtk? ( nls? ( sys-devel/gettext ) )
+       static-softmmu? ( ${SOFTMMU_LIB_DEPEND} )
+       static-user? ( ${USER_LIB_DEPEND} )
+       test? (
+               dev-libs/glib[utils]
+               sys-devel/bc
+       )"
+RDEPEND="${CDEPEND}
+       selinux? ( sec-policy/selinux-qemu )
+"
+
+STRIP_MASK="/usr/share/qemu/palcode-clipper"
+
+QA_PREBUILT="
+       usr/share/qemu/openbios-ppc
+       usr/share/qemu/openbios-sparc64
+       usr/share/qemu/openbios-sparc32
+       usr/share/qemu/palcode-clipper
+       usr/share/qemu/s390-ccw.img
+       usr/share/qemu/u-boot.e500
+"
+
+QA_WX_LOAD="usr/bin/qemu-i386
+       usr/bin/qemu-x86_64
+       usr/bin/qemu-alpha
+       usr/bin/qemu-arm
+       usr/bin/qemu-cris
+       usr/bin/qemu-m68k
+       usr/bin/qemu-microblaze
+       usr/bin/qemu-microblazeel
+       usr/bin/qemu-mips
+       usr/bin/qemu-mipsel
+       usr/bin/qemu-or32
+       usr/bin/qemu-ppc
+       usr/bin/qemu-ppc64
+       usr/bin/qemu-ppc64abi32
+       usr/bin/qemu-sh4
+       usr/bin/qemu-sh4eb
+       usr/bin/qemu-sparc
+       usr/bin/qemu-sparc64
+       usr/bin/qemu-armeb
+       usr/bin/qemu-sparc32plus
+       usr/bin/qemu-s390x
+       usr/bin/qemu-unicore32"
+
+DOC_CONTENTS="If you don't have kvm compiled into the kernel, make sure
+you have the kernel module loaded before running kvm. The easiest way to
+ensure that the kernel module is loaded is to load it on boot.\n
+For AMD CPUs the module is called 'kvm-amd'\n
+For Intel CPUs the module is called 'kvm-intel'\n
+Please review /etc/conf.d/modules for how to load these\n\n
+Make sure your user is in the 'kvm' group\n
+Just run 'gpasswd -a <USER> kvm', then have <USER> re-login."
+
+qemu_support_kvm() {
+       if use qemu_softmmu_targets_x86_64 || use qemu_softmmu_targets_i386 \
+               use qemu_softmmu_targets_ppc || use qemu_softmmu_targets_ppc64 \
+               use qemu_softmmu_targets_s390x; then
+               return 0
+       fi
+
+       return 1
+}
+
+pkg_pretend() {
+       if use kernel_linux && kernel_is lt 2 6 25; then
+               eerror "This version of KVM requres a host kernel of 2.6.25 or higher."
+       elif use kernel_linux; then
+               if ! linux_config_exists; then
+                       eerror "Unable to check your kernel for KVM support"
+               else
+                       CONFIG_CHECK="~KVM ~TUN ~BRIDGE"
+                       ERROR_KVM="You must enable KVM in your kernel to continue"
+                       ERROR_KVM_AMD="If you have an AMD CPU, you must enable KVM_AMD in"
+                       ERROR_KVM_AMD+=" your kernel configuration."
+                       ERROR_KVM_INTEL="If you have an Intel CPU, you must enable"
+                       ERROR_KVM_INTEL+=" KVM_INTEL in your kernel configuration."
+                       ERROR_TUN="You will need the Universal TUN/TAP driver compiled"
+                       ERROR_TUN+=" into your kernel or loaded as a module to use the"
+                       ERROR_TUN+=" virtual network device if using -net tap."
+                       ERROR_BRIDGE="You will also need support for 802.1d"
+                       ERROR_BRIDGE+=" Ethernet Bridging for some network configurations."
+                       use vhost-net && CONFIG_CHECK+=" ~VHOST_NET"
+                       ERROR_VHOST_NET="You must enable VHOST_NET to have vhost-net"
+                       ERROR_VHOST_NET+=" support"
+
+                       if use amd64 || use x86 || use amd64-linux || use x86-linux; then
+                               CONFIG_CHECK+=" ~KVM_AMD ~KVM_INTEL"
+                       fi
+
+                       use python && CONFIG_CHECK+=" ~DEBUG_FS"
+                       ERROR_DEBUG_FS="debugFS support required for kvm_stat"
+
+                       # Now do the actual checks setup above
+                       check_extra_config
+               fi
+       fi
+
+       if grep -qs '/usr/bin/qemu-kvm' "${EROOT}"/etc/libvirt/qemu/*.xml; then
+               eerror "The kvm/qemu-kvm wrappers no longer exist, but your libvirt"
+               eerror "instances are still pointing to it.  Please update your"
+               eerror "configs in /etc/libvirt/qemu/ to use the -enable-kvm flag"
+               eerror "and the right system binary (e.g. qemu-system-x86_64)."
+               die "update your virt configs to not use qemu-kvm"
+       fi
+}
+
+pkg_setup() {
+       enewgroup kvm 78
+       python_setup
+}
+
+src_prepare() {
+       # Alter target makefiles to accept CFLAGS set via flag-o
+       sed -i -r \
+               -e 's/^(C|OP_C|HELPER_C)FLAGS=/\1FLAGS+=/' \
+               Makefile Makefile.target || die
+
+       # Cheap hack to disable gettext .mo generation.
+       use nls || rm -f po/*.po
+
+       epatch "${FILESDIR}"/qemu-1.7.0-cflags.patch
+       epatch "${FILESDIR}"/${P}-CVE-2015-1779-1.patch #544328
+       epatch "${FILESDIR}"/${P}-CVE-2015-1779-2.patch #544328
+       [[ -n ${BACKPORTS} ]] && \
+               EPATCH_FORCE=yes EPATCH_SUFFIX="patch" EPATCH_SOURCE="${S}/patches" \
+                       epatch
+
+       # Fix ld and objcopy being called directly
+       tc-export AR LD OBJCOPY
+
+       # Verbose builds
+       MAKEOPTS+=" V=1"
+
+       epatch_user
+}
+
+##
+# configures qemu based on the build directory and the build type
+# we are using.
+#
+qemu_src_configure() {
+       debug-print-function ${FUNCNAME} "$@"
+
+       local buildtype=$1
+       local builddir=$2
+       local static_flag="static-${buildtype}"
+
+       # audio options
+       local audio_opts="oss"
+       use alsa && audio_opts="alsa,${audio_opts}"
+       use sdl && audio_opts="sdl,${audio_opts}"
+       use pulseaudio && audio_opts="pa,${audio_opts}"
+
+       local conf_opts=(
+               --prefix=/usr
+               --sysconfdir=/etc
+               --libdir=/usr/$(get_libdir)
+               --docdir=/usr/share/doc/${PF}/html
+               --disable-bsd-user
+               --disable-guest-agent
+               --disable-strip
+               --disable-werror
+               --python="${PYTHON}"
+               --cc="$(tc-getCC)"
+               --cxx="$(tc-getCXX)"
+               --host-cc="$(tc-getBUILD_CC)"
+               $(use_enable debug debug-info)
+               $(use_enable debug debug-tcg)
+               --enable-docs
+               $(use_enable tci tcg-interpreter)
+               $(use_enable xattr attr)
+       )
+
+       # Disable options not used by user targets as the default configure
+       # options will autoprobe and try to link in a bunch of unused junk.
+       conf_softmmu() {
+               if [[ ${buildtype} == "user" ]] ; then
+                       echo "--disable-${2:-$1}"
+               else
+                       use_enable "$@"
+               fi
+       }
+       conf_opts+=(
+               $(conf_softmmu accessibility brlapi)
+               $(conf_softmmu aio linux-aio)
+               $(conf_softmmu bluetooth bluez)
+               $(conf_softmmu caps cap-ng)
+               $(conf_softmmu curl)
+               $(conf_softmmu fdt)
+               $(conf_softmmu glusterfs)
+               $(conf_softmmu gtk)
+               $(conf_softmmu infiniband rdma)
+               $(conf_softmmu iscsi libiscsi)
+               $(conf_softmmu jpeg vnc-jpeg)
+               $(conf_softmmu kernel_linux kvm)
+               $(conf_softmmu lzo)
+               $(conf_softmmu ncurses curses)
+               $(conf_softmmu nfs libnfs)
+               $(conf_softmmu numa)
+               $(conf_softmmu opengl glx)
+               $(conf_softmmu png vnc-png)
+               $(conf_softmmu rbd)
+               $(conf_softmmu sasl vnc-sasl)
+               $(conf_softmmu sdl)
+               $(conf_softmmu seccomp)
+               $(conf_softmmu smartcard smartcard-nss)
+               $(conf_softmmu snappy)
+               $(conf_softmmu spice)
+               $(conf_softmmu ssh libssh2)
+               $(conf_softmmu tls quorum)
+               $(conf_softmmu tls vnc-tls)
+               $(conf_softmmu tls vnc-ws)
+               $(conf_softmmu usb libusb)
+               $(conf_softmmu usbredir usb-redir)
+               $(conf_softmmu uuid)
+               $(conf_softmmu vde)
+               $(conf_softmmu vhost-net)
+               $(conf_softmmu virtfs)
+               $(conf_softmmu vnc)
+               $(conf_softmmu xen)
+               $(conf_softmmu xen xen-pci-passthrough)
+               $(conf_softmmu xfs xfsctl)
+       )
+
+       case ${buildtype} in
+       user)
+               conf_opts+=(
+                       --enable-linux-user
+                       --disable-system
+                       --target-list="${user_targets}"
+                       --disable-blobs
+                       --disable-tools
+               )
+               ;;
+       softmmu)
+               conf_opts+=(
+                       --disable-linux-user
+                       --enable-system
+                       --target-list="${softmmu_targets}"
+                       --with-system-pixman
+                       --audio-drv-list="${audio_opts}"
+               )
+               use gtk && conf_opts+=( --with-gtkabi=3.0 )
+               ;;
+       esac
+
+       # Add support for SystemTAP
+       use systemtap && conf_opts+=( --enable-trace-backend=dtrace )
+
+       # We always want to attempt to build with PIE support as it results
+       # in a more secure binary. But it doesn't work with static or if
+       # the current GCC doesn't have PIE support.
+       if use ${static_flag}; then
+               conf_opts+=( --static --disable-pie )
+       else
+               gcc-specs-pie && conf_opts+=( --enable-pie )
+       fi
+
+       einfo "../configure ${conf_opts[*]}"
+       cd "${builddir}"
+       ../configure "${conf_opts[@]}" || die "configure failed"
+
+       # FreeBSD's kernel does not support QEMU assigning/grabbing
+       # host USB devices yet
+       use kernel_FreeBSD && \
+               sed -i -E -e "s|^(HOST_USB=)bsd|\1stub|" "${S}"/config-host.mak
+}
+
+src_configure() {
+       local target
+
+       python_export_best
+
+       softmmu_targets= softmmu_bins=()
+       user_targets= user_bins=()
+
+       for target in ${IUSE_SOFTMMU_TARGETS} ; do
+               if use "qemu_softmmu_targets_${target}"; then
+                       softmmu_targets+=",${target}-softmmu"
+                       softmmu_bins+=( "qemu-system-${target}" )
+               fi
+       done
+
+       for target in ${IUSE_USER_TARGETS} ; do
+               if use "qemu_user_targets_${target}"; then
+                       user_targets+=",${target}-linux-user"
+                       user_bins+=( "qemu-${target}" )
+               fi
+       done
+
+       [[ -n ${softmmu_targets} ]] && \
+               einfo "Building the following softmmu targets: ${softmmu_targets}"
+
+       [[ -n ${user_targets} ]] && \
+               einfo "Building the following user targets: ${user_targets}"
+
+       if [[ -n ${softmmu_targets} ]]; then
+               mkdir "${S}/softmmu-build"
+               qemu_src_configure "softmmu" "${S}/softmmu-build"
+       fi
+
+       if [[ -n ${user_targets} ]]; then
+               mkdir "${S}/user-build"
+               qemu_src_configure "user" "${S}/user-build"
+       fi
+}
+
+src_compile() {
+       if [[ -n ${user_targets} ]]; then
+               cd "${S}/user-build"
+               default
+       fi
+
+       if [[ -n ${softmmu_targets} ]]; then
+               cd "${S}/softmmu-build"
+               default
+       fi
+}
+
+src_test() {
+       if [[ -n ${softmmu_targets} ]]; then
+               cd "${S}/softmmu-build"
+               pax-mark m */qemu-system-* #515550
+               emake -j1 check
+               emake -j1 check-report.html
+       fi
+}
+
+qemu_python_install() {
+       python_domodule "${S}/scripts/qmp/qmp.py"
+
+       python_doscript "${S}/scripts/kvm/kvm_stat"
+       python_doscript "${S}/scripts/kvm/vmxcap"
+       python_doscript "${S}/scripts/qmp/qmp-shell"
+       python_doscript "${S}/scripts/qmp/qemu-ga-client"
+}
+
+src_install() {
+       if [[ -n ${user_targets} ]]; then
+               cd "${S}/user-build"
+               emake DESTDIR="${ED}" install
+
+               # Install binfmt handler init script for user targets
+               newinitd "${FILESDIR}/qemu-binfmt.initd-r1" qemu-binfmt
+       fi
+
+       if [[ -n ${softmmu_targets} ]]; then
+               cd "${S}/softmmu-build"
+               emake DESTDIR="${ED}" install
+
+               # This might not exist if the test failed. #512010
+               [[ -e check-report.html ]] && dohtml check-report.html
+
+               if use kernel_linux; then
+                       udev_dorules "${FILESDIR}"/65-kvm.rules
+               fi
+
+               if use python; then
+                       python_foreach_impl qemu_python_install
+               fi
+       fi
+
+       # Disable mprotect on the qemu binaries as they use JITs to be fast #459348
+       pushd "${ED}"/usr/bin >/dev/null
+       pax-mark m "${softmmu_bins[@]}" "${user_bins[@]}"
+       popd >/dev/null
+
+       # Install config file example for qemu-bridge-helper
+       insinto "/etc/qemu"
+       doins "${FILESDIR}/bridge.conf"
+
+       # Remove the docdir placed qmp-commands.txt
+       mv "${ED}/usr/share/doc/${PF}/html/qmp-commands.txt" "${S}/docs/qmp/"
+
+       cd "${S}"
+       dodoc Changelog MAINTAINERS docs/specs/pci-ids.txt
+       newdoc pc-bios/README README.pc-bios
+       dodoc docs/qmp/*.txt
+
+       # Remove SeaBIOS since we're using the SeaBIOS packaged one
+       rm "${ED}/usr/share/qemu/bios.bin"
+       if use qemu_softmmu_targets_x86_64 || use qemu_softmmu_targets_i386; then
+               dosym ../seabios/bios.bin /usr/share/qemu/bios.bin
+       fi
+
+       # Remove vgabios since we're using the vgabios packaged one
+       if [[ -n ${softmmu_targets} ]]; then
+               rm "${ED}/usr/share/qemu/vgabios.bin"
+               rm "${ED}/usr/share/qemu/vgabios-cirrus.bin"
+               rm "${ED}/usr/share/qemu/vgabios-qxl.bin"
+               rm "${ED}/usr/share/qemu/vgabios-stdvga.bin"
+               rm "${ED}/usr/share/qemu/vgabios-vmware.bin"
+               if use qemu_softmmu_targets_x86_64 || use qemu_softmmu_targets_i386; then
+                       dosym ../vgabios/vgabios.bin /usr/share/qemu/vgabios.bin
+                       dosym ../vgabios/vgabios-cirrus.bin /usr/share/qemu/vgabios-cirrus.bin
+                       dosym ../vgabios/vgabios-qxl.bin /usr/share/qemu/vgabios-qxl.bin
+                       dosym ../vgabios/vgabios-stdvga.bin /usr/share/qemu/vgabios-stdvga.bin
+                       dosym ../vgabios/vgabios-vmware.bin /usr/share/qemu/vgabios-vmware.bin
+               fi
+
+               # Remove sgabios since we're using the sgabios packaged one
+               rm "${ED}/usr/share/qemu/sgabios.bin"
+               if use qemu_softmmu_targets_x86_64 || use qemu_softmmu_targets_i386; then
+                       dosym ../sgabios/sgabios.bin /usr/share/qemu/sgabios.bin
+               fi
+
+               # Remove iPXE since we're using the iPXE packaged one
+               rm "${ED}"/usr/share/qemu/pxe-*.rom
+               if use qemu_softmmu_targets_x86_64 || use qemu_softmmu_targets_i386; then
+                       dosym ../ipxe/8086100e.rom /usr/share/qemu/pxe-e1000.rom
+                       dosym ../ipxe/80861209.rom /usr/share/qemu/pxe-eepro100.rom
+                       dosym ../ipxe/10500940.rom /usr/share/qemu/pxe-ne2k_pci.rom
+                       dosym ../ipxe/10222000.rom /usr/share/qemu/pxe-pcnet.rom
+                       dosym ../ipxe/10ec8139.rom /usr/share/qemu/pxe-rtl8139.rom
+                       dosym ../ipxe/1af41000.rom /usr/share/qemu/pxe-virtio.rom
+               fi
+       fi
+
+       qemu_support_kvm && readme.gentoo_create_doc
+}
+
+pkg_postinst() {
+       if qemu_support_kvm; then
+               readme.gentoo_print_elog
+               ewarn "Migration from qemu-kvm instances and loading qemu-kvm created"
+               ewarn "save states has been removed starting with the 1.6.2 release"
+               ewarn
+               ewarn "It is recommended that you migrate any VMs that may be running"
+               ewarn "on qemu-kvm to a host with a newer qemu and regenerate"
+               ewarn "any saved states with a newer qemu."
+               ewarn
+               ewarn "qemu-kvm was the primary qemu provider in Gentoo through 1.2.x"
+
+               if use x86 || use amd64; then
+                       ewarn
+                       ewarn "The /usr/bin/kvm and /usr/bin/qemu-kvm wrappers are no longer"
+                       ewarn "installed.  In order to use kvm acceleration, pass the flag"
+                       ewarn "-enable-kvm when running your system target."
+               fi
+       fi
+
+       if [[ -n ${softmmu_targets} ]] && use kernel_linux; then
+               udev_reload
+       fi
+
+       fcaps cap_net_admin /usr/libexec/qemu-bridge-helper
+       if use virtfs && [ -n "${softmmu_targets}" ]; then
+               local virtfs_caps="cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_setgid,cap_mknod,cap_setuid"
+               fcaps ${virtfs_caps} /usr/bin/virtfs-proxy-helper
+       fi
+}
+
+pkg_info() {
+       echo "Using:"
+       echo "  $(best_version app-emulation/spice-protocol)"
+       echo "  $(best_version sys-firmware/ipxe)"
+       echo "  $(best_version sys-firmware/seabios)"
+       if has_version sys-firmware/seabios[binary]; then
+               echo "    USE=binary"
+       else
+               echo "    USE=''"
+       fi
+       echo "  $(best_version sys-firmware/vgabios)"
+}