From 03ecfa81e75d6c0a0e29a76c62f81ce3b1b7b1e693bc57d7db70fb85cce2e995 Mon Sep 17 00:00:00 2001 From: Bruce Rogers Date: Tue, 15 Aug 2017 20:33:21 +0000 Subject: [PATCH] Accepting request 517094 from home:bfrogers:branches:Virtualization Discovered we needed to augment a previous security patch with two additional patches to complete a clean fix. OBS-URL: https://build.opensuse.org/request/show/517094 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=353 --- ...-vnc-password-file-and-incoming-conn.patch | 14 +- ...-test-string-input-visitor-Add-int-t.patch | 20 +-- ...-xen-mapcache-store-dma-information-.patch | 161 ++++++++++++++++++ ...-exec-Add-lock-parameter-to-qemu_ram.patch | 84 +++++++++ qemu-linux-user.changes | 8 + qemu-linux-user.spec | 4 + qemu-testsuite.changes | 9 + qemu-testsuite.spec | 4 + qemu.changes | 9 + qemu.spec | 4 + 10 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 0073-xen-mapcache-store-dma-information-.patch create mode 100644 0074-exec-Add-lock-parameter-to-qemu_ram.patch diff --git a/0016-vnc-password-file-and-incoming-conn.patch b/0016-vnc-password-file-and-incoming-conn.patch index 01577411..62040190 100644 --- a/0016-vnc-password-file-and-incoming-conn.patch +++ b/0016-vnc-password-file-and-incoming-conn.patch @@ -83,26 +83,26 @@ index 349cfc9d86..486d2759e4 100644 static QemuOptsList qemu_vnc_opts = { .name = "vnc", .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head), -@@ -3202,6 +3245,9 @@ static QemuOptsList qemu_vnc_opts = { +@@ -3201,6 +3244,9 @@ static QemuOptsList qemu_vnc_opts = { + },{ .name = "connections", .type = QEMU_OPT_NUMBER, - },{ ++ },{ + .name = "allowed-connections", + .type = QEMU_OPT_NUMBER, -+ },{ + },{ .name = "to", .type = QEMU_OPT_NUMBER, +@@ -3213,6 +3259,9 @@ static QemuOptsList qemu_vnc_opts = { },{ -@@ -3214,6 +3260,9 @@ static QemuOptsList qemu_vnc_opts = { .name = "password", .type = QEMU_OPT_BOOL, - },{ ++ },{ + .name = "password-file", + .type = QEMU_OPT_STRING, -+ },{ + },{ .name = "reverse", .type = QEMU_OPT_BOOL, - },{ @@ -3766,6 +3815,7 @@ void vnc_display_open(const char *id, Error **errp) const char *share, *device_id; QemuConsole *con; diff --git a/0042-test-string-input-visitor-Add-int-t.patch b/0042-test-string-input-visitor-Add-int-t.patch index 1795b472..1a293f38 100644 --- a/0042-test-string-input-visitor-Add-int-t.patch +++ b/0042-test-string-input-visitor-Add-int-t.patch @@ -17,18 +17,18 @@ diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor index 79313a7f7a..e00194a649 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c -@@ -58,6 +58,14 @@ static void test_visitor_in_int(TestInputVisitorData *data, - visit_type_int(v, NULL, &res, &err); - g_assert(!err); - g_assert_cmpint(res, ==, value); +@@ -55,6 +55,14 @@ static void test_visitor_in_int(TestInputVisitorData *data, + + v = visitor_input_test_init(data, "-42"); + ++ visit_type_int(v, NULL, &res, &err); ++ g_assert(!err); ++ g_assert_cmpint(res, ==, value); + visitor_input_teardown(data, unused); + + value = INT64_MAX; + v = visitor_input_test_init(data, g_strdup_printf("%" PRId64, value)); + -+ visit_type_int(v, NULL, &res, &err); -+ g_assert(!err); -+ g_assert_cmpint(res, ==, value); - - v = visitor_input_test_init(data, "not an int"); - + visit_type_int(v, NULL, &res, &err); + g_assert(!err); + g_assert_cmpint(res, ==, value); diff --git a/0073-xen-mapcache-store-dma-information-.patch b/0073-xen-mapcache-store-dma-information-.patch new file mode 100644 index 00000000..c9251743 --- /dev/null +++ b/0073-xen-mapcache-store-dma-information-.patch @@ -0,0 +1,161 @@ +From 96ce16c57f821b9f676de88f25d488d52fec68fe Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini +Date: Wed, 3 May 2017 14:00:35 -0700 +Subject: [PATCH] xen/mapcache: store dma information in revmapcache entries + for debugging + +The Xen mapcache is able to create long term mappings, they are called +"locked" mappings. The third parameter of the xen_map_cache call +specifies if a mapping is a "locked" mapping. + +>From the QEMU point of view there are two kinds of long term mappings: + +[a] device memory mappings, such as option roms and video memory +[b] dma mappings, created by dma_memory_map & friends + +After certain operations, ballooning a VM in particular, Xen asks QEMU +kindly to destroy all mappings. However, certainly [a] mappings are +present and cannot be removed. That's not a problem as they are not +affected by balloonning. The *real* problem is that if there are any +mappings of type [b], any outstanding dma operations could fail. This is +a known shortcoming. In other words, when Xen asks QEMU to destroy all +mappings, it is an error if any [b] mappings exist. + +However today we have no way of distinguishing [a] from [b]. Because of +that, we cannot even print a decent warning. + +This patch introduces a new "dma" bool field to MapCacheRev entires, to +remember if a given mapping is for dma or is a long term device memory +mapping. When xen_invalidate_map_cache is called, we print a warning if +any [b] mappings exist. We ignore [a] mappings. + +Mappings created by qemu_map_ram_ptr are assumed to be [a], while +mappings created by address_space_map->qemu_ram_ptr_length are assumed +to be [b]. + +The goal of the patch is to make debugging and system understanding +easier. + +Signed-off-by: Stefano Stabellini +Acked-by: Paolo Bonzini +Acked-by: Anthony PERARD +(cherry picked from commit 1ff7c5986a515d2d936eba026ff19947bbc7cb92) +[BR: infrastructure (and otherwise useful) for BSC#1048902] +Signed-off-by: Bruce Rogers +--- + exec.c | 8 ++++---- + include/sysemu/xen-mapcache.h | 5 +++-- + xen-mapcache.c | 15 ++++++++++----- + 3 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/exec.c b/exec.c +index 1de9107b61..8f45b902e4 100644 +--- a/exec.c ++++ b/exec.c +@@ -2012,10 +2012,10 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr) + * In that case just map until the end of the page. + */ + if (block->offset == 0) { +- return xen_map_cache(addr, 0, 0); ++ return xen_map_cache(addr, 0, 0, false); + } + +- block->host = xen_map_cache(block->offset, block->max_length, 1); ++ block->host = xen_map_cache(block->offset, block->max_length, 1, false); + } + return ramblock_ptr(block, addr); + } +@@ -2045,10 +2045,10 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr, + * In that case just map the requested area. + */ + if (block->offset == 0) { +- return xen_map_cache(addr, *size, 1); ++ return xen_map_cache(addr, *size, 1, true); + } + +- block->host = xen_map_cache(block->offset, block->max_length, 1); ++ block->host = xen_map_cache(block->offset, block->max_length, 1, true); + } + + return ramblock_ptr(block, addr); +diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h +index b8c93b9bce..01daaad00c 100644 +--- a/include/sysemu/xen-mapcache.h ++++ b/include/sysemu/xen-mapcache.h +@@ -17,7 +17,7 @@ typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr start_addr, + void xen_map_cache_init(phys_offset_to_gaddr_t f, + void *opaque); + uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size, +- uint8_t lock); ++ uint8_t lock, bool dma); + ram_addr_t xen_ram_addr_from_mapcache(void *ptr); + void xen_invalidate_map_cache_entry(uint8_t *buffer); + void xen_invalidate_map_cache(void); +@@ -31,7 +31,8 @@ static inline void xen_map_cache_init(phys_offset_to_gaddr_t f, + + static inline uint8_t *xen_map_cache(hwaddr phys_addr, + hwaddr size, +- uint8_t lock) ++ uint8_t lock, ++ bool dma) + { + abort(); + } +diff --git a/xen-mapcache.c b/xen-mapcache.c +index 1a96d2e5db..8335266698 100644 +--- a/xen-mapcache.c ++++ b/xen-mapcache.c +@@ -62,6 +62,7 @@ typedef struct MapCacheRev { + hwaddr paddr_index; + hwaddr size; + QTAILQ_ENTRY(MapCacheRev) next; ++ bool dma; + } MapCacheRev; + + typedef struct MapCache { +@@ -202,7 +203,7 @@ static void xen_remap_bucket(MapCacheEntry *entry, + } + + static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size, +- uint8_t lock) ++ uint8_t lock, bool dma) + { + MapCacheEntry *entry, *pentry = NULL; + hwaddr address_index; +@@ -289,6 +290,7 @@ tryagain: + if (lock) { + MapCacheRev *reventry = g_malloc0(sizeof(MapCacheRev)); + entry->lock++; ++ reventry->dma = dma; + reventry->vaddr_req = mapcache->last_entry->vaddr_base + address_offset; + reventry->paddr_index = mapcache->last_entry->paddr_index; + reventry->size = entry->size; +@@ -300,12 +302,12 @@ tryagain: + } + + uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size, +- uint8_t lock) ++ uint8_t lock, bool dma) + { + uint8_t *p; + + mapcache_lock(); +- p = xen_map_cache_unlocked(phys_addr, size, lock); ++ p = xen_map_cache_unlocked(phys_addr, size, lock, dma); + mapcache_unlock(); + return p; + } +@@ -426,8 +428,11 @@ void xen_invalidate_map_cache(void) + mapcache_lock(); + + QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) { +- DPRINTF("There should be no locked mappings at this time, " +- "but "TARGET_FMT_plx" -> %p is present\n", ++ if (!reventry->dma) { ++ continue; ++ } ++ fprintf(stderr, "Locked DMA mapping while invalidating mapcache!" ++ " "TARGET_FMT_plx" -> %p is present\n", + reventry->paddr_index, reventry->vaddr_req); + } + diff --git a/0074-exec-Add-lock-parameter-to-qemu_ram.patch b/0074-exec-Add-lock-parameter-to-qemu_ram.patch new file mode 100644 index 00000000..3ec5b661 --- /dev/null +++ b/0074-exec-Add-lock-parameter-to-qemu_ram.patch @@ -0,0 +1,84 @@ +From 9ca38f9940fd21f0a24f5a5bfac69f81561096f9 Mon Sep 17 00:00:00 2001 +From: Anthony PERARD +Date: Wed, 26 Jul 2017 17:53:26 +0100 +Subject: [PATCH] exec: Add lock parameter to qemu_ram_ptr_length + +Commit 04bf2526ce87f21b32c9acba1c5518708c243ad0 (exec: use +qemu_ram_ptr_length to access guest ram) start using qemu_ram_ptr_length +instead of qemu_map_ram_ptr, but when used with Xen, the behavior of +both function is different. They both call xen_map_cache, but one with +"lock", meaning the mapping of guest memory is never released +implicitly, and the second one without, which means, mapping can be +release later, when needed. + +In the context of address_space_{read,write}_continue, the ptr to those +mapping should not be locked because it is used immediatly and never +used again. + +The lock parameter make it explicit in which context qemu_ram_ptr_length +is called. + +Signed-off-by: Anthony PERARD +Message-Id: <20170726165326.10327-1-anthony.perard@citrix.com> +Reviewed-by: Stefano Stabellini +Signed-off-by: Paolo Bonzini +(cherry picked from commit f5aa69bdc3418773f26747ca282c291519626ece) +[BR: infrastructure for BSC#1048902] +Signed-off-by: Bruce Rogers +--- + exec.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/exec.c b/exec.c +index 8f45b902e4..9ef33e4f65 100644 +--- a/exec.c ++++ b/exec.c +@@ -2026,7 +2026,7 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr) + * Called within RCU critical section. + */ + static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr, +- hwaddr *size) ++ hwaddr *size, bool lock) + { + RAMBlock *block = ram_block; + if (*size == 0) { +@@ -2045,10 +2045,10 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr, + * In that case just map the requested area. + */ + if (block->offset == 0) { +- return xen_map_cache(addr, *size, 1, true); ++ return xen_map_cache(addr, *size, lock, lock); + } + +- block->host = xen_map_cache(block->offset, block->max_length, 1, true); ++ block->host = xen_map_cache(block->offset, block->max_length, 1, lock); + } + + return ramblock_ptr(block, addr); +@@ -2767,7 +2767,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr, + } + } else { + /* RAM case */ +- ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l); ++ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false); + memcpy(ptr, buf, l); + invalidate_and_set_dirty(mr, addr1, l); + } +@@ -2858,7 +2858,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr, + } + } else { + /* RAM case */ +- ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l); ++ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false); + memcpy(buf, ptr, l); + } + +@@ -3169,7 +3169,7 @@ void *address_space_map(AddressSpace *as, + + memory_region_ref(mr); + *plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write); +- ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen); ++ ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true); + rcu_read_unlock(); + + return ptr; diff --git a/qemu-linux-user.changes b/qemu-linux-user.changes index c9d64cf2..1c750685 100644 --- a/qemu-linux-user.changes +++ b/qemu-linux-user.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Aug 15 19:29:59 UTC 2017 - brogers@suse.com + +- Patch queue updated from git://github.com/openSUSE/qemu.git opensuse-2.9 +* Patches added: + 0073-xen-mapcache-store-dma-information-.patch + 0074-exec-Add-lock-parameter-to-qemu_ram.patch + ------------------------------------------------------------------- Tue Jul 25 19:36:58 UTC 2017 - brogers@suse.com diff --git a/qemu-linux-user.spec b/qemu-linux-user.spec index ba9cf6b4..13da755c 100644 --- a/qemu-linux-user.spec +++ b/qemu-linux-user.spec @@ -98,6 +98,8 @@ Patch0069: 0069-qemu-nbd-Ignore-SIGPIPE.patch Patch0070: 0070-usb-redir-fix-stack-overflow-in-usb.patch Patch0071: 0071-exec-use-qemu_ram_ptr_length-to-acc.patch Patch0072: 0072-slirp-check-len-against-dhcp-option.patch +Patch0073: 0073-xen-mapcache-store-dma-information-.patch +Patch0074: 0074-exec-Add-lock-parameter-to-qemu_ram.patch # Please do not add QEMU patches manually here. # Run update_git.sh to regenerate this queue. Source400: update_git.sh @@ -223,6 +225,8 @@ run cross-architecture builds. %patch0070 -p1 %patch0071 -p1 %patch0072 -p1 +%patch0073 -p1 +%patch0074 -p1 %build ./configure \ diff --git a/qemu-testsuite.changes b/qemu-testsuite.changes index 8138d3e2..bf983d44 100644 --- a/qemu-testsuite.changes +++ b/qemu-testsuite.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Tue Aug 15 19:30:11 UTC 2017 - brogers@suse.com + +- The recent security fix for CVE-2017-11334 adversely affects Xen. + Include two additional patches to make sure Xen is going to be OK. + 0073-xen-mapcache-store-dma-information-.patch + 0074-exec-Add-lock-parameter-to-qemu_ram.patch +- Patch queue updated from git://github.com/openSUSE/qemu.git opensuse-2.9 + ------------------------------------------------------------------- Wed Aug 9 12:54:23 UTC 2017 - lyan@suse.com diff --git a/qemu-testsuite.spec b/qemu-testsuite.spec index 58f42cda..2881aa1d 100644 --- a/qemu-testsuite.spec +++ b/qemu-testsuite.spec @@ -202,6 +202,8 @@ Patch0069: 0069-qemu-nbd-Ignore-SIGPIPE.patch Patch0070: 0070-usb-redir-fix-stack-overflow-in-usb.patch Patch0071: 0071-exec-use-qemu_ram_ptr_length-to-acc.patch Patch0072: 0072-slirp-check-len-against-dhcp-option.patch +Patch0073: 0073-xen-mapcache-store-dma-information-.patch +Patch0074: 0074-exec-Add-lock-parameter-to-qemu_ram.patch # Please do not add QEMU patches manually here. # Run update_git.sh to regenerate this queue. @@ -926,6 +928,8 @@ This package provides a service file for starting and stopping KSM. %patch0070 -p1 %patch0071 -p1 %patch0072 -p1 +%patch0073 -p1 +%patch0074 -p1 pushd roms/ipxe %patch1100 -p1 diff --git a/qemu.changes b/qemu.changes index 8138d3e2..bf983d44 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Tue Aug 15 19:30:11 UTC 2017 - brogers@suse.com + +- The recent security fix for CVE-2017-11334 adversely affects Xen. + Include two additional patches to make sure Xen is going to be OK. + 0073-xen-mapcache-store-dma-information-.patch + 0074-exec-Add-lock-parameter-to-qemu_ram.patch +- Patch queue updated from git://github.com/openSUSE/qemu.git opensuse-2.9 + ------------------------------------------------------------------- Wed Aug 9 12:54:23 UTC 2017 - lyan@suse.com diff --git a/qemu.spec b/qemu.spec index fab8baab..67978587 100644 --- a/qemu.spec +++ b/qemu.spec @@ -202,6 +202,8 @@ Patch0069: 0069-qemu-nbd-Ignore-SIGPIPE.patch Patch0070: 0070-usb-redir-fix-stack-overflow-in-usb.patch Patch0071: 0071-exec-use-qemu_ram_ptr_length-to-acc.patch Patch0072: 0072-slirp-check-len-against-dhcp-option.patch +Patch0073: 0073-xen-mapcache-store-dma-information-.patch +Patch0074: 0074-exec-Add-lock-parameter-to-qemu_ram.patch # Please do not add QEMU patches manually here. # Run update_git.sh to regenerate this queue. @@ -926,6 +928,8 @@ This package provides a service file for starting and stopping KSM. %patch0070 -p1 %patch0071 -p1 %patch0072 -p1 +%patch0073 -p1 +%patch0074 -p1 pushd roms/ipxe %patch1100 -p1