From 1072c8b30f152643d36a85e4980db1370e002c68 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 09 2021 09:52:18 +0000 Subject: import qemu-kvm-4.2.0-59.module+el8.5.0+12817+cb650d43 --- diff --git a/SOURCES/kvm-Add-mtod_check.patch b/SOURCES/kvm-Add-mtod_check.patch new file mode 100644 index 0000000..0b2e710 --- /dev/null +++ b/SOURCES/kvm-Add-mtod_check.patch @@ -0,0 +1,68 @@ +From 52bf635da30c75d0fdb0a3e7e7b9a2483ca033fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:55:59 -0400 +Subject: [PATCH 05/14] Add mtod_check() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210708082537.1550263-2-marcandre.lureau@redhat.com> +Patchwork-id: 101819 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/8] Add mtod_check() +Bugzilla: 1970819 1970835 1970843 1970853 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +From: Marc-André Lureau + +Recent security issues demonstrate the lack of safety care when casting +a mbuf to a particular structure type. At least, it should check that +the buffer is large enough. The following patches will make use of this +function. + +Signed-off-by: Marc-André Lureau + +(cherry picked from commit 93e645e72a056ec0b2c16e0299fc5c6b94e4ca17) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/src/mbuf.c | 11 +++++++++++ + slirp/src/mbuf.h | 1 + + 2 files changed, 12 insertions(+) + +diff --git a/slirp/src/mbuf.c b/slirp/src/mbuf.c +index 4fd62282a9..6d0653ed3d 100644 +--- a/slirp/src/mbuf.c ++++ b/slirp/src/mbuf.c +@@ -222,3 +222,14 @@ struct mbuf *dtom(Slirp *slirp, void *dat) + + return (struct mbuf *)0; + } ++ ++void *mtod_check(struct mbuf *m, size_t len) ++{ ++ if (m->m_len >= len) { ++ return m->m_data; ++ } ++ ++ DEBUG_ERROR("mtod failed"); ++ ++ return NULL; ++} +diff --git a/slirp/src/mbuf.h b/slirp/src/mbuf.h +index 546e7852c5..2015e3232f 100644 +--- a/slirp/src/mbuf.h ++++ b/slirp/src/mbuf.h +@@ -118,6 +118,7 @@ void m_inc(struct mbuf *, int); + void m_adj(struct mbuf *, int); + int m_copy(struct mbuf *, struct mbuf *, int, int); + struct mbuf *dtom(Slirp *, void *); ++void *mtod_check(struct mbuf *, size_t len); + + static inline void ifs_init(struct mbuf *ifm) + { +-- +2.27.0 + diff --git a/SOURCES/kvm-Compress-lines-for-immediate-return.patch b/SOURCES/kvm-Compress-lines-for-immediate-return.patch new file mode 100644 index 0000000..aed5149 --- /dev/null +++ b/SOURCES/kvm-Compress-lines-for-immediate-return.patch @@ -0,0 +1,242 @@ +From 5cf6dd33456c4e7e2a8849f458ce234fb5bb290c Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 25 Jun 2021 17:41:03 -0400 +Subject: [PATCH 3/4] Compress lines for immediate return +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Kevin Wolf +Message-id: <20210625174104.44313-2-kwolf@redhat.com> +Patchwork-id: 101777 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] Compress lines for immediate return +Bugzilla: 1970912 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +From: Simran Singhal + +Compress two lines into a single line if immediate return statement is found. + +It also remove variables progress, val, data, ret and sock +as they are no longer needed. + +Remove space between function "mixer_load" and '(' to fix the +checkpatch.pl error:- +ERROR: space prohibited between function name and open parenthesis '(' + +Done using following coccinelle script: +@@ +local idexpression ret; +expression e; +@@ + +-ret = ++return + e; +-return ret; + +Signed-off-by: Simran Singhal +Reviewed-by: Stefan Hajnoczi +Message-Id: <20200401165314.GA3213@simran-Inspiron-5558> +[lv: in handle_aiocb_write_zeroes_unmap() move "int ret" inside the #ifdef] +Signed-off-by: Laurent Vivier +(cherry picked from commit b3ac2b94cdc939a90d5a22338ae507689e2cfab0) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/file-posix.c | 8 +++----- + block/nfs.c | 3 +-- + block/nvme.c | 4 +--- + block/vhdx.c | 3 +-- + hw/audio/ac97.c | 4 +--- + hw/audio/adlib.c | 5 +---- + hw/display/cirrus_vga.c | 4 +--- + migration/ram.c | 4 +--- + ui/gtk.c | 3 +-- + util/qemu-sockets.c | 5 +---- + 10 files changed, 12 insertions(+), 31 deletions(-) + +diff --git a/block/file-posix.c b/block/file-posix.c +index 371572f1b0..837edcf027 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -1626,13 +1626,12 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque) + { + RawPosixAIOData *aiocb = opaque; + BDRVRawState *s G_GNUC_UNUSED = aiocb->bs->opaque; +- int ret; + + /* First try to write zeros and unmap at the same time */ + + #ifdef CONFIG_FALLOCATE_PUNCH_HOLE +- ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, +- aiocb->aio_offset, aiocb->aio_nbytes); ++ int ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, ++ aiocb->aio_offset, aiocb->aio_nbytes); + if (ret != -ENOTSUP) { + return ret; + } +@@ -1640,8 +1639,7 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque) + + /* If we couldn't manage to unmap while guaranteed that the area reads as + * all-zero afterwards, just write zeroes without unmapping */ +- ret = handle_aiocb_write_zeroes(aiocb); +- return ret; ++ return handle_aiocb_write_zeroes(aiocb); + } + + #ifndef HAVE_COPY_FILE_RANGE +diff --git a/block/nfs.c b/block/nfs.c +index 2393fbfe6b..18c0a73694 100644 +--- a/block/nfs.c ++++ b/block/nfs.c +@@ -623,8 +623,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags, + } + + bs->total_sectors = ret; +- ret = 0; +- return ret; ++ return 0; + } + + static QemuOptsList nfs_create_opts = { +diff --git a/block/nvme.c b/block/nvme.c +index 7b7c0cc5d6..eb2f54dd9d 100644 +--- a/block/nvme.c ++++ b/block/nvme.c +@@ -575,11 +575,9 @@ static bool nvme_poll_cb(void *opaque) + { + EventNotifier *e = opaque; + BDRVNVMeState *s = container_of(e, BDRVNVMeState, irq_notifier); +- bool progress = false; + + trace_nvme_poll_cb(s); +- progress = nvme_poll_queues(s); +- return progress; ++ return nvme_poll_queues(s); + } + + static int nvme_init(BlockDriverState *bs, const char *device, int namespace, +diff --git a/block/vhdx.c b/block/vhdx.c +index 21497f7318..a427e47f10 100644 +--- a/block/vhdx.c ++++ b/block/vhdx.c +@@ -411,8 +411,7 @@ int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s, + if (ret < 0) { + return ret; + } +- ret = vhdx_update_header(bs, s, generate_data_write_guid, log_guid); +- return ret; ++ return vhdx_update_header(bs, s, generate_data_write_guid, log_guid); + } + + /* opens the specified header block from the VHDX file header section */ +diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c +index a136b97f68..a2cfae52b3 100644 +--- a/hw/audio/ac97.c ++++ b/hw/audio/ac97.c +@@ -574,11 +574,9 @@ static uint32_t nam_readb (void *opaque, uint32_t addr) + static uint32_t nam_readw (void *opaque, uint32_t addr) + { + AC97LinkState *s = opaque; +- uint32_t val = ~0U; + uint32_t index = addr; + s->cas = 0; +- val = mixer_load (s, index); +- return val; ++ return mixer_load(s, index); + } + + static uint32_t nam_readl (void *opaque, uint32_t addr) +diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c +index cb4178d861..5779d09815 100644 +--- a/hw/audio/adlib.c ++++ b/hw/audio/adlib.c +@@ -120,13 +120,10 @@ static void adlib_write(void *opaque, uint32_t nport, uint32_t val) + static uint32_t adlib_read(void *opaque, uint32_t nport) + { + AdlibState *s = opaque; +- uint8_t data; + int a = nport & 3; + + adlib_kill_timers (s); +- data = OPLRead (s->opl, a); +- +- return data; ++ return OPLRead (s->opl, a); + } + + static void timer_handler (void *opaque, int c, double interval_Sec) +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 93afa26fda..a52d3094b9 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -2411,12 +2411,10 @@ static uint64_t cirrus_linear_bitblt_read(void *opaque, + unsigned size) + { + CirrusVGAState *s = opaque; +- uint32_t ret; + + /* XXX handle bitblt */ + (void)s; +- ret = 0xff; +- return ret; ++ return 0xff; + } + + static void cirrus_linear_bitblt_write(void *opaque, +diff --git a/migration/ram.c b/migration/ram.c +index 5344c7d59e..92c506d13c 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -3101,9 +3101,7 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms) + } + trace_ram_postcopy_send_discard_bitmap(); + +- ret = postcopy_each_ram_send_discard(ms); +- +- return ret; ++ return postcopy_each_ram_send_discard(ms); + } + + /** +diff --git a/ui/gtk.c b/ui/gtk.c +index 692ccc7bbb..e032e3c36f 100644 +--- a/ui/gtk.c ++++ b/ui/gtk.c +@@ -1649,8 +1649,7 @@ static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc, + G_CALLBACK(gd_menu_switch_vc), s); + gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), vc->menu_item); + +- group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item)); +- return group; ++ return gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item)); + } + + #if defined(CONFIG_VTE) +diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c +index bcc06d0e01..86c48b9fa5 100644 +--- a/util/qemu-sockets.c ++++ b/util/qemu-sockets.c +@@ -765,15 +765,12 @@ static int vsock_connect_addr(const struct sockaddr_vm *svm, Error **errp) + static int vsock_connect_saddr(VsockSocketAddress *vaddr, Error **errp) + { + struct sockaddr_vm svm; +- int sock = -1; + + if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) { + return -1; + } + +- sock = vsock_connect_addr(&svm, errp); +- +- return sock; ++ return vsock_connect_addr(&svm, errp); + } + + static int vsock_listen_saddr(VsockSocketAddress *vaddr, +-- +2.27.0 + diff --git a/SOURCES/kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch b/SOURCES/kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch new file mode 100644 index 0000000..2dd4457 --- /dev/null +++ b/SOURCES/kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch @@ -0,0 +1,59 @@ +From d0c668aa0ad255c3598267816154874541ac2943 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:56:42 -0400 +Subject: [PATCH 12/14] Fix "DHCP broken in libslirp v4.6.0" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210708082537.1550263-9-marcandre.lureau@redhat.com> +Patchwork-id: 101824 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 8/8] Fix "DHCP broken in libslirp v4.6.0" +Bugzilla: 1970819 1970835 1970843 1970853 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +From: Akihiro Suda + +Fix issue 48 + +Signed-off-by: Akihiro Suda + +(cherry picked from commit c9f314f6e315a5518432761fea864196a290f799) +[ minor conflict fix due to indentation change ] +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/src/bootp.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/slirp/src/bootp.c b/slirp/src/bootp.c +index 5789187166..3e4af075f1 100644 +--- a/slirp/src/bootp.c ++++ b/slirp/src/bootp.c +@@ -354,14 +354,14 @@ static void bootp_reply(Slirp *slirp, + q += sizeof(nak_msg) - 1; + } + assert(q < end); +- *q = +-RFC1533_END +-; ++ *q = RFC1533_END; + +-daddr.sin_addr.s_addr = 0xffffffffu; ++ daddr.sin_addr.s_addr = 0xffffffffu; + +-m->m_len = sizeof(struct bootp_t) - sizeof(struct ip) - sizeof(struct udphdr); +-udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); ++ assert ((q - rbp->bp_vend + 1) <= DHCP_OPT_LEN); ++ ++ m->m_len = sizeof(struct bootp_t) + (q - rbp->bp_vend + 1) - sizeof(struct ip) - sizeof(struct udphdr); ++ udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); + } + + void bootp_input(struct mbuf *m) +-- +2.27.0 + diff --git a/SOURCES/kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch b/SOURCES/kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch index 859de91..1538d11 100644 --- a/SOURCES/kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch +++ b/SOURCES/kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch @@ -1,7 +1,7 @@ -From 6c2949cba8971971c89fb1e5db9e557dfcd156ef Mon Sep 17 00:00:00 2001 +From dcac680adb6b8624f14eda3e812521bddbe8ecea Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Wed, 21 Apr 2021 22:30:04 -0400 -Subject: [PATCH 5/8] acpi: accept byte and word access to core ACPI registers +Subject: [PATCH 5/7] acpi: accept byte and word access to core ACPI registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -10,7 +10,7 @@ RH-Author: Jon Maloy Message-id: <20210421223006.19650-5-jmaloy@redhat.com> Patchwork-id: 101482 O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 4/6] acpi: accept byte and word access to core ACPI registers -Bugzilla: 1944621 +Bugzilla: 1842478 RH-Acked-by: Stefano Garzarella RH-Acked-by: Philippe Mathieu-Daudé RH-Acked-by: Laszlo Ersek diff --git a/SOURCES/kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch b/SOURCES/kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch new file mode 100644 index 0000000..a234140 --- /dev/null +++ b/SOURCES/kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch @@ -0,0 +1,132 @@ +From b474155fdc38f86f516c14ba9a6f934616d589ef Mon Sep 17 00:00:00 2001 +From: Andrew Jones +Date: Wed, 4 Aug 2021 03:27:22 -0400 +Subject: [PATCH 1/2] aio-wait: delegate polling of main AioContext if BQL not + held + +RH-Author: Andrew Jones +Message-id: <20210729134448.4995-2-drjones@redhat.com> +Patchwork-id: 101935 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 1/2] aio-wait: delegate polling of main AioContext if BQL not held +Bugzilla: 1969848 +RH-Acked-by: Gavin Shan +RH-Acked-by: Auger Eric +RH-Acked-by: Stefan Hajnoczi + +From: Paolo Bonzini + +Any thread that is not a iothread returns NULL for qemu_get_current_aio_context(). +As a result, it would also return true for +in_aio_context_home_thread(qemu_get_aio_context()), causing +AIO_WAIT_WHILE to invoke aio_poll() directly. This is incorrect +if the BQL is not held, because aio_poll() does not expect to +run concurrently from multiple threads, and it can actually +happen when savevm writes to the vmstate file from the +migration thread. + +Therefore, restrict in_aio_context_home_thread to return true +for the main AioContext only if the BQL is held. + +The function is moved to aio-wait.h because it is mostly used +there and to avoid a circular reference between main-loop.h +and block/aio.h. + +Signed-off-by: Paolo Bonzini +Message-Id: <20200407140746.8041-5-pbonzini@redhat.com> +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 3c18a92dc4b55ca8cc37a755ed119f11c0f34099) +Signed-off-by: Andrew Jones +Signed-off-by: Miroslav Rezanina +--- + include/block/aio-wait.h | 22 ++++++++++++++++++++++ + include/block/aio.h | 29 ++++++++++------------------- + 2 files changed, 32 insertions(+), 19 deletions(-) + +diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h +index afeeb18f95..716d2639df 100644 +--- a/include/block/aio-wait.h ++++ b/include/block/aio-wait.h +@@ -26,6 +26,7 @@ + #define QEMU_AIO_WAIT_H + + #include "block/aio.h" ++#include "qemu/main-loop.h" + + /** + * AioWait: +@@ -124,4 +125,25 @@ void aio_wait_kick(void); + */ + void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque); + ++/** ++ * in_aio_context_home_thread: ++ * @ctx: the aio context ++ * ++ * Return whether we are running in the thread that normally runs @ctx. Note ++ * that acquiring/releasing ctx does not affect the outcome, each AioContext ++ * still only has one home thread that is responsible for running it. ++ */ ++static inline bool in_aio_context_home_thread(AioContext *ctx) ++{ ++ if (ctx == qemu_get_current_aio_context()) { ++ return true; ++ } ++ ++ if (ctx == qemu_get_aio_context()) { ++ return qemu_mutex_iothread_locked(); ++ } else { ++ return false; ++ } ++} ++ + #endif /* QEMU_AIO_WAIT_H */ +diff --git a/include/block/aio.h b/include/block/aio.h +index 6b0d52f732..9d28e247df 100644 +--- a/include/block/aio.h ++++ b/include/block/aio.h +@@ -60,12 +60,16 @@ struct AioContext { + QLIST_HEAD(, AioHandler) aio_handlers; + + /* Used to avoid unnecessary event_notifier_set calls in aio_notify; +- * accessed with atomic primitives. If this field is 0, everything +- * (file descriptors, bottom halves, timers) will be re-evaluated +- * before the next blocking poll(), thus the event_notifier_set call +- * can be skipped. If it is non-zero, you may need to wake up a +- * concurrent aio_poll or the glib main event loop, making +- * event_notifier_set necessary. ++ * only written from the AioContext home thread, or under the BQL in ++ * the case of the main AioContext. However, it is read from any ++ * thread so it is still accessed with atomic primitives. ++ * ++ * If this field is 0, everything (file descriptors, bottom halves, ++ * timers) will be re-evaluated before the next blocking poll() or ++ * io_uring wait; therefore, the event_notifier_set call can be ++ * skipped. If it is non-zero, you may need to wake up a concurrent ++ * aio_poll or the glib main event loop, making event_notifier_set ++ * necessary. + * + * Bit 0 is reserved for GSource usage of the AioContext, and is 1 + * between a call to aio_ctx_prepare and the next call to aio_ctx_check. +@@ -580,19 +584,6 @@ void aio_co_enter(AioContext *ctx, struct Coroutine *co); + */ + AioContext *qemu_get_current_aio_context(void); + +-/** +- * in_aio_context_home_thread: +- * @ctx: the aio context +- * +- * Return whether we are running in the thread that normally runs @ctx. Note +- * that acquiring/releasing ctx does not affect the outcome, each AioContext +- * still only has one home thread that is responsible for running it. +- */ +-static inline bool in_aio_context_home_thread(AioContext *ctx) +-{ +- return ctx == qemu_get_current_aio_context(); +-} +- + /** + * aio_context_setup: + * @ctx: the aio context +-- +2.27.0 + diff --git a/SOURCES/kvm-async-use-explicit-memory-barriers.patch b/SOURCES/kvm-async-use-explicit-memory-barriers.patch new file mode 100644 index 0000000..2bf7245 --- /dev/null +++ b/SOURCES/kvm-async-use-explicit-memory-barriers.patch @@ -0,0 +1,183 @@ +From 82a02aec3a8b3c2ac925d0b71ea4c35aa5d6463b Mon Sep 17 00:00:00 2001 +From: Andrew Jones +Date: Wed, 4 Aug 2021 03:27:24 -0400 +Subject: [PATCH 2/2] async: use explicit memory barriers + +RH-Author: Andrew Jones +Message-id: <20210729134448.4995-3-drjones@redhat.com> +Patchwork-id: 101937 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 2/2] async: use explicit memory barriers +Bugzilla: 1969848 +RH-Acked-by: Gavin Shan +RH-Acked-by: Auger Eric +RH-Acked-by: Stefan Hajnoczi + +From: Paolo Bonzini + +When using C11 atomics, non-seqcst reads and writes do not participate +in the total order of seqcst operations. In util/async.c and util/aio-posix.c, +in particular, the pattern that we use + + write ctx->notify_me write bh->scheduled + read bh->scheduled read ctx->notify_me + if !bh->scheduled, sleep if ctx->notify_me, notify + +needs to use seqcst operations for both the write and the read. In +general this is something that we do not want, because there can be +many sources that are polled in addition to bottom halves. The +alternative is to place a seqcst memory barrier between the write +and the read. This also comes with a disadvantage, in that the +memory barrier is implicit on strongly-ordered architectures and +it wastes a few dozen clock cycles. + +Fortunately, ctx->notify_me is never written concurrently by two +threads, so we can assert that and relax the writes to ctx->notify_me. +The resulting solution works and performs well on both aarch64 and x86. + +Note that the atomic_set/atomic_read combination is not an atomic +read-modify-write, and therefore it is even weaker than C11 ATOMIC_RELAXED; +on x86, ATOMIC_RELAXED compiles to a locked operation. + +Analyzed-by: Ying Fang +Signed-off-by: Paolo Bonzini +Tested-by: Ying Fang +Message-Id: <20200407140746.8041-6-pbonzini@redhat.com> +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 5710a3e09f9b85801e5ce70797a4a511e5fc9e2c) +Signed-off-by: Andrew Jones +Signed-off-by: Miroslav Rezanina +--- + util/aio-posix.c | 16 ++++++++++++++-- + util/aio-win32.c | 17 ++++++++++++++--- + util/async.c | 16 ++++++++++++---- + 3 files changed, 40 insertions(+), 9 deletions(-) + +diff --git a/util/aio-posix.c b/util/aio-posix.c +index abc396d030..8cfb25650d 100644 +--- a/util/aio-posix.c ++++ b/util/aio-posix.c +@@ -624,6 +624,11 @@ bool aio_poll(AioContext *ctx, bool blocking) + int64_t timeout; + int64_t start = 0; + ++ /* ++ * There cannot be two concurrent aio_poll calls for the same AioContext (or ++ * an aio_poll concurrent with a GSource prepare/check/dispatch callback). ++ * We rely on this below to avoid slow locked accesses to ctx->notify_me. ++ */ + assert(in_aio_context_home_thread(ctx)); + + /* aio_notify can avoid the expensive event_notifier_set if +@@ -634,7 +639,13 @@ bool aio_poll(AioContext *ctx, bool blocking) + * so disable the optimization now. + */ + if (blocking) { +- atomic_add(&ctx->notify_me, 2); ++ atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2); ++ /* ++ * Write ctx->notify_me before computing the timeout ++ * (reading bottom half flags, etc.). Pairs with ++ * smp_mb in aio_notify(). ++ */ ++ smp_mb(); + } + + qemu_lockcnt_inc(&ctx->list_lock); +@@ -679,7 +690,8 @@ bool aio_poll(AioContext *ctx, bool blocking) + } + + if (blocking) { +- atomic_sub(&ctx->notify_me, 2); ++ /* Finish the poll before clearing the flag. */ ++ atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) - 2); + aio_notify_accept(ctx); + } + +diff --git a/util/aio-win32.c b/util/aio-win32.c +index a23b9c364d..729d533faf 100644 +--- a/util/aio-win32.c ++++ b/util/aio-win32.c +@@ -321,6 +321,12 @@ bool aio_poll(AioContext *ctx, bool blocking) + int count; + int timeout; + ++ /* ++ * There cannot be two concurrent aio_poll calls for the same AioContext (or ++ * an aio_poll concurrent with a GSource prepare/check/dispatch callback). ++ * We rely on this below to avoid slow locked accesses to ctx->notify_me. ++ */ ++ assert(in_aio_context_home_thread(ctx)); + progress = false; + + /* aio_notify can avoid the expensive event_notifier_set if +@@ -331,7 +337,13 @@ bool aio_poll(AioContext *ctx, bool blocking) + * so disable the optimization now. + */ + if (blocking) { +- atomic_add(&ctx->notify_me, 2); ++ atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2); ++ /* ++ * Write ctx->notify_me before computing the timeout ++ * (reading bottom half flags, etc.). Pairs with ++ * smp_mb in aio_notify(). ++ */ ++ smp_mb(); + } + + qemu_lockcnt_inc(&ctx->list_lock); +@@ -364,8 +376,7 @@ bool aio_poll(AioContext *ctx, bool blocking) + ret = WaitForMultipleObjects(count, events, FALSE, timeout); + if (blocking) { + assert(first); +- assert(in_aio_context_home_thread(ctx)); +- atomic_sub(&ctx->notify_me, 2); ++ atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) - 2); + aio_notify_accept(ctx); + } + +diff --git a/util/async.c b/util/async.c +index b1fa5319e5..c65c58bbc9 100644 +--- a/util/async.c ++++ b/util/async.c +@@ -220,7 +220,14 @@ aio_ctx_prepare(GSource *source, gint *timeout) + { + AioContext *ctx = (AioContext *) source; + +- atomic_or(&ctx->notify_me, 1); ++ atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) | 1); ++ ++ /* ++ * Write ctx->notify_me before computing the timeout ++ * (reading bottom half flags, etc.). Pairs with ++ * smp_mb in aio_notify(). ++ */ ++ smp_mb(); + + /* We assume there is no timeout already supplied */ + *timeout = qemu_timeout_ns_to_ms(aio_compute_timeout(ctx)); +@@ -238,7 +245,8 @@ aio_ctx_check(GSource *source) + AioContext *ctx = (AioContext *) source; + QEMUBH *bh; + +- atomic_and(&ctx->notify_me, ~1); ++ /* Finish computing the timeout before clearing the flag. */ ++ atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) & ~1); + aio_notify_accept(ctx); + + for (bh = ctx->first_bh; bh; bh = bh->next) { +@@ -343,10 +351,10 @@ LinuxAioState *aio_get_linux_aio(AioContext *ctx) + void aio_notify(AioContext *ctx) + { + /* Write e.g. bh->scheduled before reading ctx->notify_me. Pairs +- * with atomic_or in aio_ctx_prepare or atomic_add in aio_poll. ++ * with smp_mb in aio_ctx_prepare or aio_poll. + */ + smp_mb(); +- if (ctx->notify_me) { ++ if (atomic_read(&ctx->notify_me)) { + event_notifier_set(&ctx->notifier); + atomic_mb_set(&ctx->notified, true); + } +-- +2.27.0 + diff --git a/SOURCES/kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch b/SOURCES/kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch new file mode 100644 index 0000000..1a20688 --- /dev/null +++ b/SOURCES/kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch @@ -0,0 +1,53 @@ +From 96c8fcafa7325cd0e8a23a743a55f0ad0aa9f79b Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 18 Mar 2021 09:13:42 -0400 +Subject: [PATCH 5/5] audio: audio_generic_get_buffer_in should honor *size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Gerd Hoffmann +Message-id: <20210318091342.3232471-2-kraxel@redhat.com> +Patchwork-id: 101352 +O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] audio: audio_generic_get_buffer_in should honor *size +Bugzilla: 1932823 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Danilo de Paula +RH-Acked-by: Philippe Mathieu-Daudé + +From: Volker Rümelin + +The function generic_get_buffer_in currently ignores the *size +parameter and may return a buffer larger than *size. + +As a result the variable samples in function +audio_pcm_hw_run_in may underflow. The while loop then most +likely will never termiate. + +Buglink: http://bugs.debian.org/948658 +Signed-off-by: Volker Rümelin +Message-Id: <20200123074943.6699-9-vr_qemu@t-online.de> +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 599eac4e5a41e828645594097daee39373acc3c0) +Signed-off-by: Danilo C. L. de Paula +--- + audio/audio.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/audio/audio.c b/audio/audio.c +index 56fae55047..39a62fc62a 100644 +--- a/audio/audio.c ++++ b/audio/audio.c +@@ -1402,7 +1402,8 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size) + } + assert(start >= 0 && start < hw->size_emul); + +- *size = MIN(hw->pending_emul, hw->size_emul - start); ++ *size = MIN(*size, hw->pending_emul); ++ *size = MIN(*size, hw->size_emul - start); + return hw->buf_emul + start; + } + +-- +2.27.0 + diff --git a/SOURCES/kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch b/SOURCES/kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch new file mode 100644 index 0000000..60b1b0a --- /dev/null +++ b/SOURCES/kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch @@ -0,0 +1,76 @@ +From 8c339c3535728179acc94deb5b922aebcfac9ab6 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Thu, 3 Jun 2021 16:13:34 -0400 +Subject: [PATCH 2/4] block/file-posix: Fix problem with fallocate(PUNCH_HOLE) + on GPFS + +RH-Author: Thomas Huth +Message-id: <20210603161334.607005-2-thuth@redhat.com> +Patchwork-id: 101673 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] block/file-posix: Fix problem with fallocate(PUNCH_HOLE) on GPFS +Bugzilla: 1944861 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Max Reitz +RH-Acked-by: Cornelia Huck +RH-Acked-by: Laszlo Ersek + +A customer reported that running + + qemu-img convert -t none -O qcow2 -f qcow2 input.qcow2 output.qcow2 + +fails for them with the following error message when the images are +stored on a GPFS file system : + + qemu-img: error while writing sector 0: Invalid argument + +After analyzing the strace output, it seems like the problem is in +handle_aiocb_write_zeroes(): The call to fallocate(FALLOC_FL_PUNCH_HOLE) +returns EINVAL, which can apparently happen if the file system has +a different idea of the granularity of the operation. It's arguably +a bug in GPFS, since the PUNCH_HOLE mode should not result in EINVAL +according to the man-page of fallocate(), but the file system is out +there in production and so we have to deal with it. In commit 294682cc3a +("block: workaround for unaligned byte range in fallocate()") we also +already applied the a work-around for the same problem to the earlier +fallocate(FALLOC_FL_ZERO_RANGE) call, so do it now similar with the +PUNCH_HOLE call. But instead of silently catching and returning +-ENOTSUP (which causes the caller to fall back to writing zeroes), +let's rather inform the user once about the buggy file system and +try the other fallback instead. + +Signed-off-by: Thomas Huth +Message-Id: <20210527172020.847617-2-thuth@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 73ebf29729d1a40feaa9f8ab8951b6ee6dbfbede) +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1944861 +Signed-off-by: Thomas Huth +Signed-off-by: Danilo C. L. de Paula +--- + block/file-posix.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/block/file-posix.c b/block/file-posix.c +index 62a463229f..371572f1b0 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -1587,6 +1587,17 @@ static int handle_aiocb_write_zeroes(void *opaque) + return ret; + } + s->has_fallocate = false; ++ } else if (ret == -EINVAL) { ++ /* ++ * Some file systems like older versions of GPFS do not like un- ++ * aligned byte ranges, and return EINVAL in such a case, though ++ * they should not do it according to the man-page of fallocate(). ++ * Warn about the bad filesystem and try the final fallback instead. ++ */ ++ warn_report_once("Your file system is misbehaving: " ++ "fallocate(FALLOC_FL_PUNCH_HOLE) returned EINVAL. " ++ "Please report this bug to your file sytem " ++ "vendor."); + } else if (ret != -ENOTSUP) { + return ret; + } else { +-- +2.27.0 + diff --git a/SOURCES/kvm-bootp-check-bootp_input-buffer-size.patch b/SOURCES/kvm-bootp-check-bootp_input-buffer-size.patch new file mode 100644 index 0000000..3362cb0 --- /dev/null +++ b/SOURCES/kvm-bootp-check-bootp_input-buffer-size.patch @@ -0,0 +1,52 @@ +From a66ab346bf74ebf3ed8fca0dc2e2febfe70069e8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:56:28 -0400 +Subject: [PATCH 07/14] bootp: check bootp_input buffer size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210708082537.1550263-4-marcandre.lureau@redhat.com> +Patchwork-id: 101820 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 3/8] bootp: check bootp_input buffer size +Bugzilla: 1970819 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +From: Marc-André Lureau + +Fixes: CVE-2021-3592 +Fixes: https://gitlab.freedesktop.org/slirp/libslirp/-/issues/44 + +Signed-off-by: Marc-André Lureau + +BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1970819 + +(cherry picked from commit 2eca0838eee1da96204545e22cdaed860d9d7c6c) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/src/bootp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/slirp/src/bootp.c b/slirp/src/bootp.c +index 5754327138..5789187166 100644 +--- a/slirp/src/bootp.c ++++ b/slirp/src/bootp.c +@@ -366,9 +366,9 @@ udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); + + void bootp_input(struct mbuf *m) + { +- struct bootp_t *bp = mtod(m, struct bootp_t *); ++ struct bootp_t *bp = mtod_check(m, sizeof(struct bootp_t)); + +- if (bp->bp_op == BOOTP_REQUEST) { ++ if (bp && bp->bp_op == BOOTP_REQUEST) { + bootp_reply(m->slirp, bp, m_end(m)); + } + } +-- +2.27.0 + diff --git a/SOURCES/kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch b/SOURCES/kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch new file mode 100644 index 0000000..bbf9b03 --- /dev/null +++ b/SOURCES/kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch @@ -0,0 +1,175 @@ +From 8198ae7c21a4d37f7e365058f973867c41d44d21 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:56:25 -0400 +Subject: [PATCH 06/14] bootp: limit vendor-specific area to input packet + memory buffer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210708082537.1550263-3-marcandre.lureau@redhat.com> +Patchwork-id: 101821 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/8] bootp: limit vendor-specific area to input packet memory buffer +Bugzilla: 1970819 1970835 1970843 1970853 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +From: Marc-André Lureau + +sizeof(bootp_t) currently holds DHCP_OPT_LEN. Remove this optional field +from the structure, to help with the following patch checking for +minimal header size. Modify the bootp_reply() function to take the +buffer boundaries and avoiding potential buffer overflow. + +Related to CVE-2021-3592. + +https://gitlab.freedesktop.org/slirp/libslirp/-/issues/44 + +Signed-off-by: Marc-André Lureau + +(cherry picked from commit f13cad45b25d92760bb0ad67bec0300a4d7d5275) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/src/bootp.c | 26 +++++++++++++++----------- + slirp/src/bootp.h | 2 +- + slirp/src/mbuf.c | 5 +++++ + slirp/src/mbuf.h | 1 + + 4 files changed, 22 insertions(+), 12 deletions(-) + +diff --git a/slirp/src/bootp.c b/slirp/src/bootp.c +index 3f9ce2553e..5754327138 100644 +--- a/slirp/src/bootp.c ++++ b/slirp/src/bootp.c +@@ -92,21 +92,22 @@ found: + return bc; + } + +-static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type, ++static void dhcp_decode(const struct bootp_t *bp, ++ const uint8_t *bp_end, ++ int *pmsg_type, + struct in_addr *preq_addr) + { +- const uint8_t *p, *p_end; ++ const uint8_t *p; + int len, tag; + + *pmsg_type = 0; + preq_addr->s_addr = htonl(0L); + + p = bp->bp_vend; +- p_end = p + DHCP_OPT_LEN; + if (memcmp(p, rfc1533_cookie, 4) != 0) + return; + p += 4; +- while (p < p_end) { ++ while (p < bp_end) { + tag = p[0]; + if (tag == RFC1533_PAD) { + p++; +@@ -114,10 +115,10 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type, + break; + } else { + p++; +- if (p >= p_end) ++ if (p >= bp_end) + break; + len = *p++; +- if (p + len > p_end) { ++ if (p + len > bp_end) { + break; + } + DPRINTF("dhcp: tag=%d len=%d\n", tag, len); +@@ -144,7 +145,9 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type, + } + } + +-static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) ++static void bootp_reply(Slirp *slirp, ++ const struct bootp_t *bp, ++ const uint8_t *bp_end) + { + BOOTPClient *bc = NULL; + struct mbuf *m; +@@ -157,7 +160,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) + uint8_t client_ethaddr[ETH_ALEN]; + + /* extract exact DHCP msg type */ +- dhcp_decode(bp, &dhcp_msg_type, &preq_addr); ++ dhcp_decode(bp, bp_end, &dhcp_msg_type, &preq_addr); + DPRINTF("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type); + if (preq_addr.s_addr != htonl(0L)) + DPRINTF(" req_addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr)); +@@ -179,9 +182,10 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) + return; + } + m->m_data += IF_MAXLINKHDR; ++ m_inc(m, sizeof(struct bootp_t) + DHCP_OPT_LEN); + rbp = (struct bootp_t *)m->m_data; + m->m_data += sizeof(struct udpiphdr); +- memset(rbp, 0, sizeof(struct bootp_t)); ++ memset(rbp, 0, sizeof(struct bootp_t) + DHCP_OPT_LEN); + + if (dhcp_msg_type == DHCPDISCOVER) { + if (preq_addr.s_addr != htonl(0L)) { +@@ -235,7 +239,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) + rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ + + q = rbp->bp_vend; +- end = (uint8_t *)&rbp[1]; ++ end = rbp->bp_vend + DHCP_OPT_LEN; + memcpy(q, rfc1533_cookie, 4); + q += 4; + +@@ -365,6 +369,6 @@ void bootp_input(struct mbuf *m) + struct bootp_t *bp = mtod(m, struct bootp_t *); + + if (bp->bp_op == BOOTP_REQUEST) { +- bootp_reply(m->slirp, bp); ++ bootp_reply(m->slirp, bp, m_end(m)); + } + } +diff --git a/slirp/src/bootp.h b/slirp/src/bootp.h +index 03ece9bf28..0d20a944a8 100644 +--- a/slirp/src/bootp.h ++++ b/slirp/src/bootp.h +@@ -114,7 +114,7 @@ struct bootp_t { + uint8_t bp_hwaddr[16]; + uint8_t bp_sname[64]; + uint8_t bp_file[128]; +- uint8_t bp_vend[DHCP_OPT_LEN]; ++ uint8_t bp_vend[]; + }; + + typedef struct { +diff --git a/slirp/src/mbuf.c b/slirp/src/mbuf.c +index 6d0653ed3d..7db07c088e 100644 +--- a/slirp/src/mbuf.c ++++ b/slirp/src/mbuf.c +@@ -233,3 +233,8 @@ void *mtod_check(struct mbuf *m, size_t len) + + return NULL; + } ++ ++void *m_end(struct mbuf *m) ++{ ++ return m->m_data + m->m_len; ++} +diff --git a/slirp/src/mbuf.h b/slirp/src/mbuf.h +index 2015e3232f..a9752a36e0 100644 +--- a/slirp/src/mbuf.h ++++ b/slirp/src/mbuf.h +@@ -119,6 +119,7 @@ void m_adj(struct mbuf *, int); + int m_copy(struct mbuf *, struct mbuf *, int, int); + struct mbuf *dtom(Slirp *, void *); + void *mtod_check(struct mbuf *, size_t len); ++void *m_end(struct mbuf *); + + static inline void ifs_init(struct mbuf *ifm) + { +-- +2.27.0 + diff --git a/SOURCES/kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch b/SOURCES/kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch index 4316d69..32d5377 100644 --- a/SOURCES/kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch +++ b/SOURCES/kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch @@ -1,4 +1,4 @@ -From 1cbb554a4057afd4d71c04757ef7fd1bbb7114ee Mon Sep 17 00:00:00 2001 +From 6f1ebcfdb92d12ef2caae0b63a3a380265cba1fa Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:46 -0400 Subject: [PATCH 8/9] cadence_gem: switch to use qemu_receive_packet() for diff --git a/SOURCES/kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch b/SOURCES/kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch index a100b0c..77e99eb 100644 --- a/SOURCES/kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch +++ b/SOURCES/kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch @@ -1,4 +1,4 @@ -From 4044e97e37188a9844cc6cd66d8b7819acccb27e Mon Sep 17 00:00:00 2001 +From a6f0bef82cdd84844a06dac1e6d279d95824d827 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:41 -0400 Subject: [PATCH 3/9] dp8393x: switch to use qemu_receive_packet() for loopback diff --git a/SOURCES/kvm-e1000-fail-early-for-evil-descriptor.patch b/SOURCES/kvm-e1000-fail-early-for-evil-descriptor.patch new file mode 100644 index 0000000..e599b7c --- /dev/null +++ b/SOURCES/kvm-e1000-fail-early-for-evil-descriptor.patch @@ -0,0 +1,65 @@ +From 7bd3000cf22a91e6bc6afc1e7adbf0ae1b731104 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Tue, 13 Apr 2021 22:45:17 -0400 +Subject: [PATCH 2/5] e1000: fail early for evil descriptor + +RH-Author: Jon Maloy +Message-id: <20210413224517.3841507-2-jmaloy@redhat.com> +Patchwork-id: 101473 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] e1000: fail early for evil descriptor +Bugzilla: 1930092 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Stefan Hajnoczi + +From: Jason Wang + +During procss_tx_desc(), driver can try to chain data descriptor with +legacy descriptor, when will lead underflow for the following +calculation in process_tx_desc() for bytes: + + if (tp->size + bytes > msh) + bytes = msh - tp->size; + +This will lead a infinite loop. So check and fail early if tp->size if +greater or equal to msh. + +Reported-by: Alexander Bulekov +Reported-by: Cheolwoo Myung +Reported-by: Ruhr-University Bochum +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Signed-off-by: Jason Wang + +(cherry picked from commit 3de46e6fc489c52c9431a8a832ad8170a7569bd8) +Signed-off-by: Jon Maloy +Signed-off-by: Danilo C. L. de Paula +--- + hw/net/e1000.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/hw/net/e1000.c b/hw/net/e1000.c +index fc73fdd6fa..fe56bccd52 100644 +--- a/hw/net/e1000.c ++++ b/hw/net/e1000.c +@@ -671,6 +671,9 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) + msh = tp->tso_props.hdr_len + tp->tso_props.mss; + do { + bytes = split_size; ++ if (tp->size >= msh) { ++ goto eop; ++ } + if (tp->size + bytes > msh) + bytes = msh - tp->size; + +@@ -696,6 +699,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) + tp->size += split_size; + } + ++eop: + if (!(txd_lower & E1000_TXD_CMD_EOP)) + return; + if (!(tp->cptse && tp->size < tp->tso_props.hdr_len)) { +-- +2.27.0 + diff --git a/SOURCES/kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch b/SOURCES/kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch index b2a211f..05ff372 100644 --- a/SOURCES/kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch +++ b/SOURCES/kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch @@ -1,4 +1,4 @@ -From bf44928b2ac2cb8b9608209d5425533458fd2b8a Mon Sep 17 00:00:00 2001 +From 128b97f6049144af3c1a41ceb8e8583419edcd69 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:40 -0400 Subject: [PATCH 2/9] e1000: switch to use qemu_receive_packet() for loopback @@ -35,7 +35,7 @@ Signed-off-by: Danilo C. L. de Paula 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/e1000.c b/hw/net/e1000.c -index fc73fdd6fa..f6ae78748a 100644 +index fe56bccd52..8680b7d46b 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -547,7 +547,7 @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size) diff --git a/SOURCES/kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch b/SOURCES/kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch new file mode 100644 index 0000000..ac7b859 --- /dev/null +++ b/SOURCES/kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch @@ -0,0 +1,59 @@ +From 94d99b13b48e922861570f043490efc966b3b445 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 25 Jun 2021 17:41:04 -0400 +Subject: [PATCH 4/4] file-posix: Handle `EINVAL` fallocate return value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Kevin Wolf +Message-id: <20210625174104.44313-3-kwolf@redhat.com> +Patchwork-id: 101778 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] file-posix: Handle `EINVAL` fallocate return value +Bugzilla: 1970912 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +From: Antoine Damhet + +The `detect-zeroes=unmap` option may issue unaligned +`FALLOC_FL_PUNCH_HOLE` requests, raw block devices can (and will) return +`EINVAL`, qemu should then write the zeroes to the blockdev instead of +issuing an `IO_ERROR`. + +The problem can be reprodced like this: + +$ qemu-io -c 'write -P 0 42 1234' --image-opts driver=host_device,filename=/dev/loop0,detect-zeroes=unmap +write failed: Invalid argument + +Signed-off-by: Antoine Damhet +Message-Id: <20200717135603.51180-1-antoine.damhet@blade-group.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit bae127d4dcf6158c5042e2eee9582430839a9967) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/file-posix.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/block/file-posix.c b/block/file-posix.c +index 837edcf027..6cd19e6c9a 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -1632,7 +1632,11 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque) + #ifdef CONFIG_FALLOCATE_PUNCH_HOLE + int ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + aiocb->aio_offset, aiocb->aio_nbytes); +- if (ret != -ENOTSUP) { ++ switch (ret) { ++ case -ENOTSUP: ++ case -EINVAL: ++ break; ++ default: + return ret; + } + #endif +-- +2.27.0 + diff --git a/SOURCES/kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch b/SOURCES/kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch new file mode 100644 index 0000000..e8639f3 --- /dev/null +++ b/SOURCES/kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch @@ -0,0 +1,466 @@ +From 7ee01b5ccb7fc660dafaf3fdb1578649d17fbddf Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 26 May 2021 09:05:52 -0400 +Subject: [PATCH 1/4] file-posix: Mitigate file fragmentation with extent size + hints + +RH-Author: Kevin Wolf +Message-id: <20210526090552.155820-2-kwolf@redhat.com> +Patchwork-id: 101638 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] file-posix: Mitigate file fragmentation with extent size hints +Bugzilla: 1877163 +RH-Acked-by: Sergio Lopez Pascual +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Max Reitz + +Especially when O_DIRECT is used with image files so that the page cache +indirection can't cause a merge of allocating requests, the file will +fragment on the file system layer, with a potentially very small +fragment size (this depends on the requests the guest sent). + +On Linux, fragmentation can be reduced by setting an extent size hint +when creating the file (at least on XFS, it can't be set any more after +the first extent has been allocated), basically giving raw files a +"cluster size" for allocation. + +This adds a create option to set the extent size hint, and changes the +default from not setting a hint to setting it to 1 MB. The main reason +why qcow2 defaults to smaller cluster sizes is that COW becomes more +expensive, which is not an issue with raw files, so we can choose a +larger size. The tradeoff here is only potentially wasted disk space. + +For qcow2 (or other image formats) over file-posix, the advantage should +even be greater because they grow sequentially without leaving holes, so +there won't be wasted space. Setting even larger extent size hints for +such images may make sense. This can be done with the new option, but +let's keep the default conservative for now. + +The effect is very visible with a test that intentionally creates a +badly fragmented file with qemu-img bench (the time difference while +creating the file is already remarkable) and then looks at the number of +extents and the time a simple "qemu-img map" takes. + +Without an extent size hint: + + $ ./qemu-img create -f raw -o extent_size_hint=0 ~/tmp/test.raw 10G + Formatting '/home/kwolf/tmp/test.raw', fmt=raw size=10737418240 extent_size_hint=0 + $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 1000000 -S 8192 -o 0 + Sending 1000000 write requests, 4096 bytes each, 64 in parallel (starting at offset 0, step size 8192) + Run completed in 25.848 seconds. + $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 1000000 -S 8192 -o 4096 + Sending 1000000 write requests, 4096 bytes each, 64 in parallel (starting at offset 4096, step size 8192) + Run completed in 19.616 seconds. + $ filefrag ~/tmp/test.raw + /home/kwolf/tmp/test.raw: 2000000 extents found + $ time ./qemu-img map ~/tmp/test.raw + Offset Length Mapped to File + 0 0x1e8480000 0 /home/kwolf/tmp/test.raw + + real 0m1,279s + user 0m0,043s + sys 0m1,226s + +With the new default extent size hint of 1 MB: + + $ ./qemu-img create -f raw -o extent_size_hint=1M ~/tmp/test.raw 10G + Formatting '/home/kwolf/tmp/test.raw', fmt=raw size=10737418240 extent_size_hint=1048576 + $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 1000000 -S 8192 -o 0 + Sending 1000000 write requests, 4096 bytes each, 64 in parallel (starting at offset 0, step size 8192) + Run completed in 11.833 seconds. + $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 1000000 -S 8192 -o 4096 + Sending 1000000 write requests, 4096 bytes each, 64 in parallel (starting at offset 4096, step size 8192) + Run completed in 10.155 seconds. + $ filefrag ~/tmp/test.raw + /home/kwolf/tmp/test.raw: 178 extents found + $ time ./qemu-img map ~/tmp/test.raw + Offset Length Mapped to File + 0 0x1e8480000 0 /home/kwolf/tmp/test.raw + + real 0m0,061s + user 0m0,040s + sys 0m0,014s + +Signed-off-by: Kevin Wolf +Message-Id: <20200707142329.48303-1-kwolf@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit ffa244c84a1a30dff69ecc80b0137a2b6d428ecb) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/file-posix.c | 44 ++++++++++++++++++++++++++++++++ + include/block/block_int.h | 1 + + qapi/block-core.json | 11 +++++--- + tests/qemu-iotests/082.out | 16 ++++++++++++ + tests/qemu-iotests/106 | 7 +++-- + tests/qemu-iotests/175 | 6 ++--- + tests/qemu-iotests/243 | 6 ++--- + tests/qemu-iotests/common.filter | 1 + + 8 files changed, 80 insertions(+), 12 deletions(-) + +diff --git a/block/file-posix.c b/block/file-posix.c +index 2d834fbdf6..62a463229f 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -30,6 +30,7 @@ + #include "block/block_int.h" + #include "qemu/module.h" + #include "qemu/option.h" ++#include "qemu/units.h" + #include "trace.h" + #include "block/thread-pool.h" + #include "qemu/iov.h" +@@ -2289,6 +2290,14 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) + if (!file_opts->has_preallocation) { + file_opts->preallocation = PREALLOC_MODE_OFF; + } ++ if (!file_opts->has_extent_size_hint) { ++ file_opts->extent_size_hint = 1 * MiB; ++ } ++ if (file_opts->extent_size_hint > UINT32_MAX) { ++ result = -EINVAL; ++ error_setg(errp, "Extent size hint is too large"); ++ goto out; ++ } + + /* Create file */ + fd = qemu_open(file_opts->filename, O_RDWR | O_CREAT | O_BINARY, 0644); +@@ -2346,6 +2355,27 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) + } + #endif + } ++#ifdef FS_IOC_FSSETXATTR ++ /* ++ * Try to set the extent size hint. Failure is not fatal, and a warning is ++ * only printed if the option was explicitly specified. ++ */ ++ { ++ struct fsxattr attr; ++ result = ioctl(fd, FS_IOC_FSGETXATTR, &attr); ++ if (result == 0) { ++ attr.fsx_xflags |= FS_XFLAG_EXTSIZE; ++ attr.fsx_extsize = file_opts->extent_size_hint; ++ result = ioctl(fd, FS_IOC_FSSETXATTR, &attr); ++ } ++ if (result < 0 && file_opts->has_extent_size_hint && ++ file_opts->extent_size_hint) ++ { ++ warn_report("Failed to set extent size hint: %s", ++ strerror(errno)); ++ } ++ } ++#endif + + /* Resize and potentially preallocate the file to the desired + * final size */ +@@ -2381,6 +2411,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv, + { + BlockdevCreateOptions options; + int64_t total_size = 0; ++ int64_t extent_size_hint = 0; ++ bool has_extent_size_hint = false; + bool nocow = false; + PreallocMode prealloc; + char *buf = NULL; +@@ -2392,6 +2424,11 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv, + /* Read out options */ + total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); ++ if (qemu_opt_get(opts, BLOCK_OPT_EXTENT_SIZE_HINT)) { ++ has_extent_size_hint = true; ++ extent_size_hint = ++ qemu_opt_get_size_del(opts, BLOCK_OPT_EXTENT_SIZE_HINT, -1); ++ } + nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false); + buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); + prealloc = qapi_enum_parse(&PreallocMode_lookup, buf, +@@ -2411,6 +2448,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv, + .preallocation = prealloc, + .has_nocow = true, + .nocow = nocow, ++ .has_extent_size_hint = has_extent_size_hint, ++ .extent_size_hint = extent_size_hint, + }, + }; + return raw_co_create(&options, errp); +@@ -2902,6 +2941,11 @@ static QemuOptsList raw_create_opts = { + #endif + ", full)" + }, ++ { ++ .name = BLOCK_OPT_EXTENT_SIZE_HINT, ++ .type = QEMU_OPT_SIZE, ++ .help = "Extent size hint for the image file, 0 to disable" ++ }, + { /* end of list */ } + } + }; +diff --git a/include/block/block_int.h b/include/block/block_int.h +index 41f13ecbed..4b23da2eb0 100644 +--- a/include/block/block_int.h ++++ b/include/block/block_int.h +@@ -53,6 +53,7 @@ + #define BLOCK_OPT_ADAPTER_TYPE "adapter_type" + #define BLOCK_OPT_REDUNDANCY "redundancy" + #define BLOCK_OPT_NOCOW "nocow" ++#define BLOCK_OPT_EXTENT_SIZE_HINT "extent_size_hint" + #define BLOCK_OPT_OBJECT_SIZE "object_size" + #define BLOCK_OPT_REFCOUNT_BITS "refcount_bits" + #define BLOCK_OPT_DATA_FILE "data_file" +diff --git a/qapi/block-core.json b/qapi/block-core.json +index 289320902d..c7aa919fa3 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -4272,14 +4272,17 @@ + # falloc (if defined CONFIG_POSIX_FALLOCATE), + # full (if defined CONFIG_POSIX)) + # @nocow Turn off copy-on-write (valid only on btrfs; default: off) ++# @extent-size-hint: Extent size hint to add to the image file; 0 for not ++# adding an extent size hint (default: 1 MB, since 5.1) + # + # Since: 2.12 + ## + { 'struct': 'BlockdevCreateOptionsFile', +- 'data': { 'filename': 'str', +- 'size': 'size', +- '*preallocation': 'PreallocMode', +- '*nocow': 'bool' } } ++ 'data': { 'filename': 'str', ++ 'size': 'size', ++ '*preallocation': 'PreallocMode', ++ '*nocow': 'bool', ++ '*extent-size-hint': 'size'} } + + ## + # @BlockdevCreateOptionsGluster: +diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out +index 9d4ed4dc9d..7a87946fa2 100644 +--- a/tests/qemu-iotests/082.out ++++ b/tests/qemu-iotests/082.out +@@ -59,6 +59,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -82,6 +83,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -105,6 +107,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -128,6 +131,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -151,6 +155,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -174,6 +179,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -197,6 +203,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -220,6 +227,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -339,6 +347,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -362,6 +371,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -385,6 +395,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -408,6 +419,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -431,6 +443,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -454,6 +467,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -477,6 +491,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +@@ -500,6 +515,7 @@ Supported options: + encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm + encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase + encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) ++ extent_size_hint= - Extent size hint for the image file, 0 to disable + lazy_refcounts= - Postpone refcount updates + nocow= - Turn off copy-on-write (valid only on btrfs) + preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) +diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106 +index ac47eaa0f5..ee6f51d08b 100755 +--- a/tests/qemu-iotests/106 ++++ b/tests/qemu-iotests/106 +@@ -51,7 +51,10 @@ for create_mode in off falloc full; do + echo + echo "--- create_mode=$create_mode growth_mode=$growth_mode ---" + +- IMGOPTS="preallocation=$create_mode" _make_test_img ${CREATION_SIZE}K ++ # Our calculation below assumes kilobytes as unit for the actual size. ++ # Disable the extent size hint because it would give us a result in ++ # megabytes. ++ IMGOPTS="preallocation=$create_mode,extent_size_hint=0" _make_test_img ${CREATION_SIZE}K + $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K + + expected_size=0 +@@ -98,7 +101,7 @@ for growth_mode in falloc full; do + # plain int. We should use the correct type for the result, and + # this tests we do. + +- _make_test_img 2G ++ _make_test_img -o "extent_size_hint=0" 2G + $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K + + actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size') +diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175 +index 55db2803ed..8a8494aeb6 100755 +--- a/tests/qemu-iotests/175 ++++ b/tests/qemu-iotests/175 +@@ -89,20 +89,20 @@ min_blocks=$(stat -c '%b' "$TEST_DIR/empty") + + echo + echo "== creating image with default preallocation ==" +-_make_test_img $size | _filter_imgfmt ++_make_test_img -o extent_size_hint=0 $size | _filter_imgfmt + stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size + + for mode in off full falloc; do + echo + echo "== creating image with preallocation $mode ==" +- IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt ++ IMGOPTS="preallocation=$mode,extent_size_hint=0" _make_test_img $size | _filter_imgfmt + stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size + done + + for new_size in 4096 1048576; do + echo + echo "== resize empty image with block_resize ==" +- _make_test_img 0 | _filter_imgfmt ++ _make_test_img -o extent_size_hint=0 0 | _filter_imgfmt + _block_resize $TEST_IMG $new_size >/dev/null + stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $new_size + done +diff --git a/tests/qemu-iotests/243 b/tests/qemu-iotests/243 +index e563761307..104c7256c4 100755 +--- a/tests/qemu-iotests/243 ++++ b/tests/qemu-iotests/243 +@@ -47,7 +47,7 @@ for mode in off metadata falloc full; do + echo "=== preallocation=$mode ===" + echo + +- IMGOPTS="preallocation=$mode" _make_test_img 64M ++ IMGOPTS="preallocation=$mode,extent_size_hint=0" _make_test_img 64M + + printf "File size: " + du -b $TEST_IMG | cut -f1 +@@ -64,7 +64,7 @@ for mode in off metadata falloc full; do + echo "=== External data file: preallocation=$mode ===" + echo + +- IMGOPTS="data_file=$TEST_IMG.data,preallocation=$mode" _make_test_img 64M ++ IMGOPTS="data_file=$TEST_IMG.data,preallocation=$mode,extent_size_hint=0" _make_test_img 64M + + echo -n "qcow2 file size: " + du -b $TEST_IMG | cut -f1 +@@ -75,7 +75,7 @@ for mode in off metadata falloc full; do + echo -n "qcow2 disk usage: " + [ $(du -B1 $TEST_IMG | cut -f1) -lt 1048576 ] && echo "low" || echo "high" + echo -n "data disk usage: " +- [ $(du -B1 $TEST_IMG.data | cut -f1) -lt 1048576 ] && echo "low" || echo "high" ++ [ $(du -B1 $TEST_IMG.data | cut -f1) -lt 2097152 ] && echo "low" || echo "high" + + done + +diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter +index c8e8663665..f29c1d3238 100644 +--- a/tests/qemu-iotests/common.filter ++++ b/tests/qemu-iotests/common.filter +@@ -146,6 +146,7 @@ _filter_img_create() + -e "s# refcount_bits=[0-9]\\+##g" \ + -e "s# key-secret=[a-zA-Z0-9]\\+##g" \ + -e "s# iter-time=[0-9]\\+##g" \ ++ -e "s# extent_size_hint=[0-9]\\+##g" \ + -e "s# force_size=\\(on\\|off\\)##g" + } + +-- +2.27.0 + diff --git a/SOURCES/kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch b/SOURCES/kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch new file mode 100644 index 0000000..551b2eb --- /dev/null +++ b/SOURCES/kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch @@ -0,0 +1,89 @@ +From 15331267d11713906361ddd767c3e04ae46d9a83 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:55:50 -0400 +Subject: [PATCH 01/14] glib-compat: add g_unix_get_passwd_entry_qemu() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210609100615.2501448-2-marcandre.lureau@redhat.com> +Patchwork-id: 101687 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/4] glib-compat: add g_unix_get_passwd_entry_qemu() +Bugzilla: 1967716 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Michal Privoznik + +From: Marc-André Lureau + +The glib function was introduced in 2.64. It's a safer version of +getpwnam, and also simpler to use than getpwnam_r. + +Currently, it's only use by the next patch in qemu-ga, which doesn't +(well well...) need the thread safety guarantees. Since the fallback +version is still unsafe, I would rather keep the _qemu postfix, to make +sure it's not being misused by mistake. When/if necessary, we can +implement a safer fallback and drop the _qemu suffix. + +Signed-off-by: Marc-André Lureau +Reviewed-by: Michal Privoznik +*fix checkpatch warnings about newlines before/after block comments +Signed-off-by: Michael Roth + +(cherry picked from commit 6d593ab451c490b0ca941c6a519894231634751e) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + include/glib-compat.h | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/include/glib-compat.h b/include/glib-compat.h +index 0b0ec76299..695a96f7ea 100644 +--- a/include/glib-compat.h ++++ b/include/glib-compat.h +@@ -30,6 +30,11 @@ + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + + #include ++#if defined(G_OS_UNIX) ++#include ++#include ++#include ++#endif + + /* + * Note that because of the GLIB_VERSION_MAX_ALLOWED constant above, allowing +@@ -72,6 +77,29 @@ + gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout); + #endif + ++#if defined(G_OS_UNIX) ++/* ++ * Note: The fallback implementation is not MT-safe, and it returns a copy of ++ * the libc passwd (must be g_free() after use) but not the content. Because of ++ * these important differences the caller must be aware of, it's not #define for ++ * GLib API substitution. ++ */ ++static inline struct passwd * ++g_unix_get_passwd_entry_qemu(const gchar *user_name, GError **error) ++{ ++#if GLIB_CHECK_VERSION(2, 64, 0) ++ return g_unix_get_passwd_entry(user_name, error); ++#else ++ struct passwd *p = getpwnam(user_name); ++ if (!p) { ++ g_set_error_literal(error, G_UNIX_ERROR, 0, g_strerror(errno)); ++ return NULL; ++ } ++ return (struct passwd *)g_memdup(p, sizeof(*p)); ++#endif ++} ++#endif /* G_OS_UNIX */ ++ + #pragma GCC diagnostic pop + + #endif +-- +2.27.0 + diff --git a/SOURCES/kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch b/SOURCES/kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch index d63b7ed..650555c 100644 --- a/SOURCES/kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch +++ b/SOURCES/kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch @@ -1,18 +1,18 @@ -From fd46dd1555e5955cf55b463ef126cf5cfac1d7ae Mon Sep 17 00:00:00 2001 +From dad4f9beaa3fd1eec1e0dd46c3d5cd2f444c0f48 Mon Sep 17 00:00:00 2001 From: Jon Maloy -Date: Fri, 21 May 2021 23:04:32 -0400 -Subject: [PATCH 8/8] hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register +Date: Tue, 13 Apr 2021 20:05:51 -0400 +Subject: [PATCH 1/7] hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Jon Maloy -Message-id: <20210521230432.585518-2-jmaloy@redhat.com> -Patchwork-id: 101625 -O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register -Bugzilla: 1952986 -RH-Acked-by: Danilo de Paula -RH-Acked-by: Stefano Garzarella +Message-id: <20210413200551.3825495-2-jmaloy@redhat.com> +Patchwork-id: 101471 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register +Bugzilla: 1925430 +RH-Acked-by: Andrew Jones +RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Philippe Mathieu-Daudé From: Philippe Mathieu-Daudé diff --git a/SOURCES/kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch b/SOURCES/kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch index 11fac16..902af6c 100644 --- a/SOURCES/kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch +++ b/SOURCES/kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch @@ -1,4 +1,4 @@ -From 0438b497def59f2101864d79a20e50b896ae1870 Mon Sep 17 00:00:00 2001 +From e2cafb929acb74377754cb688419575b139b922a Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:47 -0400 Subject: [PATCH 9/9] lan9118: switch to use qemu_receive_packet() for loopback diff --git a/SOURCES/kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch b/SOURCES/kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch index b9781d0..71a2eac 100644 --- a/SOURCES/kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch +++ b/SOURCES/kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch @@ -1,7 +1,7 @@ -From 17813233c9bb5c93c7f3c7fc350641f8e76e769c Mon Sep 17 00:00:00 2001 +From 2687e0348e3e4d377b4f5356e46948dc2b371b6d Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Wed, 21 Apr 2021 22:30:02 -0400 -Subject: [PATCH 3/8] libqos: pci-pc: use 32-bit write for EJ register +Subject: [PATCH 3/7] libqos: pci-pc: use 32-bit write for EJ register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -10,7 +10,7 @@ RH-Author: Jon Maloy Message-id: <20210421223006.19650-3-jmaloy@redhat.com> Patchwork-id: 101484 O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 2/6] libqos: pci-pc: use 32-bit write for EJ register -Bugzilla: 1944621 +Bugzilla: 1842478 RH-Acked-by: Stefano Garzarella RH-Acked-by: Philippe Mathieu-Daudé RH-Acked-by: Laszlo Ersek diff --git a/SOURCES/kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch b/SOURCES/kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch index 1406231..424a60c 100644 --- a/SOURCES/kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch +++ b/SOURCES/kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch @@ -1,7 +1,7 @@ -From 9c10bd2a3cd83c06add41e61a970da304fb0d3bf Mon Sep 17 00:00:00 2001 +From 6320b4e76965b1cf64da4307f4d313fe6b2aa971 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Wed, 21 Apr 2021 22:30:01 -0400 -Subject: [PATCH 2/8] libqos: usb-hcd-ehci: use 32-bit write for config +Subject: [PATCH 2/7] libqos: usb-hcd-ehci: use 32-bit write for config register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -11,7 +11,7 @@ RH-Author: Jon Maloy Message-id: <20210421223006.19650-2-jmaloy@redhat.com> Patchwork-id: 101478 O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 1/6] libqos: usb-hcd-ehci: use 32-bit write for config register -Bugzilla: 1944621 +Bugzilla: 1842478 RH-Acked-by: Stefano Garzarella RH-Acked-by: Philippe Mathieu-Daudé RH-Acked-by: Laszlo Ersek diff --git a/SOURCES/kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch b/SOURCES/kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch new file mode 100644 index 0000000..d9c81cf --- /dev/null +++ b/SOURCES/kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch @@ -0,0 +1,43 @@ +From f844ca939adb619cce8426e104b0039a7eba70a6 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Tue, 11 May 2021 11:24:04 -0400 +Subject: [PATCH 1/5] linux-headers: Add VFIO_CCW_REQ_IRQ_INDEX + +RH-Author: Thomas Huth +Message-id: <20210511112405.297037-2-thuth@redhat.com> +Patchwork-id: 101537 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] linux-headers: Add VFIO_CCW_REQ_IRQ_INDEX +Bugzilla: 1940450 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Cornelia Huck +RH-Acked-by: David Hildenbrand + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940450 +Upstream-status: N/A + +This is based on upstream commit b3c818a47f ("Update linux headers to +5.11-rc2"), but has been reduced to the single hunk that is required +for the next patch (there were too many unrelated conflicts in the other +files for doing full backport of the original upstream commit). + +Signed-off-by: Thomas Huth +Signed-off-by: Danilo C. L. de Paula +--- + linux-headers/linux/vfio.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h +index f660bd7bac..9c8810bef4 100644 +--- a/linux-headers/linux/vfio.h ++++ b/linux-headers/linux/vfio.h +@@ -580,6 +580,7 @@ enum { + enum { + VFIO_CCW_IO_IRQ_INDEX, + VFIO_CCW_CRW_IRQ_INDEX, ++ VFIO_CCW_REQ_IRQ_INDEX, + VFIO_CCW_NUM_IRQS + }; + +-- +2.27.0 + diff --git a/SOURCES/kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch b/SOURCES/kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch index eff9682..f81c86f 100644 --- a/SOURCES/kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch +++ b/SOURCES/kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch @@ -1,7 +1,7 @@ -From e4010373c72eab2342d2ba7f10c1ddf43dc618c8 Mon Sep 17 00:00:00 2001 +From 13f4ebe4708f4f4dc20d710e475a42d520459860 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Wed, 21 Apr 2021 22:30:03 -0400 -Subject: [PATCH 4/8] memory: Revert "memory: accept mismatching sizes in +Subject: [PATCH 4/7] memory: Revert "memory: accept mismatching sizes in memory_region_access_valid" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -11,7 +11,7 @@ RH-Author: Jon Maloy Message-id: <20210421223006.19650-4-jmaloy@redhat.com> Patchwork-id: 101480 O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 3/6] memory: Revert "memory: accept mismatching sizes in memory_region_access_valid" -Bugzilla: 1944621 +Bugzilla: 1842478 RH-Acked-by: Stefano Garzarella RH-Acked-by: Philippe Mathieu-Daudé RH-Acked-by: Laszlo Ersek diff --git a/SOURCES/kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch b/SOURCES/kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch new file mode 100644 index 0000000..654a64f --- /dev/null +++ b/SOURCES/kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch @@ -0,0 +1,301 @@ +From 512c7e92808dff66779f7421f1c17a081f18d7e6 Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Thu, 29 Jul 2021 04:56:46 -0400 +Subject: [PATCH 13/14] net: check if the file descriptor is valid before using + it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +Message-id: <20210726102337.6359-2-lvivier@redhat.com> +Patchwork-id: 101924 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] net: check if the file descriptor is valid before using it +Bugzilla: 1982134 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Philippe Mathieu-Daudé + +BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1982134 +BRANCH: rhel-8.5.0 +UPSTREAM: Merged +BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=38380653 + +qemu_set_nonblock() checks that the file descriptor can be used and, if +not, crashes QEMU. An assert() is used for that. The use of assert() is +used to detect programming error and the coredump will allow to debug +the problem. + +But in the case of the tap device, this assert() can be triggered by +a misconfiguration by the user. At startup, it's not a real problem, but it +can also happen during the hot-plug of a new device, and here it's a +problem because we can crash a perfectly healthy system. + +For instance: + # ip link add link virbr0 name macvtap0 type macvtap mode bridge + # ip link set macvtap0 up + # TAP=/dev/tap$(ip -o link show macvtap0 | cut -d: -f1) + # qemu-system-x86_64 -machine q35 -device pcie-root-port,id=pcie-root-port-0 -monitor stdio 9<> $TAP + (qemu) netdev_add type=tap,id=hostnet0,vhost=on,fd=9 + (qemu) device_add driver=virtio-net-pci,netdev=hostnet0,id=net0,bus=pcie-root-port-0 + (qemu) device_del net0 + (qemu) netdev_del hostnet0 + (qemu) netdev_add type=tap,id=hostnet1,vhost=on,fd=9 + qemu-system-x86_64: .../util/oslib-posix.c:247: qemu_set_nonblock: Assertion `f != -1' failed. + Aborted (core dumped) + +To avoid that, add a function, qemu_try_set_nonblock(), that allows to report the +problem without crashing. + +In the same way, we also update the function for vhostfd in net_init_tap_one() and +for fd in net_init_socket() (both descriptors are provided by the user and can +be wrong). + +Signed-off-by: Laurent Vivier +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Jason Wang +(cherry picked from commit 894022e616016fe81745753f14adfbd680a1c7ee) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + include/qemu/sockets.h | 1 + + net/socket.c | 9 +++++-- + net/tap.c | 25 +++++++++++++++--- + util/oslib-posix.c | 26 +++++++++++++------ + util/oslib-win32.c | 57 ++++++++++++++++++++++++------------------ + 5 files changed, 79 insertions(+), 39 deletions(-) + +diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h +index 57cd049d6e..7d1f813576 100644 +--- a/include/qemu/sockets.h ++++ b/include/qemu/sockets.h +@@ -18,6 +18,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); + int socket_set_cork(int fd, int v); + int socket_set_nodelay(int fd); + void qemu_set_block(int fd); ++int qemu_try_set_nonblock(int fd); + void qemu_set_nonblock(int fd); + int socket_set_fast_reuse(int fd); + +diff --git a/net/socket.c b/net/socket.c +index c92354049b..2d21fddd9c 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -725,13 +725,18 @@ int net_init_socket(const Netdev *netdev, const char *name, + } + + if (sock->has_fd) { +- int fd; ++ int fd, ret; + + fd = monitor_fd_param(cur_mon, sock->fd, errp); + if (fd == -1) { + return -1; + } +- qemu_set_nonblock(fd); ++ ret = qemu_try_set_nonblock(fd); ++ if (ret < 0) { ++ error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", ++ name, fd); ++ return -1; ++ } + if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast, + errp)) { + return -1; +diff --git a/net/tap.c b/net/tap.c +index 6207f61f84..41a20102fd 100644 +--- a/net/tap.c ++++ b/net/tap.c +@@ -689,6 +689,8 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, + } + + if (vhostfdname) { ++ int ret; ++ + vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err); + if (vhostfd == -1) { + if (tap->has_vhostforce && tap->vhostforce) { +@@ -698,7 +700,12 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, + } + return; + } +- qemu_set_nonblock(vhostfd); ++ ret = qemu_try_set_nonblock(vhostfd); ++ if (ret < 0) { ++ error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", ++ name, fd); ++ return; ++ } + } else { + vhostfd = open("/dev/vhost-net", O_RDWR); + if (vhostfd < 0) { +@@ -766,6 +773,7 @@ int net_init_tap(const Netdev *netdev, const char *name, + Error *err = NULL; + const char *vhostfdname; + char ifname[128]; ++ int ret = 0; + + assert(netdev->type == NET_CLIENT_DRIVER_TAP); + tap = &netdev->u.tap; +@@ -795,7 +803,12 @@ int net_init_tap(const Netdev *netdev, const char *name, + return -1; + } + +- qemu_set_nonblock(fd); ++ ret = qemu_try_set_nonblock(fd); ++ if (ret < 0) { ++ error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", ++ name, fd); ++ return -1; ++ } + + vnet_hdr = tap_probe_vnet_hdr(fd); + +@@ -810,7 +823,6 @@ int net_init_tap(const Netdev *netdev, const char *name, + char **fds; + char **vhost_fds; + int nfds = 0, nvhosts = 0; +- int ret = 0; + + if (tap->has_ifname || tap->has_script || tap->has_downscript || + tap->has_vnet_hdr || tap->has_helper || tap->has_queues || +@@ -843,7 +855,12 @@ int net_init_tap(const Netdev *netdev, const char *name, + goto free_fail; + } + +- qemu_set_nonblock(fd); ++ ret = qemu_try_set_nonblock(fd); ++ if (ret < 0) { ++ error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", ++ name, fd); ++ goto free_fail; ++ } + + if (i == 0) { + vnet_hdr = tap_probe_vnet_hdr(fd); +diff --git a/util/oslib-posix.c b/util/oslib-posix.c +index 8f88e4dbe1..db70416dbb 100644 +--- a/util/oslib-posix.c ++++ b/util/oslib-posix.c +@@ -240,25 +240,35 @@ void qemu_set_block(int fd) + assert(f != -1); + } + +-void qemu_set_nonblock(int fd) ++int qemu_try_set_nonblock(int fd) + { + int f; + f = fcntl(fd, F_GETFL); +- assert(f != -1); +- f = fcntl(fd, F_SETFL, f | O_NONBLOCK); +-#ifdef __OpenBSD__ + if (f == -1) { ++ return -errno; ++ } ++ if (fcntl(fd, F_SETFL, f | O_NONBLOCK) == -1) { ++#ifdef __OpenBSD__ + /* + * Previous to OpenBSD 6.3, fcntl(F_SETFL) is not permitted on + * memory devices and sets errno to ENODEV. + * It's OK if we fail to set O_NONBLOCK on devices like /dev/null, + * because they will never block anyway. + */ +- assert(errno == ENODEV); +- } +-#else +- assert(f != -1); ++ if (errno == ENODEV) { ++ return 0; ++ } + #endif ++ return -errno; ++ } ++ return 0; ++} ++ ++void qemu_set_nonblock(int fd) ++{ ++ int f; ++ f = qemu_try_set_nonblock(fd); ++ assert(f == 0); + } + + int socket_set_fast_reuse(int fd) +diff --git a/util/oslib-win32.c b/util/oslib-win32.c +index 3b49d27297..7eedbe5859 100644 +--- a/util/oslib-win32.c ++++ b/util/oslib-win32.c +@@ -132,31 +132,6 @@ struct tm *localtime_r(const time_t *timep, struct tm *result) + } + #endif /* CONFIG_LOCALTIME_R */ + +-void qemu_set_block(int fd) +-{ +- unsigned long opt = 0; +- WSAEventSelect(fd, NULL, 0); +- ioctlsocket(fd, FIONBIO, &opt); +-} +- +-void qemu_set_nonblock(int fd) +-{ +- unsigned long opt = 1; +- ioctlsocket(fd, FIONBIO, &opt); +- qemu_fd_register(fd); +-} +- +-int socket_set_fast_reuse(int fd) +-{ +- /* Enabling the reuse of an endpoint that was used by a socket still in +- * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows +- * fast reuse is the default and SO_REUSEADDR does strange things. So we +- * don't have to do anything here. More info can be found at: +- * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */ +- return 0; +-} +- +- + static int socket_error(void) + { + switch (WSAGetLastError()) { +@@ -233,6 +208,38 @@ static int socket_error(void) + } + } + ++void qemu_set_block(int fd) ++{ ++ unsigned long opt = 0; ++ WSAEventSelect(fd, NULL, 0); ++ ioctlsocket(fd, FIONBIO, &opt); ++} ++ ++int qemu_try_set_nonblock(int fd) ++{ ++ unsigned long opt = 1; ++ if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) { ++ return -socket_error(); ++ } ++ qemu_fd_register(fd); ++ return 0; ++} ++ ++void qemu_set_nonblock(int fd) ++{ ++ (void)qemu_try_set_nonblock(fd); ++} ++ ++int socket_set_fast_reuse(int fd) ++{ ++ /* Enabling the reuse of an endpoint that was used by a socket still in ++ * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows ++ * fast reuse is the default and SO_REUSEADDR does strange things. So we ++ * don't have to do anything here. More info can be found at: ++ * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */ ++ return 0; ++} ++ + int inet_aton(const char *cp, struct in_addr *ia) + { + uint32_t addr = inet_addr(cp); +-- +2.27.0 + diff --git a/SOURCES/kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch b/SOURCES/kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch new file mode 100644 index 0000000..8718c71 --- /dev/null +++ b/SOURCES/kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch @@ -0,0 +1,221 @@ +From 3475ea6598896edb689ca8ba6fb81781e2517b6f Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Thu, 29 Jul 2021 04:56:49 -0400 +Subject: [PATCH 14/14] net: detect errors from probing vnet hdr flag for TAP + devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +Message-id: <20210726102337.6359-3-lvivier@redhat.com> +Patchwork-id: 101923 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] net: detect errors from probing vnet hdr flag for TAP devices +Bugzilla: 1982134 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Philippe Mathieu-Daudé + +From: "Daniel P. Berrange" + +BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1982134 +BRANCH: rhel-8.5.0 +UPSTREAM: Merged +BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=38380653 + +When QEMU sets up a tap based network device backend, it mostly ignores errors +reported from various ioctl() calls it makes, assuming the TAP file descriptor +is valid. This assumption can easily be violated when the user is passing in a +pre-opened file descriptor. At best, the ioctls may fail with a -EBADF, but if +the user passes in a bogus FD number that happens to clash with a FD number that +QEMU has opened internally for another reason, a wide variety of errnos may +result, as the TUNGETIFF ioctl number may map to a completely different command +on a different type of file. + +By ignoring all these errors, QEMU sets up a zombie network backend that will +never pass any data. Even worse, when QEMU shuts down, or that network backend +is hot-removed, it will close this bogus file descriptor, which could belong to +another QEMU device backend. + +There's no obvious guaranteed reliable way to detect that a FD genuinely is a +TAP device, as opposed to a UNIX socket, or pipe, or something else. Checking +the errno from probing vnet hdr flag though, does catch the big common cases. +ie calling TUNGETIFF will return EBADF for an invalid FD, and ENOTTY when FD is +a UNIX socket, or pipe which catches accidental collisions with FDs used for +stdio, or monitor socket. + +Previously the example below where bogus fd 9 collides with the FD used for the +chardev saw: + +$ ./x86_64-softmmu/qemu-system-x86_64 -netdev tap,id=hostnet0,fd=9 \ + -chardev socket,id=charchannel0,path=/tmp/qga,server,nowait \ + -monitor stdio -vnc :0 +qemu-system-x86_64: -netdev tap,id=hostnet0,fd=9: TUNGETIFF ioctl() failed: Inappropriate ioctl for device +TUNSETOFFLOAD ioctl() failed: Bad address +QEMU 2.9.1 monitor - type 'help' for more information +(qemu) Warning: netdev hostnet0 has no peer + +which gives a running QEMU with a zombie network backend. + +With this change applied we get an error message and QEMU immediately exits +before carrying on and making a bigger disaster: + +$ ./x86_64-softmmu/qemu-system-x86_64 -netdev tap,id=hostnet0,fd=9 \ + -chardev socket,id=charchannel0,path=/tmp/qga,server,nowait \ + -monitor stdio -vnc :0 +qemu-system-x86_64: -netdev tap,id=hostnet0,vhost=on,fd=9: Unable to query TUNGETIFF on FD 9: Inappropriate ioctl for device + +Reported-by: Dr. David Alan Gilbert +Signed-off-by: Daniel P. Berrange +Tested-by: Dr. David Alan Gilbert +Message-id: 20171027085548.3472-1-berrange@redhat.com +[lv: to simplify, don't check on EINVAL with TUNGETIFF as it exists since v2.6.27] +Signed-off-by: Laurent Vivier +Signed-off-by: Jason Wang +(cherry picked from commit e7b347d0bf640adb1c998d317eaf44d2d7cbd973) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + net/tap-bsd.c | 2 +- + net/tap-linux.c | 8 +++++--- + net/tap-solaris.c | 2 +- + net/tap-stub.c | 2 +- + net/tap.c | 25 ++++++++++++++++++++----- + net/tap_int.h | 2 +- + 6 files changed, 29 insertions(+), 12 deletions(-) + +diff --git a/net/tap-bsd.c b/net/tap-bsd.c +index a5c3707f80..77aaf674b1 100644 +--- a/net/tap-bsd.c ++++ b/net/tap-bsd.c +@@ -211,7 +211,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp) + { + } + +-int tap_probe_vnet_hdr(int fd) ++int tap_probe_vnet_hdr(int fd, Error **errp) + { + return 0; + } +diff --git a/net/tap-linux.c b/net/tap-linux.c +index e0dd442ee3..b0635e9e32 100644 +--- a/net/tap-linux.c ++++ b/net/tap-linux.c +@@ -147,13 +147,15 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp) + } + } + +-int tap_probe_vnet_hdr(int fd) ++int tap_probe_vnet_hdr(int fd, Error **errp) + { + struct ifreq ifr; + + if (ioctl(fd, TUNGETIFF, &ifr) != 0) { +- error_report("TUNGETIFF ioctl() failed: %s", strerror(errno)); +- return 0; ++ /* TUNGETIFF is available since kernel v2.6.27 */ ++ error_setg_errno(errp, errno, ++ "Unable to query TUNGETIFF on FD %d", fd); ++ return -1; + } + + return ifr.ifr_flags & IFF_VNET_HDR; +diff --git a/net/tap-solaris.c b/net/tap-solaris.c +index 4725d2314e..ae2ba68284 100644 +--- a/net/tap-solaris.c ++++ b/net/tap-solaris.c +@@ -206,7 +206,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp) + { + } + +-int tap_probe_vnet_hdr(int fd) ++int tap_probe_vnet_hdr(int fd, Error **errp) + { + return 0; + } +diff --git a/net/tap-stub.c b/net/tap-stub.c +index a9ab8f8293..de525a2e69 100644 +--- a/net/tap-stub.c ++++ b/net/tap-stub.c +@@ -37,7 +37,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp) + { + } + +-int tap_probe_vnet_hdr(int fd) ++int tap_probe_vnet_hdr(int fd, Error **errp) + { + return 0; + } +diff --git a/net/tap.c b/net/tap.c +index 41a20102fd..b37ccae00c 100644 +--- a/net/tap.c ++++ b/net/tap.c +@@ -597,7 +597,11 @@ int net_init_bridge(const Netdev *netdev, const char *name, + } + + qemu_set_nonblock(fd); +- vnet_hdr = tap_probe_vnet_hdr(fd); ++ vnet_hdr = tap_probe_vnet_hdr(fd, errp); ++ if (vnet_hdr < 0) { ++ close(fd); ++ return -1; ++ } + s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr); + + snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper, +@@ -810,7 +814,11 @@ int net_init_tap(const Netdev *netdev, const char *name, + return -1; + } + +- vnet_hdr = tap_probe_vnet_hdr(fd); ++ vnet_hdr = tap_probe_vnet_hdr(fd, errp); ++ if (vnet_hdr < 0) { ++ close(fd); ++ return -1; ++ } + + net_init_tap_one(tap, peer, "tap", name, NULL, + script, downscript, +@@ -863,8 +871,11 @@ int net_init_tap(const Netdev *netdev, const char *name, + } + + if (i == 0) { +- vnet_hdr = tap_probe_vnet_hdr(fd); +- } else if (vnet_hdr != tap_probe_vnet_hdr(fd)) { ++ vnet_hdr = tap_probe_vnet_hdr(fd, errp); ++ if (vnet_hdr < 0) { ++ goto free_fail; ++ } ++ } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) { + error_setg(errp, + "vnet_hdr not consistent across given tap fds"); + ret = -1; +@@ -909,7 +920,11 @@ free_fail: + } + + qemu_set_nonblock(fd); +- vnet_hdr = tap_probe_vnet_hdr(fd); ++ vnet_hdr = tap_probe_vnet_hdr(fd, errp); ++ if (vnet_hdr < 0) { ++ close(fd); ++ return -1; ++ } + + net_init_tap_one(tap, peer, "bridge", name, ifname, + script, downscript, vhostfdname, +diff --git a/net/tap_int.h b/net/tap_int.h +index e3194b23f4..225a49ea48 100644 +--- a/net/tap_int.h ++++ b/net/tap_int.h +@@ -34,7 +34,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, + ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen); + + void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp); +-int tap_probe_vnet_hdr(int fd); ++int tap_probe_vnet_hdr(int fd, Error **errp); + int tap_probe_vnet_hdr_len(int fd, int len); + int tap_probe_has_ufo(int fd); + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo); +-- +2.27.0 + diff --git a/SOURCES/kvm-net-forbid-the-reentrant-RX.patch b/SOURCES/kvm-net-forbid-the-reentrant-RX.patch new file mode 100644 index 0000000..aaf57ed --- /dev/null +++ b/SOURCES/kvm-net-forbid-the-reentrant-RX.patch @@ -0,0 +1,50 @@ +From 1e01e2f96fd5e903394eab59365d5363394c8b18 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Tue, 13 Apr 2021 18:59:12 -0400 +Subject: [PATCH 3/5] net: forbid the reentrant RX + +RH-Author: Jon Maloy +Message-id: <20210413185912.3811035-2-jmaloy@redhat.com> +Patchwork-id: 101467 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] net: forbid the reentrant RX +Bugzilla: 1859175 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth +RH-Acked-by: Xiao Wang + +From: Jason Wang + +The memory API allows DMA into NIC's MMIO area. This means the NIC's +RX routine must be reentrant. Instead of auditing all the NIC, we can +simply detect the reentrancy and return early. The queue->delivering +is set and cleared by qemu_net_queue_deliver() for other queue helpers +to know whether the delivering in on going (NIC's receive is being +called). We can check it and return early in qemu_net_queue_flush() to +forbid reentrant RX. + +Signed-off-by: Jason Wang + +(cherry picked from commit 22dc8663d9fc7baa22100544c600b6285a63c7a3) +Signed-off-by: Jon Maloy +Signed-off-by: Danilo C. L. de Paula +--- + net/queue.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/queue.c b/net/queue.c +index 61276ca4be..c679d79f4b 100644 +--- a/net/queue.c ++++ b/net/queue.c +@@ -250,6 +250,9 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from) + + bool qemu_net_queue_flush(NetQueue *queue) + { ++ if (queue->delivering) ++ return false; ++ + while (!QTAILQ_EMPTY(&queue->packets)) { + NetPacket *packet; + int ret; +-- +2.27.0 + diff --git a/SOURCES/kvm-net-introduce-qemu_receive_packet.patch b/SOURCES/kvm-net-introduce-qemu_receive_packet.patch index 7fecc55..8de8cae 100644 --- a/SOURCES/kvm-net-introduce-qemu_receive_packet.patch +++ b/SOURCES/kvm-net-introduce-qemu_receive_packet.patch @@ -1,4 +1,4 @@ -From ee23b82cc9174c96ea73252e2986cf822999494b Mon Sep 17 00:00:00 2001 +From 89732bf03b26daaebbd3e6e031e79459ae3f77e1 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:39 -0400 Subject: [PATCH 1/9] net: introduce qemu_receive_packet() @@ -150,7 +150,7 @@ index 84aa6d8d00..d0b651ca95 100644 { return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW, diff --git a/net/queue.c b/net/queue.c -index 61276ca4be..7c0b72c8ef 100644 +index c679d79f4b..5f0f9ffcaf 100644 --- a/net/queue.c +++ b/net/queue.c @@ -182,6 +182,28 @@ static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue, diff --git a/SOURCES/kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch b/SOURCES/kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch index cf3ef08..b619e78 100644 --- a/SOURCES/kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch +++ b/SOURCES/kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch @@ -1,19 +1,16 @@ -From 04c233dd15e3b5bc842af371c3433eb723ffb6e6 Mon Sep 17 00:00:00 2001 +From b7de63e72c479df42c324c058a487517210fa069 Mon Sep 17 00:00:00 2001 From: Jon Maloy -Date: Tue, 23 Mar 2021 22:11:13 -0400 -Subject: [PATCH 1/8] net: remove an assert call in eth_get_gso_type -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Date: Tue, 13 Apr 2021 19:21:50 -0400 +Subject: [PATCH 1/5] net: remove an assert call in eth_get_gso_type RH-Author: Jon Maloy -Message-id: <20210323221113.1893864-2-jmaloy@redhat.com> -Patchwork-id: 101364 -O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] net: remove an assert call in eth_get_gso_type -Bugzilla: 1939494 -RH-Acked-by: Philippe Mathieu-Daudé +Message-id: <20210413192150.3817133-2-jmaloy@redhat.com> +Patchwork-id: 101469 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] net: remove an assert call in eth_get_gso_type +Bugzilla: 1892350 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Xiao Wang -RH-Acked-by: Thomas Huth From: Prasad J Pandit diff --git a/SOURCES/kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch b/SOURCES/kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch index c54cfbd..414cc13 100644 --- a/SOURCES/kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch +++ b/SOURCES/kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch @@ -1,16 +1,19 @@ -From 3d7ff6c57357e1fb8453b26200cfd239e9cdaa72 Mon Sep 17 00:00:00 2001 +From 56ae2d8a1ee3a35e2eed4f4baa61f97184189b47 Mon Sep 17 00:00:00 2001 From: Thomas Huth -Date: Thu, 24 Jun 2021 14:50:46 -0400 -Subject: [PATCH 2/3] pc-bios/s390-ccw: break loop if a null block number is +Date: Tue, 18 May 2021 13:51:24 -0400 +Subject: [PATCH 4/5] pc-bios/s390-ccw: break loop if a null block number is reached +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit RH-Author: Thomas Huth -Message-id: <20210624145047.483112-3-thuth@redhat.com> -Patchwork-id: 101762 -O-Subject: [RHEL-8.2.0.z / RHEL-8.4.0.z qemu-kvm PATCH 2/3] pc-bios/s390-ccw: break loop if a null block number is reached -Bugzilla: 1975679 -RH-Acked-by: Stefano Garzarella -RH-Acked-by: Jon Maloy +Message-id: <20210518135125.191329-3-thuth@redhat.com> +Patchwork-id: 101549 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/3] pc-bios/s390-ccw: break loop if a null block number is reached +Bugzilla: 1942880 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: David Hildenbrand RH-Acked-by: Cornelia Huck Break the loop if `cur_block_nr` is a null block number because this @@ -23,6 +26,7 @@ Signed-off-by: Marc Hartmayer Message-Id: <20200924085926.21709-3-mhartmay@linux.ibm.com> Signed-off-by: Thomas Huth (cherry picked from commit 468184ec9024f4f7b55247f70ec57554e8a500d7) +Signed-off-by: Thomas Huth Signed-off-by: Danilo C. L. de Paula --- pc-bios/s390-ccw/bootmap.c | 2 +- diff --git a/SOURCES/kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch b/SOURCES/kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch index 1d45f6d..2597118 100644 --- a/SOURCES/kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch +++ b/SOURCES/kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch @@ -1,16 +1,19 @@ -From c3f15d52ad265bba0b21453d2d8b69f597092c25 Mon Sep 17 00:00:00 2001 +From 52ba1903b2c8ce69e8cd1de2a78c2c63cc60383b Mon Sep 17 00:00:00 2001 From: Thomas Huth -Date: Thu, 24 Jun 2021 14:50:47 -0400 -Subject: [PATCH 3/3] pc-bios/s390-ccw: don't try to read the next block if end +Date: Tue, 18 May 2021 13:51:25 -0400 +Subject: [PATCH 5/5] pc-bios/s390-ccw: don't try to read the next block if end of chunk is reached +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit RH-Author: Thomas Huth -Message-id: <20210624145047.483112-4-thuth@redhat.com> -Patchwork-id: 101763 -O-Subject: [RHEL-8.2.0.z / RHEL-8.4.0.z qemu-kvm PATCH 3/3] pc-bios/s390-ccw: don't try to read the next block if end of chunk is reached -Bugzilla: 1975679 -RH-Acked-by: Stefano Garzarella -RH-Acked-by: Jon Maloy +Message-id: <20210518135125.191329-4-thuth@redhat.com> +Patchwork-id: 101550 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 3/3] pc-bios/s390-ccw: don't try to read the next block if end of chunk is reached +Bugzilla: 1942880 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: David Hildenbrand RH-Acked-by: Cornelia Huck Don't read the block if a null block number is reached, because this means that @@ -21,6 +24,7 @@ Signed-off-by: Marc Hartmayer Message-Id: <20210416074736.17409-1-mhartmay@linux.ibm.com> Signed-off-by: Thomas Huth (cherry picked from commit a6625d38cce3901a7c1cba069f0abcf743a293f1) +Signed-off-by: Thomas Huth Signed-off-by: Danilo C. L. de Paula --- pc-bios/s390-ccw/bootmap.c | 2 +- diff --git a/SOURCES/kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch b/SOURCES/kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch index d180158..691bed4 100644 --- a/SOURCES/kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch +++ b/SOURCES/kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch @@ -1,15 +1,18 @@ -From 93ddbd8ba056141dd68d973d534b67dad9882052 Mon Sep 17 00:00:00 2001 +From 0e9bdb960045f98d70f765bbb585f1647e5fea08 Mon Sep 17 00:00:00 2001 From: Thomas Huth -Date: Thu, 24 Jun 2021 14:50:45 -0400 -Subject: [PATCH 1/3] pc-bios/s390-ccw: fix off-by-one error +Date: Tue, 18 May 2021 13:51:23 -0400 +Subject: [PATCH 3/5] pc-bios/s390-ccw: fix off-by-one error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit RH-Author: Thomas Huth -Message-id: <20210624145047.483112-2-thuth@redhat.com> -Patchwork-id: 101764 -O-Subject: [RHEL-8.2.0.z / RHEL-8.4.0.z qemu-kvm PATCH 1/3] pc-bios/s390-ccw: fix off-by-one error -Bugzilla: 1975679 -RH-Acked-by: Stefano Garzarella -RH-Acked-by: Jon Maloy +Message-id: <20210518135125.191329-2-thuth@redhat.com> +Patchwork-id: 101548 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/3] pc-bios/s390-ccw: fix off-by-one error +Bugzilla: 1942880 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: David Hildenbrand RH-Acked-by: Cornelia Huck This error takes effect when the magic value "zIPL" is located at the @@ -24,6 +27,7 @@ Reviewed-by: Thomas Huth [thuth: Use "<= ... - 4" instead of "< ... - 3"] Signed-off-by: Thomas Huth (cherry picked from commit 5f97ba0c74ccace0a4014460de9751ff3c6f454a) +Signed-off-by: Thomas Huth Signed-off-by: Danilo C. L. de Paula --- pc-bios/s390-ccw/bootmap.c | 2 +- diff --git a/SOURCES/kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch b/SOURCES/kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch index 2c66a5f..8c33334 100644 --- a/SOURCES/kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch +++ b/SOURCES/kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch @@ -1,4 +1,4 @@ -From 3427c5573a7ab788e0c39e30b4d0ed5db85f03b3 Mon Sep 17 00:00:00 2001 +From b36a9259e085b4d32532d896e485889181b130ae Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:45 -0400 Subject: [PATCH 7/9] pcnet: switch to use qemu_receive_packet() for loopback diff --git a/SOURCES/kvm-qemu-img-convert-Don-t-pre-zero-images.patch b/SOURCES/kvm-qemu-img-convert-Don-t-pre-zero-images.patch new file mode 100644 index 0000000..28311f4 --- /dev/null +++ b/SOURCES/kvm-qemu-img-convert-Don-t-pre-zero-images.patch @@ -0,0 +1,73 @@ +From eea45924903f03dc6d8f20576be0a4a84d5acce4 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Feb 2021 10:16:11 -0500 +Subject: [PATCH 4/5] qemu-img convert: Don't pre-zero images + +RH-Author: Kevin Wolf +Message-id: <20210210101611.137928-2-kwolf@redhat.com> +Patchwork-id: 101030 +O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] qemu-img convert: Don't pre-zero images +Bugzilla: 1855250 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Max Reitz + +Since commit 5a37b60a61c, qemu-img create will pre-zero the target image +if it isn't already zero-initialised (most importantly, for host block +devices, but also iscsi etc.), so that writing explicit zeros wouldn't +be necessary later. + +This could speed up the operation significantly, in particular when the +source image file was only sparsely populated. However, it also means +that some block are written twice: Once when pre-zeroing them, and then +when they are overwritten with actual data. On a full image, the +pre-zeroing is wasted work because everything will be overwritten. + +In practice, write_zeroes typically turns out faster than writing +explicit zero buffers, but slow enough that first zeroing everything and +then overwriting parts can be a significant net loss. + +Meanwhile, qemu-img convert was rewritten in 690c7301600 and zero blocks +are now written to the target using bdrv_co_pwrite_zeroes() if the +target could be pre-zeroed. This way we already make use of the faster +write_zeroes operation, but avoid writing any blocks twice. + +Remove the pre-zeroing because these days this former optimisation has +actually turned into a pessimisation in the common case. + +Reported-by: Nir Soffer +Signed-off-by: Kevin Wolf +Message-Id: <20200622151203.35624-1-kwolf@redhat.com> +Tested-by: Nir Soffer +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit edafc70c0c8510862f2f213a3acf7067113bcd08) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + qemu-img.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/qemu-img.c b/qemu-img.c +index a27ad70851..b10dc5129b 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -2029,15 +2029,6 @@ static int convert_do_copy(ImgConvertState *s) + s->has_zero_init = false; + } + +- if (!s->has_zero_init && !s->target_has_backing && +- bdrv_can_write_zeroes_with_unmap(blk_bs(s->target))) +- { +- ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK); +- if (ret == 0) { +- s->has_zero_init = true; +- } +- } +- + /* Allocate buffer for copied data. For compressed images, only one cluster + * can be copied at a time. */ + if (s->compressed) { +-- +2.27.0 + diff --git a/SOURCES/kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch b/SOURCES/kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch new file mode 100644 index 0000000..dec7f7b --- /dev/null +++ b/SOURCES/kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch @@ -0,0 +1,176 @@ +From 7f8888f2c53060c4536856859d5ea94d23ea9e45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:55:54 -0400 +Subject: [PATCH 03/14] qga: add *reset argument to ssh-add-authorized-keys +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210609100615.2501448-4-marcandre.lureau@redhat.com> +Patchwork-id: 101689 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 3/4] qga: add *reset argument to ssh-add-authorized-keys +Bugzilla: 1967716 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Michal Privoznik + +From: Michael Roth + +I prefer 'reset' over 'clear', since 'clear' and keys may have some +other relations or meaning. + +Signed-off-by: Marc-André Lureau +*fix disallowed g_assert* usage reported by checkpatch +Signed-off-by: Michael Roth + +(cherry picked from commit 0e3c94758e3851f0ab30d2a1e63a73284499775d) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + qga/commands-posix-ssh.c | 53 ++++++++++++++++++++++++++++++++++++---- + qga/qapi-schema.json | 3 ++- + 2 files changed, 50 insertions(+), 6 deletions(-) + +diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c +index f74d89679c..362c9e8816 100644 +--- a/qga/commands-posix-ssh.c ++++ b/qga/commands-posix-ssh.c +@@ -168,6 +168,7 @@ read_authkeys(const char *path, Error **errp) + + void + qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys, ++ bool has_reset, bool reset, + Error **errp) + { + g_autofree struct passwd *p = NULL; +@@ -178,6 +179,7 @@ qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys, + size_t nkeys, nauthkeys; + + ERRP_GUARD(); ++ reset = has_reset && reset; + + if (!check_openssh_pub_keys(keys, &nkeys, errp)) { + return; +@@ -191,7 +193,9 @@ qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys, + ssh_path = g_build_filename(p->pw_dir, ".ssh", NULL); + authkeys_path = g_build_filename(ssh_path, "authorized_keys", NULL); + +- authkeys = read_authkeys(authkeys_path, NULL); ++ if (!reset) { ++ authkeys = read_authkeys(authkeys_path, NULL); ++ } + if (authkeys == NULL) { + if (!g_file_test(ssh_path, G_FILE_TEST_IS_DIR) && + !mkdir_for_user(ssh_path, p, 0700, errp)) { +@@ -318,7 +322,7 @@ test_invalid_user(void) + { + Error *err = NULL; + +- qmp_guest_ssh_add_authorized_keys("", NULL, &err); ++ qmp_guest_ssh_add_authorized_keys("", NULL, FALSE, FALSE, &err); + error_free_or_abort(&err); + + qmp_guest_ssh_remove_authorized_keys("", NULL, &err); +@@ -333,7 +337,8 @@ test_invalid_key(void) + }; + Error *err = NULL; + +- qmp_guest_ssh_add_authorized_keys(g_get_user_name(), &key, &err); ++ qmp_guest_ssh_add_authorized_keys(g_get_user_name(), &key, ++ FALSE, FALSE, &err); + error_free_or_abort(&err); + + qmp_guest_ssh_remove_authorized_keys(g_get_user_name(), &key, &err); +@@ -346,13 +351,17 @@ test_add_keys(void) + Error *err = NULL; + + qmp_guest_ssh_add_authorized_keys(g_get_user_name(), +- (strList *)&test_key2, &err); ++ (strList *)&test_key2, ++ FALSE, FALSE, ++ &err); + g_assert(err == NULL); + + test_authorized_keys_equal("algo key2 comments"); + + qmp_guest_ssh_add_authorized_keys(g_get_user_name(), +- (strList *)&test_key1_2, &err); ++ (strList *)&test_key1_2, ++ FALSE, FALSE, ++ &err); + g_assert(err == NULL); + + /* key2 came first, and should'nt be duplicated */ +@@ -360,6 +369,39 @@ test_add_keys(void) + "algo key1 comments"); + } + ++static void ++test_add_reset_keys(void) ++{ ++ Error *err = NULL; ++ ++ qmp_guest_ssh_add_authorized_keys(g_get_user_name(), ++ (strList *)&test_key1_2, ++ FALSE, FALSE, ++ &err); ++ g_assert(err == NULL); ++ ++ /* reset with key2 only */ ++ test_authorized_keys_equal("algo key1 comments\n" ++ "algo key2 comments"); ++ ++ qmp_guest_ssh_add_authorized_keys(g_get_user_name(), ++ (strList *)&test_key2, ++ TRUE, TRUE, ++ &err); ++ g_assert(err == NULL); ++ ++ test_authorized_keys_equal("algo key2 comments"); ++ ++ /* empty should clear file */ ++ qmp_guest_ssh_add_authorized_keys(g_get_user_name(), ++ (strList *)NULL, ++ TRUE, TRUE, ++ &err); ++ g_assert(err == NULL); ++ ++ test_authorized_keys_equal(""); ++} ++ + static void + test_remove_keys(void) + { +@@ -393,6 +435,7 @@ int main(int argc, char *argv[]) + g_test_add_func("/qga/ssh/invalid_user", test_invalid_user); + g_test_add_func("/qga/ssh/invalid_key", test_invalid_key); + g_test_add_func("/qga/ssh/add_keys", test_add_keys); ++ g_test_add_func("/qga/ssh/add_reset_keys", test_add_reset_keys); + g_test_add_func("/qga/ssh/remove_keys", test_remove_keys); + + return g_test_run(); +diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json +index 3b85f5a03f..a70ea5da77 100644 +--- a/qga/qapi-schema.json ++++ b/qga/qapi-schema.json +@@ -1279,6 +1279,7 @@ + # + # @username: the user account to add the authorized keys + # @keys: the public keys to add (in OpenSSH/sshd(8) authorized_keys format) ++# @reset: ignore the existing content, set it with the given keys only + # + # Append public keys to user .ssh/authorized_keys on Unix systems (not + # implemented for other systems). +@@ -1288,7 +1289,7 @@ + # Since: 5.2 + ## + { 'command': 'guest-ssh-add-authorized-keys', +- 'data': { 'username': 'str', 'keys': ['str'] }, ++ 'data': { 'username': 'str', 'keys': ['str'], '*reset': 'bool' }, + 'if': 'defined(CONFIG_POSIX)' } + + ## +-- +2.27.0 + diff --git a/SOURCES/kvm-qga-add-ssh-add-remove-authorized-keys.patch b/SOURCES/kvm-qga-add-ssh-add-remove-authorized-keys.patch new file mode 100644 index 0000000..b767d42 --- /dev/null +++ b/SOURCES/kvm-qga-add-ssh-add-remove-authorized-keys.patch @@ -0,0 +1,525 @@ +From 4be6cb23235b29d6ce450c2dacaef09c52d1aeea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:55:52 -0400 +Subject: [PATCH 02/14] qga: add ssh-{add, remove}-authorized-keys +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210609100615.2501448-3-marcandre.lureau@redhat.com> +Patchwork-id: 101688 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/4] qga: add ssh-{add, remove}-authorized-keys +Bugzilla: 1967716 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Michal Privoznik + +From: Marc-André Lureau + +Add new commands to add and remove SSH public keys from +~/.ssh/authorized_keys. + +I took a different approach for testing, including the unit tests right +with the code. I wanted to overwrite the function to get the user +details, I couldn't easily do that over QMP. Furthermore, I prefer +having unit tests very close to the code, and unit files that are domain +specific (commands-posix is too crowded already). FWIW, that +coding/testing style is Rust-style (where tests can or should even be +part of the documentation!). + +Fixes: +https://bugzilla.redhat.com/show_bug.cgi?id=1885332 + +Signed-off-by: Marc-André Lureau +Reviewed-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +*squashed in fix-ups for setting file ownership and use of QAPI + conditionals for CONFIG_POSIX instead of stub definitions +*disable qga-ssh-test for now due to G_TEST_OPTION_ISOLATE_DIRS + triggering leak detector in build-oss-fuzz +*fix disallowed g_assert* usage reported by checkpatch +Signed-off-by: Michael Roth + +(cherry picked from commit 8d769ec777dccbff199711aba43aa6297fe4a0e0) +[ Fixes trivial backport conflicts and use Makefile.objs build-sys ] +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + qga/Makefile.objs | 2 +- + qga/commands-posix-ssh.c | 407 +++++++++++++++++++++++++++++++++++++++ + qga/qapi-schema.json | 35 ++++ + 3 files changed, 443 insertions(+), 1 deletion(-) + create mode 100644 qga/commands-posix-ssh.c + +diff --git a/qga/Makefile.objs b/qga/Makefile.objs +index 80e6bb3c2e..c8da634db0 100644 +--- a/qga/Makefile.objs ++++ b/qga/Makefile.objs +@@ -1,6 +1,6 @@ + commands-posix.o-libs := $(LIBUDEV_LIBS) + qga-obj-y = commands.o guest-agent-command-state.o main.o +-qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o ++qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o commands-posix-ssh.o + qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o + qga-obj-$(CONFIG_WIN32) += vss-win32.o + qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o +diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c +new file mode 100644 +index 0000000000..f74d89679c +--- /dev/null ++++ b/qga/commands-posix-ssh.c +@@ -0,0 +1,407 @@ ++ /* ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++#include "qemu/osdep.h" ++ ++#include ++#include ++#include ++#include ++ ++#include "qapi/error.h" ++#include "qga-qapi-commands.h" ++ ++#ifdef QGA_BUILD_UNIT_TEST ++static struct passwd * ++test_get_passwd_entry(const gchar *user_name, GError **error) ++{ ++ struct passwd *p; ++ int ret; ++ ++ if (!user_name || g_strcmp0(user_name, g_get_user_name())) { ++ g_set_error(error, G_UNIX_ERROR, 0, "Invalid user name"); ++ return NULL; ++ } ++ ++ p = g_new0(struct passwd, 1); ++ p->pw_dir = (char *)g_get_home_dir(); ++ p->pw_uid = geteuid(); ++ p->pw_gid = getegid(); ++ ++ ret = g_mkdir_with_parents(p->pw_dir, 0700); ++ g_assert(ret == 0); ++ ++ return p; ++} ++ ++#define g_unix_get_passwd_entry_qemu(username, err) \ ++ test_get_passwd_entry(username, err) ++#endif ++ ++static struct passwd * ++get_passwd_entry(const char *username, Error **errp) ++{ ++ g_autoptr(GError) err = NULL; ++ struct passwd *p; ++ ++ ERRP_GUARD(); ++ ++ p = g_unix_get_passwd_entry_qemu(username, &err); ++ if (p == NULL) { ++ error_setg(errp, "failed to lookup user '%s': %s", ++ username, err->message); ++ return NULL; ++ } ++ ++ return p; ++} ++ ++static bool ++mkdir_for_user(const char *path, const struct passwd *p, ++ mode_t mode, Error **errp) ++{ ++ ERRP_GUARD(); ++ ++ if (g_mkdir(path, mode) == -1) { ++ error_setg(errp, "failed to create directory '%s': %s", ++ path, g_strerror(errno)); ++ return false; ++ } ++ ++ if (chown(path, p->pw_uid, p->pw_gid) == -1) { ++ error_setg(errp, "failed to set ownership of directory '%s': %s", ++ path, g_strerror(errno)); ++ return false; ++ } ++ ++ if (chmod(path, mode) == -1) { ++ error_setg(errp, "failed to set permissions of directory '%s': %s", ++ path, g_strerror(errno)); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool ++check_openssh_pub_key(const char *key, Error **errp) ++{ ++ ERRP_GUARD(); ++ ++ /* simple sanity-check, we may want more? */ ++ if (!key || key[0] == '#' || strchr(key, '\n')) { ++ error_setg(errp, "invalid OpenSSH public key: '%s'", key); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool ++check_openssh_pub_keys(strList *keys, size_t *nkeys, Error **errp) ++{ ++ size_t n = 0; ++ strList *k; ++ ++ ERRP_GUARD(); ++ ++ for (k = keys; k != NULL; k = k->next) { ++ if (!check_openssh_pub_key(k->value, errp)) { ++ return false; ++ } ++ n++; ++ } ++ ++ if (nkeys) { ++ *nkeys = n; ++ } ++ return true; ++} ++ ++static bool ++write_authkeys(const char *path, const GStrv keys, ++ const struct passwd *p, Error **errp) ++{ ++ g_autofree char *contents = NULL; ++ g_autoptr(GError) err = NULL; ++ ++ ERRP_GUARD(); ++ ++ contents = g_strjoinv("\n", keys); ++ if (!g_file_set_contents(path, contents, -1, &err)) { ++ error_setg(errp, "failed to write to '%s': %s", path, err->message); ++ return false; ++ } ++ ++ if (chown(path, p->pw_uid, p->pw_gid) == -1) { ++ error_setg(errp, "failed to set ownership of directory '%s': %s", ++ path, g_strerror(errno)); ++ return false; ++ } ++ ++ if (chmod(path, 0600) == -1) { ++ error_setg(errp, "failed to set permissions of '%s': %s", ++ path, g_strerror(errno)); ++ return false; ++ } ++ ++ return true; ++} ++ ++static GStrv ++read_authkeys(const char *path, Error **errp) ++{ ++ g_autoptr(GError) err = NULL; ++ g_autofree char *contents = NULL; ++ ++ ERRP_GUARD(); ++ ++ if (!g_file_get_contents(path, &contents, NULL, &err)) { ++ error_setg(errp, "failed to read '%s': %s", path, err->message); ++ return NULL; ++ } ++ ++ return g_strsplit(contents, "\n", -1); ++ ++} ++ ++void ++qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys, ++ Error **errp) ++{ ++ g_autofree struct passwd *p = NULL; ++ g_autofree char *ssh_path = NULL; ++ g_autofree char *authkeys_path = NULL; ++ g_auto(GStrv) authkeys = NULL; ++ strList *k; ++ size_t nkeys, nauthkeys; ++ ++ ERRP_GUARD(); ++ ++ if (!check_openssh_pub_keys(keys, &nkeys, errp)) { ++ return; ++ } ++ ++ p = get_passwd_entry(username, errp); ++ if (p == NULL) { ++ return; ++ } ++ ++ ssh_path = g_build_filename(p->pw_dir, ".ssh", NULL); ++ authkeys_path = g_build_filename(ssh_path, "authorized_keys", NULL); ++ ++ authkeys = read_authkeys(authkeys_path, NULL); ++ if (authkeys == NULL) { ++ if (!g_file_test(ssh_path, G_FILE_TEST_IS_DIR) && ++ !mkdir_for_user(ssh_path, p, 0700, errp)) { ++ return; ++ } ++ } ++ ++ nauthkeys = authkeys ? g_strv_length(authkeys) : 0; ++ authkeys = g_realloc_n(authkeys, nauthkeys + nkeys + 1, sizeof(char *)); ++ memset(authkeys + nauthkeys, 0, (nkeys + 1) * sizeof(char *)); ++ ++ for (k = keys; k != NULL; k = k->next) { ++ if (g_strv_contains((const gchar * const *)authkeys, k->value)) { ++ continue; ++ } ++ authkeys[nauthkeys++] = g_strdup(k->value); ++ } ++ ++ write_authkeys(authkeys_path, authkeys, p, errp); ++} ++ ++void ++qmp_guest_ssh_remove_authorized_keys(const char *username, strList *keys, ++ Error **errp) ++{ ++ g_autofree struct passwd *p = NULL; ++ g_autofree char *authkeys_path = NULL; ++ g_autofree GStrv new_keys = NULL; /* do not own the strings */ ++ g_auto(GStrv) authkeys = NULL; ++ GStrv a; ++ size_t nkeys = 0; ++ ++ ERRP_GUARD(); ++ ++ if (!check_openssh_pub_keys(keys, NULL, errp)) { ++ return; ++ } ++ ++ p = get_passwd_entry(username, errp); ++ if (p == NULL) { ++ return; ++ } ++ ++ authkeys_path = g_build_filename(p->pw_dir, ".ssh", ++ "authorized_keys", NULL); ++ if (!g_file_test(authkeys_path, G_FILE_TEST_EXISTS)) { ++ return; ++ } ++ authkeys = read_authkeys(authkeys_path, errp); ++ if (authkeys == NULL) { ++ return; ++ } ++ ++ new_keys = g_new0(char *, g_strv_length(authkeys) + 1); ++ for (a = authkeys; *a != NULL; a++) { ++ strList *k; ++ ++ for (k = keys; k != NULL; k = k->next) { ++ if (g_str_equal(k->value, *a)) { ++ break; ++ } ++ } ++ if (k != NULL) { ++ continue; ++ } ++ ++ new_keys[nkeys++] = *a; ++ } ++ ++ write_authkeys(authkeys_path, new_keys, p, errp); ++} ++ ++ ++#ifdef QGA_BUILD_UNIT_TEST ++#if GLIB_CHECK_VERSION(2, 60, 0) ++static const strList test_key2 = { ++ .value = (char *)"algo key2 comments" ++}; ++ ++static const strList test_key1_2 = { ++ .value = (char *)"algo key1 comments", ++ .next = (strList *)&test_key2, ++}; ++ ++static char * ++test_get_authorized_keys_path(void) ++{ ++ return g_build_filename(g_get_home_dir(), ".ssh", "authorized_keys", NULL); ++} ++ ++static void ++test_authorized_keys_set(const char *contents) ++{ ++ g_autoptr(GError) err = NULL; ++ g_autofree char *path = NULL; ++ int ret; ++ ++ path = g_build_filename(g_get_home_dir(), ".ssh", NULL); ++ ret = g_mkdir_with_parents(path, 0700); ++ g_assert(ret == 0); ++ g_free(path); ++ ++ path = test_get_authorized_keys_path(); ++ g_file_set_contents(path, contents, -1, &err); ++ g_assert(err == NULL); ++} ++ ++static void ++test_authorized_keys_equal(const char *expected) ++{ ++ g_autoptr(GError) err = NULL; ++ g_autofree char *path = NULL; ++ g_autofree char *contents = NULL; ++ ++ path = test_get_authorized_keys_path(); ++ g_file_get_contents(path, &contents, NULL, &err); ++ g_assert(err == NULL); ++ ++ g_assert(g_strcmp0(contents, expected) == 0); ++} ++ ++static void ++test_invalid_user(void) ++{ ++ Error *err = NULL; ++ ++ qmp_guest_ssh_add_authorized_keys("", NULL, &err); ++ error_free_or_abort(&err); ++ ++ qmp_guest_ssh_remove_authorized_keys("", NULL, &err); ++ error_free_or_abort(&err); ++} ++ ++static void ++test_invalid_key(void) ++{ ++ strList key = { ++ .value = (char *)"not a valid\nkey" ++ }; ++ Error *err = NULL; ++ ++ qmp_guest_ssh_add_authorized_keys(g_get_user_name(), &key, &err); ++ error_free_or_abort(&err); ++ ++ qmp_guest_ssh_remove_authorized_keys(g_get_user_name(), &key, &err); ++ error_free_or_abort(&err); ++} ++ ++static void ++test_add_keys(void) ++{ ++ Error *err = NULL; ++ ++ qmp_guest_ssh_add_authorized_keys(g_get_user_name(), ++ (strList *)&test_key2, &err); ++ g_assert(err == NULL); ++ ++ test_authorized_keys_equal("algo key2 comments"); ++ ++ qmp_guest_ssh_add_authorized_keys(g_get_user_name(), ++ (strList *)&test_key1_2, &err); ++ g_assert(err == NULL); ++ ++ /* key2 came first, and should'nt be duplicated */ ++ test_authorized_keys_equal("algo key2 comments\n" ++ "algo key1 comments"); ++} ++ ++static void ++test_remove_keys(void) ++{ ++ Error *err = NULL; ++ static const char *authkeys = ++ "algo key1 comments\n" ++ /* originally duplicated */ ++ "algo key1 comments\n" ++ "# a commented line\n" ++ "algo some-key another\n"; ++ ++ test_authorized_keys_set(authkeys); ++ qmp_guest_ssh_remove_authorized_keys(g_get_user_name(), ++ (strList *)&test_key2, &err); ++ g_assert(err == NULL); ++ test_authorized_keys_equal(authkeys); ++ ++ qmp_guest_ssh_remove_authorized_keys(g_get_user_name(), ++ (strList *)&test_key1_2, &err); ++ g_assert(err == NULL); ++ test_authorized_keys_equal("# a commented line\n" ++ "algo some-key another\n"); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ setlocale(LC_ALL, ""); ++ ++ g_test_init(&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); ++ ++ g_test_add_func("/qga/ssh/invalid_user", test_invalid_user); ++ g_test_add_func("/qga/ssh/invalid_key", test_invalid_key); ++ g_test_add_func("/qga/ssh/add_keys", test_add_keys); ++ g_test_add_func("/qga/ssh/remove_keys", test_remove_keys); ++ ++ return g_test_run(); ++} ++#else ++int main(int argc, char *argv[]) ++{ ++ g_test_message("test skipped, needs glib >= 2.60"); ++ return 0; ++} ++#endif /* GLIB_2_60 */ ++#endif /* BUILD_UNIT_TEST */ +diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json +index 4222cb92d3..3b85f5a03f 100644 +--- a/qga/qapi-schema.json ++++ b/qga/qapi-schema.json +@@ -1273,3 +1273,38 @@ + ## + { 'command': 'guest-get-osinfo', + 'returns': 'GuestOSInfo' } ++ ++## ++# @guest-ssh-add-authorized-keys: ++# ++# @username: the user account to add the authorized keys ++# @keys: the public keys to add (in OpenSSH/sshd(8) authorized_keys format) ++# ++# Append public keys to user .ssh/authorized_keys on Unix systems (not ++# implemented for other systems). ++# ++# Returns: Nothing on success. ++# ++# Since: 5.2 ++## ++{ 'command': 'guest-ssh-add-authorized-keys', ++ 'data': { 'username': 'str', 'keys': ['str'] }, ++ 'if': 'defined(CONFIG_POSIX)' } ++ ++## ++# @guest-ssh-remove-authorized-keys: ++# ++# @username: the user account to remove the authorized keys ++# @keys: the public keys to remove (in OpenSSH/sshd(8) authorized_keys format) ++# ++# Remove public keys from the user .ssh/authorized_keys on Unix systems (not ++# implemented for other systems). It's not an error if the key is already ++# missing. ++# ++# Returns: Nothing on success. ++# ++# Since: 5.2 ++## ++{ 'command': 'guest-ssh-remove-authorized-keys', ++ 'data': { 'username': 'str', 'keys': ['str'] }, ++ 'if': 'defined(CONFIG_POSIX)' } +-- +2.27.0 + diff --git a/SOURCES/kvm-qga-add-ssh-get-authorized-keys.patch b/SOURCES/kvm-qga-add-ssh-get-authorized-keys.patch new file mode 100644 index 0000000..2b4c377 --- /dev/null +++ b/SOURCES/kvm-qga-add-ssh-get-authorized-keys.patch @@ -0,0 +1,170 @@ +From 1ed102f5489e6cf3168d9014e9a082909193b6fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:55:57 -0400 +Subject: [PATCH 04/14] qga: add ssh-get-authorized-keys +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210609100615.2501448-5-marcandre.lureau@redhat.com> +Patchwork-id: 101690 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 4/4] qga: add ssh-get-authorized-keys +Bugzilla: 1967716 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Michal Privoznik + +From: Marc-André Lureau + +Signed-off-by: Marc-André Lureau +*fix-up merge conflicts due to qga-ssh-test being disabled in earlier + patch due to G_TEST_OPTION_ISOLATE_DIRS triggering build-oss-fuzz + leak detector. +*fix up style and disallowed g_assert* usage reported by checkpatch +Signed-off-by: Michael Roth + +(cherry picked from commit cad97c08a1c17830d77a46780088bc0199df89d1) +[ Fix trivial schema conflict ] +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + qga/commands-posix-ssh.c | 66 ++++++++++++++++++++++++++++++++++++++++ + qga/qapi-schema.json | 30 ++++++++++++++++++ + 2 files changed, 96 insertions(+) + +diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c +index 362c9e8816..749167e82d 100644 +--- a/qga/commands-posix-ssh.c ++++ b/qga/commands-posix-ssh.c +@@ -268,6 +268,46 @@ qmp_guest_ssh_remove_authorized_keys(const char *username, strList *keys, + write_authkeys(authkeys_path, new_keys, p, errp); + } + ++GuestAuthorizedKeys * ++qmp_guest_ssh_get_authorized_keys(const char *username, Error **errp) ++{ ++ g_autofree struct passwd *p = NULL; ++ g_autofree char *authkeys_path = NULL; ++ g_auto(GStrv) authkeys = NULL; ++ g_autoptr(GuestAuthorizedKeys) ret = NULL; ++ int i; ++ ++ ERRP_GUARD(); ++ ++ p = get_passwd_entry(username, errp); ++ if (p == NULL) { ++ return NULL; ++ } ++ ++ authkeys_path = g_build_filename(p->pw_dir, ".ssh", ++ "authorized_keys", NULL); ++ authkeys = read_authkeys(authkeys_path, errp); ++ if (authkeys == NULL) { ++ return NULL; ++ } ++ ++ ret = g_new0(GuestAuthorizedKeys, 1); ++ for (i = 0; authkeys[i] != NULL; i++) { ++ strList *new; ++ ++ g_strstrip(authkeys[i]); ++ if (!authkeys[i][0] || authkeys[i][0] == '#') { ++ continue; ++ } ++ ++ new = g_new0(strList, 1); ++ new->value = g_strdup(authkeys[i]); ++ new->next = ret->keys; ++ ret->keys = new; ++ } ++ ++ return g_steal_pointer(&ret); ++} + + #ifdef QGA_BUILD_UNIT_TEST + #if GLIB_CHECK_VERSION(2, 60, 0) +@@ -426,6 +466,31 @@ test_remove_keys(void) + "algo some-key another\n"); + } + ++static void ++test_get_keys(void) ++{ ++ Error *err = NULL; ++ static const char *authkeys = ++ "algo key1 comments\n" ++ "# a commented line\n" ++ "algo some-key another\n"; ++ g_autoptr(GuestAuthorizedKeys) ret = NULL; ++ strList *k; ++ size_t len = 0; ++ ++ test_authorized_keys_set(authkeys); ++ ++ ret = qmp_guest_ssh_get_authorized_keys(g_get_user_name(), &err); ++ g_assert(err == NULL); ++ ++ for (len = 0, k = ret->keys; k != NULL; k = k->next) { ++ g_assert(g_str_has_prefix(k->value, "algo ")); ++ len++; ++ } ++ ++ g_assert(len == 2); ++} ++ + int main(int argc, char *argv[]) + { + setlocale(LC_ALL, ""); +@@ -437,6 +502,7 @@ int main(int argc, char *argv[]) + g_test_add_func("/qga/ssh/add_keys", test_add_keys); + g_test_add_func("/qga/ssh/add_reset_keys", test_add_reset_keys); + g_test_add_func("/qga/ssh/remove_keys", test_remove_keys); ++ g_test_add_func("/qga/ssh/get_keys", test_get_keys); + + return g_test_run(); + } +diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json +index a70ea5da77..97bf96712e 100644 +--- a/qga/qapi-schema.json ++++ b/qga/qapi-schema.json +@@ -1274,6 +1274,36 @@ + { 'command': 'guest-get-osinfo', + 'returns': 'GuestOSInfo' } + ++## ++# @GuestAuthorizedKeys: ++# ++# @keys: public keys (in OpenSSH/sshd(8) authorized_keys format) ++# ++# Since: 5.2 ++## ++{ 'struct': 'GuestAuthorizedKeys', ++ 'data': { ++ 'keys': ['str'] ++ }, ++ 'if': 'defined(CONFIG_POSIX)' } ++ ++## ++# @guest-ssh-get-authorized-keys: ++# ++# @username: the user account to add the authorized keys ++# ++# Return the public keys from user .ssh/authorized_keys on Unix systems (not ++# implemented for other systems). ++# ++# Returns: @GuestAuthorizedKeys ++# ++# Since: 5.2 ++## ++{ 'command': 'guest-ssh-get-authorized-keys', ++ 'data': { 'username': 'str' }, ++ 'returns': 'GuestAuthorizedKeys', ++ 'if': 'defined(CONFIG_POSIX)' } ++ + ## + # @guest-ssh-add-authorized-keys: + # +-- +2.27.0 + diff --git a/SOURCES/kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch b/SOURCES/kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch index 95df72c..917e3ff 100644 --- a/SOURCES/kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch +++ b/SOURCES/kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch @@ -1,4 +1,4 @@ -From e0b83063b76725878c466f1b8918c61864cfd0c2 Mon Sep 17 00:00:00 2001 +From 4079c4e96f910fe7e57af13feb433f06246f1d79 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:44 -0400 Subject: [PATCH 6/9] rtl8139: switch to use qemu_receive_packet() for loopback diff --git a/SOURCES/kvm-scsi-make-io_timeout-configurable.patch b/SOURCES/kvm-scsi-make-io_timeout-configurable.patch new file mode 100644 index 0000000..a073728 --- /dev/null +++ b/SOURCES/kvm-scsi-make-io_timeout-configurable.patch @@ -0,0 +1,177 @@ +From 2903ab6d961b2165f3cbfb786cd3be59a407a6b4 Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Mon, 16 Nov 2020 19:31:13 +0100 +Subject: [PATCH] scsi: make io_timeout configurable + +RH-Author: Paolo Bonzini +RH-MergeRequest: 40: scsi: make io_timeout configurable +RH-Commit: [1/1] 147c4b7bac867c708c1905e98c4f9329ab4ef838 +RH-Bugzilla: 1994041 +RH-Acked-by: Jon Maloy +RH-Acked-by: Thomas Huth +RH-Acked-by: Laszlo Ersek + +The current code sets an infinite timeout on SG_IO requests, +causing the guest to stall if the host experiences a frame +loss. +This patch adds an 'io_timeout' parameter for SCSIDevice to +make the SG_IO timeout configurable, and also shortens the +default timeout to 30 seconds to avoid infinite stalls. + +Signed-off-by: Hannes Reinecke +Message-Id: <20201116183114.55703-3-hare@suse.de> +Signed-off-by: Paolo Bonzini +(cherry picked from commit c9b6609b69facad0cc5425d4fa7934c33d7f2e91) +--- + hw/scsi/scsi-disk.c | 6 ++++-- + hw/scsi/scsi-generic.c | 17 +++++++++++------ + include/hw/scsi/scsi.h | 4 +++- + 3 files changed, 18 insertions(+), 9 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index e44c61eeb4..5cb5fd35bd 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -2610,7 +2610,7 @@ static int get_device_type(SCSIDiskState *s) + cmd[4] = sizeof(buf); + + ret = scsi_SG_IO_FROM_DEV(s->qdev.conf.blk, cmd, sizeof(cmd), +- buf, sizeof(buf)); ++ buf, sizeof(buf), s->qdev.io_timeout); + if (ret < 0) { + return -1; + } +@@ -2771,7 +2771,7 @@ static BlockAIOCB *scsi_block_do_sgio(SCSIBlockReq *req, + /* The rest is as in scsi-generic.c. */ + io_header->mx_sb_len = sizeof(r->req.sense); + io_header->sbp = r->req.sense; +- io_header->timeout = UINT_MAX; ++ io_header->timeout = s->qdev.io_timeout * 1000; + io_header->usr_ptr = r; + io_header->flags |= SG_FLAG_DIRECT_IO; + +@@ -3089,6 +3089,8 @@ static Property scsi_block_properties[] = { + DEFAULT_MAX_IO_SIZE), + DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version, + -1), ++ DEFINE_PROP_UINT32("io_timeout", SCSIDiskState, qdev.io_timeout, ++ DEFAULT_IO_TIMEOUT), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c +index e7798ebcd0..3a383fe4d6 100644 +--- a/hw/scsi/scsi-generic.c ++++ b/hw/scsi/scsi-generic.c +@@ -114,6 +114,8 @@ static int execute_command(BlockBackend *blk, + SCSIGenericReq *r, int direction, + BlockCompletionFunc *complete) + { ++ SCSIDevice *s = r->req.dev; ++ + r->io_header.interface_id = 'S'; + r->io_header.dxfer_direction = direction; + r->io_header.dxferp = r->buf; +@@ -122,7 +124,7 @@ static int execute_command(BlockBackend *blk, + r->io_header.cmd_len = r->req.cmd.len; + r->io_header.mx_sb_len = sizeof(r->req.sense); + r->io_header.sbp = r->req.sense; +- r->io_header.timeout = MAX_UINT; ++ r->io_header.timeout = s->io_timeout * 1000; + r->io_header.usr_ptr = r; + r->io_header.flags |= SG_FLAG_DIRECT_IO; + +@@ -503,7 +505,7 @@ static int read_naa_id(const uint8_t *p, uint64_t *p_wwn) + } + + int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, +- uint8_t *buf, uint8_t buf_size) ++ uint8_t *buf, uint8_t buf_size, uint32_t timeout) + { + sg_io_hdr_t io_header; + uint8_t sensebuf[8]; +@@ -518,7 +520,7 @@ int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, + io_header.cmd_len = cmd_size; + io_header.mx_sb_len = sizeof(sensebuf); + io_header.sbp = sensebuf; +- io_header.timeout = 6000; /* XXX */ ++ io_header.timeout = timeout * 1000; + + ret = blk_ioctl(blk, SG_IO, &io_header); + if (ret < 0 || io_header.driver_status || io_header.host_status) { +@@ -548,7 +550,7 @@ static void scsi_generic_set_vpd_bl_emulation(SCSIDevice *s) + cmd[4] = sizeof(buf); + + ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd), +- buf, sizeof(buf)); ++ buf, sizeof(buf), s->io_timeout); + if (ret < 0) { + /* + * Do not assume anything if we can't retrieve the +@@ -584,7 +586,7 @@ static void scsi_generic_read_device_identification(SCSIDevice *s) + cmd[4] = sizeof(buf); + + ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd), +- buf, sizeof(buf)); ++ buf, sizeof(buf), s->io_timeout); + if (ret < 0) { + return; + } +@@ -635,7 +637,7 @@ static int get_stream_blocksize(BlockBackend *blk) + cmd[0] = MODE_SENSE; + cmd[4] = sizeof(buf); + +- ret = scsi_SG_IO_FROM_DEV(blk, cmd, sizeof(cmd), buf, sizeof(buf)); ++ ret = scsi_SG_IO_FROM_DEV(blk, cmd, sizeof(cmd), buf, sizeof(buf), 6); + if (ret < 0) { + return -1; + } +@@ -725,6 +727,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp) + + /* Only used by scsi-block, but initialize it nevertheless to be clean. */ + s->default_scsi_version = -1; ++ s->io_timeout = DEFAULT_IO_TIMEOUT; + scsi_generic_read_device_inquiry(s); + } + +@@ -748,6 +751,8 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, + static Property scsi_generic_properties[] = { + DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk), + DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false), ++ DEFINE_PROP_UINT32("io_timeout", SCSIDevice, io_timeout, ++ DEFAULT_IO_TIMEOUT), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h +index 332ef602f4..ae0724a32d 100644 +--- a/include/hw/scsi/scsi.h ++++ b/include/hw/scsi/scsi.h +@@ -17,6 +17,7 @@ typedef struct SCSIReqOps SCSIReqOps; + + #define SCSI_SENSE_BUF_SIZE_OLD 96 + #define SCSI_SENSE_BUF_SIZE 252 ++#define DEFAULT_IO_TIMEOUT 30 + + struct SCSIRequest { + SCSIBus *bus; +@@ -88,6 +89,7 @@ struct SCSIDevice + uint64_t port_wwn; + int scsi_version; + int default_scsi_version; ++ uint32_t io_timeout; + bool needs_vpd_bl_emulation; + bool hba_supports_iothread; + }; +@@ -192,7 +194,7 @@ void scsi_device_unit_attention_reported(SCSIDevice *dev); + void scsi_generic_read_device_inquiry(SCSIDevice *dev); + int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); + int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, +- uint8_t *buf, uint8_t buf_size); ++ uint8_t *buf, uint8_t buf_size, uint32_t timeout); + SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); + + /* scsi-generic.c. */ +-- +2.18.2 + diff --git a/SOURCES/kvm-softmmu-memory-Log-invalid-memory-accesses.patch b/SOURCES/kvm-softmmu-memory-Log-invalid-memory-accesses.patch index 9b468ed..e4e1bc4 100644 --- a/SOURCES/kvm-softmmu-memory-Log-invalid-memory-accesses.patch +++ b/SOURCES/kvm-softmmu-memory-Log-invalid-memory-accesses.patch @@ -1,7 +1,7 @@ -From 251adb595eb7e39e9368cb7ed07f9a4c42d28d2c Mon Sep 17 00:00:00 2001 +From be0a190e3c5c4ff84f7c53630ed5a55644d18acc Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Wed, 21 Apr 2021 22:30:06 -0400 -Subject: [PATCH 7/8] softmmu/memory: Log invalid memory accesses +Subject: [PATCH 7/7] softmmu/memory: Log invalid memory accesses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -10,7 +10,7 @@ RH-Author: Jon Maloy Message-id: <20210421223006.19650-7-jmaloy@redhat.com> Patchwork-id: 101481 O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 6/6] softmmu/memory: Log invalid memory accesses -Bugzilla: 1944621 +Bugzilla: 1842478 RH-Acked-by: Stefano Garzarella RH-Acked-by: Philippe Mathieu-Daudé RH-Acked-by: Laszlo Ersek diff --git a/SOURCES/kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch b/SOURCES/kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch new file mode 100644 index 0000000..8d30406 --- /dev/null +++ b/SOURCES/kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch @@ -0,0 +1,165 @@ +From f9d332b1280cd3f6009b59323719548a36a7c52b Mon Sep 17 00:00:00 2001 +From: Daniel Henrique Barboza +Date: Mon, 21 Jun 2021 14:40:24 -0400 +Subject: [PATCH 2/4] spapr: Fix EEH capability issue on KVM guest for PCI + passthru + +RH-Author: Daniel Henrique Barboza +Message-id: <20210621144024.199732-2-dbarboza@redhat.com> +Patchwork-id: 101740 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] spapr: Fix EEH capability issue on KVM guest for PCI passthru +Bugzilla: 1957866 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Greg Kurz +RH-Acked-by: David Gibson + +From: Mahesh Salgaonkar + +With upstream kernel, especially after commit 98ba956f6a389 +("powerpc/pseries/eeh: Rework device EEH PE determination") we see that KVM +guest isn't able to enable EEH option for PCI pass-through devices anymore. + +[root@atest-guest ~]# dmesg | grep EEH +[ 0.032337] EEH: pSeries platform initialized +[ 0.298207] EEH: No capable adapters found: recovery disabled. +[root@atest-guest ~]# + +So far the linux kernel was assuming pe_config_addr equal to device's +config_addr and using it to enable EEH on the PE through ibm,set-eeh-option +RTAS call. Which wasn't the correct way as per PAPR. The linux kernel +commit 98ba956f6a389 fixed this flow. With that fixed, linux now uses PE +config address returned by ibm,get-config-addr-info2 RTAS call to enable +EEH option per-PE basis instead of per-device basis. However this has +uncovered a bug in qemu where ibm,set-eeh-option is treating PE config +address as per-device config address. + +Hence in qemu guest with recent kernel the ibm,set-eeh-option RTAS call +fails with -3 return value indicating that there is no PCI device exist for +the specified PE config address. The rtas_ibm_set_eeh_option call uses +pci_find_device() to get the PC device that matches specific bus and devfn +extracted from PE config address passed as argument. Thus it tries to map +the PE config address to a single specific PCI device 'bus->devices[devfn]' +which always results into checking device on slot 0 'bus->devices[0]'. +This succeeds when there is a pass-through device (vfio-pci) present on +slot 0. But in cases where there is no pass-through device present in slot +0, but present in non-zero slots, ibm,set-eeh-option call fails to enable +the EEH capability. + +hw/ppc/spapr_pci_vfio.c: spapr_phb_vfio_eeh_set_option() + case RTAS_EEH_ENABLE: { + PCIHostState *phb; + PCIDevice *pdev; + + /* + * The EEH functionality is enabled on basis of PCI device, + * instead of PE. We need check the validity of the PCI + * device address. + */ + phb = PCI_HOST_BRIDGE(sphb); + pdev = pci_find_device(phb->bus, + (addr >> 16) & 0xFF, (addr >> 8) & 0xFF); + if (!pdev || !object_dynamic_cast(OBJECT(pdev), "vfio-pci")) { + return RTAS_OUT_PARAM_ERROR; + } + +hw/pci/pci.c:pci_find_device() + +PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn) +{ + bus = pci_find_bus_nr(bus, bus_num); + + if (!bus) + return NULL; + + return bus->devices[devfn]; +} + +This patch fixes ibm,set-eeh-option to check for presence of any PCI device +(vfio-pci) under specified bus and enable the EEH if found. The current +code already makes sure that all the devices on that bus are from same +iommu group (within same PE) and fail very early if it does not. + +After this fix guest is able to find EEH capable devices and enable EEH +recovery on it. + +[root@atest-guest ~]# dmesg | grep EEH +[ 0.048139] EEH: pSeries platform initialized +[ 0.405115] EEH: Capable adapter found: recovery enabled. +[root@atest-guest ~]# + +Reviewed-by: Daniel Henrique Barboza +Signed-off-by: Mahesh Salgaonkar +Message-Id: <162158429107.145117.5843504911924013125.stgit@jupiter> +Signed-off-by: David Gibson +(cherry picked from commit ac9ef668321ebb6eb871a0c4dd380fa7d7891b4e) +Signed-off-by: Daniel Henrique Barboza +Signed-off-by: Danilo C. L. de Paula +--- + hw/ppc/spapr_pci_vfio.c | 40 +++++++++++++++++++++++++++++++++------- + 1 file changed, 33 insertions(+), 7 deletions(-) + +diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c +index ecb34aaade..a411b08d60 100644 +--- a/hw/ppc/spapr_pci_vfio.c ++++ b/hw/ppc/spapr_pci_vfio.c +@@ -48,6 +48,16 @@ void spapr_phb_vfio_reset(DeviceState *qdev) + spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev)); + } + ++static void spapr_eeh_pci_find_device(PCIBus *bus, PCIDevice *pdev, ++ void *opaque) ++{ ++ bool *found = opaque; ++ ++ if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) { ++ *found = true; ++ } ++} ++ + int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb, + unsigned int addr, int option) + { +@@ -60,17 +70,33 @@ int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb, + break; + case RTAS_EEH_ENABLE: { + PCIHostState *phb; +- PCIDevice *pdev; ++ bool found = false; + + /* +- * The EEH functionality is enabled on basis of PCI device, +- * instead of PE. We need check the validity of the PCI +- * device address. ++ * The EEH functionality is enabled per sphb level instead of ++ * per PCI device. We have already identified this specific sphb ++ * based on buid passed as argument to ibm,set-eeh-option rtas ++ * call. Now we just need to check the validity of the PCI ++ * pass-through devices (vfio-pci) under this sphb bus. ++ * We have already validated that all the devices under this sphb ++ * are from same iommu group (within same PE) before comming here. ++ * ++ * Prior to linux commit 98ba956f6a389 ("powerpc/pseries/eeh: ++ * Rework device EEH PE determination") kernel would call ++ * eeh-set-option for each device in the PE using the device's ++ * config_address as the argument rather than the PE address. ++ * Hence if we check validity of supplied config_addr whether ++ * it matches to this PHB will cause issues with older kernel ++ * versions v5.9 and older. If we return an error from ++ * eeh-set-option when the argument isn't a valid PE address ++ * then older kernels (v5.9 and older) will interpret that as ++ * EEH not being supported. + */ + phb = PCI_HOST_BRIDGE(sphb); +- pdev = pci_find_device(phb->bus, +- (addr >> 16) & 0xFF, (addr >> 8) & 0xFF); +- if (!pdev || !object_dynamic_cast(OBJECT(pdev), "vfio-pci")) { ++ pci_for_each_device(phb->bus, (addr >> 16) & 0xFF, ++ spapr_eeh_pci_find_device, &found); ++ ++ if (!found) { + return RTAS_OUT_PARAM_ERROR; + } + +-- +2.27.0 + diff --git a/SOURCES/kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch b/SOURCES/kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch new file mode 100644 index 0000000..4f15509 --- /dev/null +++ b/SOURCES/kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch @@ -0,0 +1,50 @@ +From b46fdf56b1a7938468565838bdadf260870e4f9b Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Wed, 9 Jun 2021 10:05:00 -0400 +Subject: [PATCH 3/4] spapr: Remove stale comment about power-saving LPCR bits +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +Message-id: <20210609100501.427096-2-lvivier@redhat.com> +Patchwork-id: 101682 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] spapr: Remove stale comment about power-saving LPCR bits +Bugzilla: 1969768 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: David Gibson +RH-Acked-by: Greg Kurz + +From: Nicholas Piggin + +Commit 47a9b551547 ("spapr: Clean up handling of LPCR power-saving exit +bits") moved this logic but did not remove the comment from the +previous location. + +Signed-off-by: Nicholas Piggin +Message-Id: <20210526091626.3388262-2-npiggin@gmail.com> +Reviewed-by: Cédric Le Goater +Reviewed-by: Greg Kurz +Signed-off-by: David Gibson +(cherry picked from commit 7be3bf6c8429969f97728bb712d9a99997835607) +Signed-off-by: Laurent Vivier +Signed-off-by: Danilo C. L. de Paula +--- + hw/ppc/spapr_rtas.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c +index 8d8d8cdfcb..295eac986e 100644 +--- a/hw/ppc/spapr_rtas.c ++++ b/hw/ppc/spapr_rtas.c +@@ -163,7 +163,6 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, + + env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); + +- /* Enable Power-saving mode Exit Cause exceptions for the new CPU */ + lpcr = env->spr[SPR_LPCR]; + if (!pcc->interrupts_big_endian(callcpu)) { + lpcr |= LPCR_ILE; +-- +2.27.0 + diff --git a/SOURCES/kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch b/SOURCES/kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch new file mode 100644 index 0000000..84abc74 --- /dev/null +++ b/SOURCES/kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch @@ -0,0 +1,89 @@ +From 28794dca79a94d01c8732b84fe6ac6ba2986ce45 Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Wed, 9 Jun 2021 10:05:01 -0400 +Subject: [PATCH 4/4] spapr: Set LPCR to current AIL mode when starting a new + CPU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +Message-id: <20210609100501.427096-3-lvivier@redhat.com> +Patchwork-id: 101683 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] spapr: Set LPCR to current AIL mode when starting a new CPU +Bugzilla: 1969768 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: David Gibson +RH-Acked-by: Greg Kurz + +From: Nicholas Piggin + +TCG does not keep track of AIL mode in a central place, it's based on +the current LPCR[AIL] bits. Synchronize the new CPU's LPCR to the +current LPCR in rtas_start_cpu(), similarly to the way the ILE bit is +synchronized. + +Open-code the ILE setting as well now that the caller's LPCR is +available directly, there is no need for the indirection. + +Without this, under both TCG and KVM, adding a POWER8/9/10 class CPU +with a new core ID after a modern Linux has booted results in the new +CPU's LPCR missing the LPCR[AIL]=0b11 setting that the other CPUs have. +This can cause crashes and unexpected behaviour. + +Signed-off-by: Nicholas Piggin +Message-Id: <20210526091626.3388262-3-npiggin@gmail.com> +Reviewed-by: Cédric Le Goater +Reviewed-by: Greg Kurz +Signed-off-by: David Gibson +(cherry picked from commit ac559ecbea2649819e7b3fdd09f4e0243e0128db) +Signed-off-by: Laurent Vivier +Signed-off-by: Danilo C. L. de Paula +--- + hw/ppc/spapr_rtas.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c +index 295eac986e..5acb7c1f10 100644 +--- a/hw/ppc/spapr_rtas.c ++++ b/hw/ppc/spapr_rtas.c +@@ -132,8 +132,8 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, + target_ulong id, start, r3; + PowerPCCPU *newcpu; + CPUPPCState *env; +- PowerPCCPUClass *pcc; + target_ulong lpcr; ++ target_ulong caller_lpcr; + + if (nargs != 3 || nret != 1) { + rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); +@@ -152,7 +152,6 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, + } + + env = &newcpu->env; +- pcc = POWERPC_CPU_GET_CLASS(newcpu); + + if (!CPU(newcpu)->halted) { + rtas_st(rets, 0, RTAS_OUT_HW_ERROR); +@@ -163,10 +162,15 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, + + env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); + ++ caller_lpcr = callcpu->env.spr[SPR_LPCR]; + lpcr = env->spr[SPR_LPCR]; +- if (!pcc->interrupts_big_endian(callcpu)) { +- lpcr |= LPCR_ILE; +- } ++ ++ /* Set ILE the same way */ ++ lpcr = (lpcr & ~LPCR_ILE) | (caller_lpcr & LPCR_ILE); ++ ++ /* Set AIL the same way */ ++ lpcr = (lpcr & ~LPCR_AIL) | (caller_lpcr & LPCR_AIL); ++ + if (env->mmu_model == POWERPC_MMU_3_00) { + /* + * New cpus are expected to start in the same radix/hash mode +-- +2.27.0 + diff --git a/SOURCES/kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch b/SOURCES/kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch index 47f8f13..e8c9f8b 100644 --- a/SOURCES/kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch +++ b/SOURCES/kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch @@ -1,4 +1,4 @@ -From 1a56df13e6a033548b22489d3b148009c8f80718 Mon Sep 17 00:00:00 2001 +From 07df0f52c26a3819bc02b4f2970b6735bcf15c5b Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:42 -0400 Subject: [PATCH 4/9] sungem: switch to use qemu_receive_packet() for loopback diff --git a/SOURCES/kvm-tftp-check-tftp_input-buffer-size.patch b/SOURCES/kvm-tftp-check-tftp_input-buffer-size.patch new file mode 100644 index 0000000..85ed811 --- /dev/null +++ b/SOURCES/kvm-tftp-check-tftp_input-buffer-size.patch @@ -0,0 +1,53 @@ +From 6bd4d80f9274f76eb402ce85aa60729150b39980 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:56:34 -0400 +Subject: [PATCH 09/14] tftp: check tftp_input buffer size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210708082537.1550263-6-marcandre.lureau@redhat.com> +Patchwork-id: 101823 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 5/8] tftp: check tftp_input buffer size +Bugzilla: 1970843 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +From: Marc-André Lureau + +Fixes: CVE-2021-3595 +Fixes: https://gitlab.freedesktop.org/slirp/libslirp/-/issues/46 + +Signed-off-by: Marc-André Lureau + +BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1970843 + +(cherry picked from commit 3f17948137155f025f7809fdc38576d5d2451c3d) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/src/tftp.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/slirp/src/tftp.c b/slirp/src/tftp.c +index 093c2e06a3..07e8f3cb2f 100644 +--- a/slirp/src/tftp.c ++++ b/slirp/src/tftp.c +@@ -444,7 +444,11 @@ static void tftp_handle_error(Slirp *slirp, struct sockaddr_storage *srcsas, + + void tftp_input(struct sockaddr_storage *srcsas, struct mbuf *m) + { +- struct tftp_t *tp = (struct tftp_t *)m->m_data; ++ struct tftp_t *tp = mtod_check(m, offsetof(struct tftp_t, x.tp_buf)); ++ ++ if (tp == NULL) { ++ return; ++ } + + switch (ntohs(tp->tp_op)) { + case TFTP_RRQ: +-- +2.27.0 + diff --git a/SOURCES/kvm-tftp-introduce-a-header-structure.patch b/SOURCES/kvm-tftp-introduce-a-header-structure.patch new file mode 100644 index 0000000..d8c8ddb --- /dev/null +++ b/SOURCES/kvm-tftp-introduce-a-header-structure.patch @@ -0,0 +1,263 @@ +From af72e344459614fcf2746739f05494ef7e691a78 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:56:36 -0400 +Subject: [PATCH 10/14] tftp: introduce a header structure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210708082537.1550263-7-marcandre.lureau@redhat.com> +Patchwork-id: 101825 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 6/8] tftp: introduce a header structure +Bugzilla: 1970819 1970835 1970843 1970853 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +From: Marc-André Lureau + +Instead of using a composed structure and potentially reading past the +incoming buffer, use a different structure for the header. + +Signed-off-by: Marc-André Lureau + +(cherry picked from commit 990163cf3ac86b7875559f49602c4d76f46f6f30) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/src/tftp.c | 58 +++++++++++++++++++++++++----------------------- + slirp/src/tftp.h | 6 ++++- + 2 files changed, 35 insertions(+), 29 deletions(-) + +diff --git a/slirp/src/tftp.c b/slirp/src/tftp.c +index 07e8f3cb2f..53e04d0aeb 100644 +--- a/slirp/src/tftp.c ++++ b/slirp/src/tftp.c +@@ -50,7 +50,7 @@ static void tftp_session_terminate(struct tftp_session *spt) + } + + static int tftp_session_allocate(Slirp *slirp, struct sockaddr_storage *srcsas, +- struct tftp_t *tp) ++ struct tftphdr *hdr) + { + struct tftp_session *spt; + int k; +@@ -75,7 +75,7 @@ found: + memcpy(&spt->client_addr, srcsas, sockaddr_size(srcsas)); + spt->fd = -1; + spt->block_size = 512; +- spt->client_port = tp->udp.uh_sport; ++ spt->client_port = hdr->udp.uh_sport; + spt->slirp = slirp; + + tftp_session_update(spt); +@@ -84,7 +84,7 @@ found: + } + + static int tftp_session_find(Slirp *slirp, struct sockaddr_storage *srcsas, +- struct tftp_t *tp) ++ struct tftphdr *hdr) + { + struct tftp_session *spt; + int k; +@@ -94,7 +94,7 @@ static int tftp_session_find(Slirp *slirp, struct sockaddr_storage *srcsas, + + if (tftp_session_in_use(spt)) { + if (sockaddr_equal(&spt->client_addr, srcsas)) { +- if (spt->client_port == tp->udp.uh_sport) { ++ if (spt->client_port == hdr->udp.uh_sport) { + return k; + } + } +@@ -146,13 +146,13 @@ static struct tftp_t *tftp_prep_mbuf_data(struct tftp_session *spt, + } + + static void tftp_udp_output(struct tftp_session *spt, struct mbuf *m, +- struct tftp_t *recv_tp) ++ struct tftphdr *hdr) + { + if (spt->client_addr.ss_family == AF_INET6) { + struct sockaddr_in6 sa6, da6; + + sa6.sin6_addr = spt->slirp->vhost_addr6; +- sa6.sin6_port = recv_tp->udp.uh_dport; ++ sa6.sin6_port = hdr->udp.uh_dport; + da6.sin6_addr = ((struct sockaddr_in6 *)&spt->client_addr)->sin6_addr; + da6.sin6_port = spt->client_port; + +@@ -161,7 +161,7 @@ static void tftp_udp_output(struct tftp_session *spt, struct mbuf *m, + struct sockaddr_in sa4, da4; + + sa4.sin_addr = spt->slirp->vhost_addr; +- sa4.sin_port = recv_tp->udp.uh_dport; ++ sa4.sin_port = hdr->udp.uh_dport; + da4.sin_addr = ((struct sockaddr_in *)&spt->client_addr)->sin_addr; + da4.sin_port = spt->client_port; + +@@ -183,7 +183,7 @@ static int tftp_send_oack(struct tftp_session *spt, const char *keys[], + + tp = tftp_prep_mbuf_data(spt, m); + +- tp->tp_op = htons(TFTP_OACK); ++ tp->hdr.tp_op = htons(TFTP_OACK); + for (i = 0; i < nb; i++) { + n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s", + keys[i]) + +@@ -195,7 +195,7 @@ static int tftp_send_oack(struct tftp_session *spt, const char *keys[], + + m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + n - + sizeof(struct udphdr); +- tftp_udp_output(spt, m, recv_tp); ++ tftp_udp_output(spt, m, &recv_tp->hdr); + + return 0; + } +@@ -216,21 +216,21 @@ static void tftp_send_error(struct tftp_session *spt, uint16_t errorcode, + + tp = tftp_prep_mbuf_data(spt, m); + +- tp->tp_op = htons(TFTP_ERROR); ++ tp->hdr.tp_op = htons(TFTP_ERROR); + tp->x.tp_error.tp_error_code = htons(errorcode); + slirp_pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), + msg); + + m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + 3 + + strlen(msg) - sizeof(struct udphdr); +- tftp_udp_output(spt, m, recv_tp); ++ tftp_udp_output(spt, m, &recv_tp->hdr); + + out: + tftp_session_terminate(spt); + } + + static void tftp_send_next_block(struct tftp_session *spt, +- struct tftp_t *recv_tp) ++ struct tftphdr *hdr) + { + struct mbuf *m; + struct tftp_t *tp; +@@ -244,7 +244,7 @@ static void tftp_send_next_block(struct tftp_session *spt, + + tp = tftp_prep_mbuf_data(spt, m); + +- tp->tp_op = htons(TFTP_DATA); ++ tp->hdr.tp_op = htons(TFTP_DATA); + tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff); + + nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, +@@ -262,7 +262,7 @@ static void tftp_send_next_block(struct tftp_session *spt, + + m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX - nobytes) - + sizeof(struct udphdr); +- tftp_udp_output(spt, m, recv_tp); ++ tftp_udp_output(spt, m, hdr); + + if (nobytes == spt->block_size) { + tftp_session_update(spt); +@@ -285,12 +285,12 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas, + int nb_options = 0; + + /* check if a session already exists and if so terminate it */ +- s = tftp_session_find(slirp, srcsas, tp); ++ s = tftp_session_find(slirp, srcsas, &tp->hdr); + if (s >= 0) { + tftp_session_terminate(&slirp->tftp_sessions[s]); + } + +- s = tftp_session_allocate(slirp, srcsas, tp); ++ s = tftp_session_allocate(slirp, srcsas, &tp->hdr); + + if (s < 0) { + return; +@@ -411,29 +411,29 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas, + } + + spt->block_nr = 0; +- tftp_send_next_block(spt, tp); ++ tftp_send_next_block(spt, &tp->hdr); + } + + static void tftp_handle_ack(Slirp *slirp, struct sockaddr_storage *srcsas, +- struct tftp_t *tp, int pktlen) ++ struct tftphdr *hdr) + { + int s; + +- s = tftp_session_find(slirp, srcsas, tp); ++ s = tftp_session_find(slirp, srcsas, hdr); + + if (s < 0) { + return; + } + +- tftp_send_next_block(&slirp->tftp_sessions[s], tp); ++ tftp_send_next_block(&slirp->tftp_sessions[s], hdr); + } + + static void tftp_handle_error(Slirp *slirp, struct sockaddr_storage *srcsas, +- struct tftp_t *tp, int pktlen) ++ struct tftphdr *hdr) + { + int s; + +- s = tftp_session_find(slirp, srcsas, tp); ++ s = tftp_session_find(slirp, srcsas, hdr); + + if (s < 0) { + return; +@@ -444,23 +444,25 @@ static void tftp_handle_error(Slirp *slirp, struct sockaddr_storage *srcsas, + + void tftp_input(struct sockaddr_storage *srcsas, struct mbuf *m) + { +- struct tftp_t *tp = mtod_check(m, offsetof(struct tftp_t, x.tp_buf)); ++ struct tftphdr *hdr = mtod_check(m, sizeof(struct tftphdr)); + +- if (tp == NULL) { ++ if (hdr == NULL) { + return; + } + +- switch (ntohs(tp->tp_op)) { ++ switch (ntohs(hdr->tp_op)) { + case TFTP_RRQ: +- tftp_handle_rrq(m->slirp, srcsas, tp, m->m_len); ++ tftp_handle_rrq(m->slirp, srcsas, ++ mtod(m, struct tftp_t *), ++ m->m_len); + break; + + case TFTP_ACK: +- tftp_handle_ack(m->slirp, srcsas, tp, m->m_len); ++ tftp_handle_ack(m->slirp, srcsas, hdr); + break; + + case TFTP_ERROR: +- tftp_handle_error(m->slirp, srcsas, tp, m->m_len); ++ tftp_handle_error(m->slirp, srcsas, hdr); + break; + } + } +diff --git a/slirp/src/tftp.h b/slirp/src/tftp.h +index c47bb43c7d..021f6cf109 100644 +--- a/slirp/src/tftp.h ++++ b/slirp/src/tftp.h +@@ -18,9 +18,13 @@ + #define TFTP_FILENAME_MAX 512 + #define TFTP_BLOCKSIZE_MAX 1428 + +-struct tftp_t { ++struct tftphdr { + struct udphdr udp; + uint16_t tp_op; ++} SLIRP_PACKED; ++ ++struct tftp_t { ++ struct tftphdr hdr; + union { + struct { + uint16_t tp_block_nr; +-- +2.27.0 + diff --git a/SOURCES/kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch b/SOURCES/kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch index fdb9496..4da71cc 100644 --- a/SOURCES/kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch +++ b/SOURCES/kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch @@ -1,4 +1,4 @@ -From 199915a03857c1e4e0a6ac90a46496b1a8abd702 Mon Sep 17 00:00:00 2001 +From 87cacc268f37758553ad93fefa8b312ed0bd2520 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 29 Jun 2021 03:42:43 -0400 Subject: [PATCH 5/9] tx_pkt: switch to use qemu_receive_packet_iov() for diff --git a/SOURCES/kvm-udp-check-upd_input-buffer-size.patch b/SOURCES/kvm-udp-check-upd_input-buffer-size.patch new file mode 100644 index 0000000..0f3c6f3 --- /dev/null +++ b/SOURCES/kvm-udp-check-upd_input-buffer-size.patch @@ -0,0 +1,52 @@ +From 1b8aa33b218a8ff3e8aa2f1b6875df40fd70f0ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:56:40 -0400 +Subject: [PATCH 11/14] udp: check upd_input buffer size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210708082537.1550263-8-marcandre.lureau@redhat.com> +Patchwork-id: 101826 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 7/8] udp: check upd_input buffer size +Bugzilla: 1970853 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +From: Marc-André Lureau + +Fixes: CVE-2021-3594 +Fixes: https://gitlab.freedesktop.org/slirp/libslirp/-/issues/47 + +Signed-off-by: Marc-André Lureau + +BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1970853 + +(cherry picked from commit 74572be49247c8c5feae7c6e0b50c4f569ca9824) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/src/udp.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/slirp/src/udp.c b/slirp/src/udp.c +index ae23ba4b2a..86142bba14 100644 +--- a/slirp/src/udp.c ++++ b/slirp/src/udp.c +@@ -90,7 +90,10 @@ void udp_input(register struct mbuf *m, int iphlen) + /* + * Get IP and UDP header together in first mbuf. + */ +- ip = mtod(m, struct ip *); ++ ip = mtod_check(m, iphlen + sizeof(struct udphdr)); ++ if (ip == NULL) { ++ goto bad; ++ } + uh = (struct udphdr *)((char *)ip + iphlen); + + /* +-- +2.27.0 + diff --git a/SOURCES/kvm-upd6-check-udp6_input-buffer-size.patch b/SOURCES/kvm-upd6-check-udp6_input-buffer-size.patch new file mode 100644 index 0000000..2aa3a24 --- /dev/null +++ b/SOURCES/kvm-upd6-check-udp6_input-buffer-size.patch @@ -0,0 +1,52 @@ +From 6808086932ddc83fd748c46fea495e7004299b55 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 29 Jul 2021 04:56:31 -0400 +Subject: [PATCH 08/14] upd6: check udp6_input buffer size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20210708082537.1550263-5-marcandre.lureau@redhat.com> +Patchwork-id: 101822 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 4/8] upd6: check udp6_input buffer size +Bugzilla: 1970835 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +From: Marc-André Lureau + +Fixes: CVE-2021-3593 +Fixes: https://gitlab.freedesktop.org/slirp/libslirp/-/issues/45 + +Signed-off-by: Marc-André Lureau + +BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1970835 + +(cherry picked from commit de71c15de66ba9350bf62c45b05f8fbff166517b) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/src/udp6.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/slirp/src/udp6.c b/slirp/src/udp6.c +index 6f9486bbca..8c490e4d10 100644 +--- a/slirp/src/udp6.c ++++ b/slirp/src/udp6.c +@@ -28,7 +28,10 @@ void udp6_input(struct mbuf *m) + ip = mtod(m, struct ip6 *); + m->m_len -= iphlen; + m->m_data += iphlen; +- uh = mtod(m, struct udphdr *); ++ uh = mtod_check(m, sizeof(struct udphdr)); ++ if (uh == NULL) { ++ goto bad; ++ } + m->m_len += iphlen; + m->m_data -= iphlen; + +-- +2.27.0 + diff --git a/SOURCES/kvm-vfio-ccw-Connect-the-device-request-notifier.patch b/SOURCES/kvm-vfio-ccw-Connect-the-device-request-notifier.patch new file mode 100644 index 0000000..298fb29 --- /dev/null +++ b/SOURCES/kvm-vfio-ccw-Connect-the-device-request-notifier.patch @@ -0,0 +1,128 @@ +From db6a782f8b9ba062f195ff504b4d2f93e471fecc Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Tue, 11 May 2021 11:24:05 -0400 +Subject: [PATCH 2/5] vfio-ccw: Connect the device request notifier + +RH-Author: Thomas Huth +Message-id: <20210511112405.297037-3-thuth@redhat.com> +Patchwork-id: 101536 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] vfio-ccw: Connect the device request notifier +Bugzilla: 1940450 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Cornelia Huck +RH-Acked-by: David Hildenbrand + +Now that the vfio-ccw code has a notifier interface to request that +a device be unplugged, let's wire that together. + +Signed-off-by: Eric Farman +Reviewed-by: Cornelia Huck +Message-Id: <20210104202057.48048-4-farman@linux.ibm.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit b2f96f9e4f5fbc8f2770a436191cb328da4d5350) +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940450 +Signed-off-by: Thomas Huth +Signed-off-by: Danilo C. L. de Paula +--- + hw/vfio/ccw.c | 40 ++++++++++++++++++++++++++++++++++++---- + 1 file changed, 36 insertions(+), 4 deletions(-) + +diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c +index b72a505893..3d450fe1c9 100644 +--- a/hw/vfio/ccw.c ++++ b/hw/vfio/ccw.c +@@ -49,6 +49,7 @@ struct VFIOCCWDevice { + struct ccw_crw_region *crw_region; + EventNotifier io_notifier; + EventNotifier crw_notifier; ++ EventNotifier req_notifier; + bool force_orb_pfch; + bool warned_orb_pfch; + }; +@@ -287,6 +288,21 @@ static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev) + } while (1); + } + ++static void vfio_ccw_req_notifier_handler(void *opaque) ++{ ++ VFIOCCWDevice *vcdev = opaque; ++ Error *err = NULL; ++ ++ if (!event_notifier_test_and_clear(&vcdev->req_notifier)) { ++ return; ++ } ++ ++ qdev_unplug(DEVICE(vcdev), &err); ++ if (err) { ++ warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name); ++ } ++} ++ + static void vfio_ccw_crw_notifier_handler(void *opaque) + { + VFIOCCWDevice *vcdev = opaque; +@@ -386,6 +402,10 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev, + notifier = &vcdev->crw_notifier; + fd_read = vfio_ccw_crw_notifier_handler; + break; ++ case VFIO_CCW_REQ_IRQ_INDEX: ++ notifier = &vcdev->req_notifier; ++ fd_read = vfio_ccw_req_notifier_handler; ++ break; + default: + error_setg(errp, "vfio: Unsupported device irq(%d)", irq); + return; +@@ -440,6 +460,9 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev, + case VFIO_CCW_CRW_IRQ_INDEX: + notifier = &vcdev->crw_notifier; + break; ++ case VFIO_CCW_REQ_IRQ_INDEX: ++ notifier = &vcdev->req_notifier; ++ break; + default: + error_report("vfio: Unsupported device irq(%d)", irq); + return; +@@ -657,20 +680,28 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp) + + vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err); + if (err) { +- goto out_notifier_err; ++ goto out_io_notifier_err; + } + + if (vcdev->crw_region) { + vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, &err); + if (err) { +- vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); +- goto out_notifier_err; ++ goto out_crw_notifier_err; + } + } + ++ vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err); ++ if (err) { ++ goto out_req_notifier_err; ++ } ++ + return; + +-out_notifier_err: ++out_req_notifier_err: ++ vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); ++out_crw_notifier_err: ++ vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); ++out_io_notifier_err: + vfio_ccw_put_region(vcdev); + out_region_err: + vfio_ccw_put_device(vcdev); +@@ -692,6 +723,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp) + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev); + VFIOGroup *group = vcdev->vdev.group; + ++ vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX); + vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); + vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); + vfio_ccw_put_region(vcdev); +-- +2.27.0 + diff --git a/SOURCES/kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch b/SOURCES/kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch new file mode 100644 index 0000000..90b6b35 --- /dev/null +++ b/SOURCES/kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch @@ -0,0 +1,72 @@ +From 3ec945ba7c2649cca13cf6070c6365b1262ad1ec Mon Sep 17 00:00:00 2001 +From: Max Reitz +Date: Fri, 6 Aug 2021 11:58:26 -0400 +Subject: [PATCH 1/2] virtiofsd: Disable remote posix locks by default +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Max Reitz +Message-id: <20210806115827.740945-2-mreitz@redhat.com> +Patchwork-id: 101970 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] virtiofsd: Disable remote posix locks by default +Bugzilla: 1967496 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Vivek Goyal + +From: Vivek Goyal + +Right now we enable remote posix locks by default. That means when guest +does a posix lock it sends request to server (virtiofsd). But currently +we only support non-blocking posix lock and return -EOPNOTSUPP for +blocking version. + +This means that existing applications which are doing blocking posix +locks get -EOPNOTSUPP and fail. To avoid this, people have been +running virtiosd with option "-o no_posix_lock". For new users it +is still a surprise and trial and error takes them to this option. + +Given posix lock implementation is not complete in virtiofsd, disable +it by default. This means that posix locks will work with-in applications +in a guest but not across guests. Anyway we don't support sharing +filesystem among different guests yet in virtiofs so this should +not lead to any kind of surprise or regression and will make life +little easier for virtiofs users. + +Reported-by: Aa Aa +Suggested-by: Miklos Szeredi +Signed-off-by: Vivek Goyal +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Misono Tomohiro +Signed-off-by: Dr. David Alan Gilbert +(cherry picked from commit 88fc107956a5812649e5918e0c092d3f78bb28ad) + +Conflicts: + docs/tools/virtiofsd.rst + We do not have virtiofsd.rst downstream (added upstream in + commit 6a7e2bbee5fa), so I dropped that hunk (which effectively + updated the default value in the man page). + +Signed-off-by: Max Reitz +Signed-off-by: Danilo C. L. de Paula +--- + tools/virtiofsd/passthrough_ll.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c +index cb0992f2db..b47029da89 100644 +--- a/tools/virtiofsd/passthrough_ll.c ++++ b/tools/virtiofsd/passthrough_ll.c +@@ -3001,7 +3001,7 @@ int main(int argc, char *argv[]) + struct lo_data lo = { + .debug = 0, + .writeback = 0, +- .posix_lock = 1, ++ .posix_lock = 0, + .proc_self_fd = -1, + }; + struct lo_map_elem *root_elem; +-- +2.27.0 + diff --git a/SOURCES/kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch b/SOURCES/kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch new file mode 100644 index 0000000..98907a5 --- /dev/null +++ b/SOURCES/kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch @@ -0,0 +1,51 @@ +From 6abfb7b3c37015ff901d11f178bc6900deec2acf Mon Sep 17 00:00:00 2001 +From: Max Reitz +Date: Fri, 6 Aug 2021 11:58:27 -0400 +Subject: [PATCH 2/2] virtiofsd: Fix the help message of posix lock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Max Reitz +Message-id: <20210806115827.740945-3-mreitz@redhat.com> +Patchwork-id: 101969 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] virtiofsd: Fix the help message of posix lock +Bugzilla: 1967496 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Vivek Goyal + +From: Jiachen Zhang + +The commit 88fc107956a5812649e5918e0c092d3f78bb28ad disabled remote +posix locks by default. But the --help message still says it is enabled +by default. So fix it to output no_posix_lock. + +Signed-off-by: Jiachen Zhang +Message-Id: <20201027081558.29904-1-zhangjiachen.jaycee@bytedance.com> +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Dr. David Alan Gilbert +(cherry picked from commit 0429eaf518be1d4742356056e6c886b7f9bc9712) +Signed-off-by: Max Reitz +Signed-off-by: Danilo C. L. de Paula +--- + tools/virtiofsd/helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c +index 5b222ea49b..813d9490e5 100644 +--- a/tools/virtiofsd/helper.c ++++ b/tools/virtiofsd/helper.c +@@ -163,7 +163,7 @@ void fuse_cmdline_help(void) + " default: false\n" + " -o posix_lock|no_posix_lock\n" + " enable/disable remote posix lock\n" +- " default: posix_lock\n" ++ " default: no_posix_lock\n" + " -o readdirplus|no_readdirplus\n" + " enable/disable readirplus\n" + " default: readdirplus except with " +-- +2.27.0 + diff --git a/SOURCES/kvm-virtiofsd-Whitelist-fchmod.patch b/SOURCES/kvm-virtiofsd-Whitelist-fchmod.patch new file mode 100644 index 0000000..a4f95d9 --- /dev/null +++ b/SOURCES/kvm-virtiofsd-Whitelist-fchmod.patch @@ -0,0 +1,79 @@ +From 181ed1777c3dd50b1ff9907b0a4199e845af1270 Mon Sep 17 00:00:00 2001 +From: Max Reitz +Date: Fri, 18 Jun 2021 16:21:17 -0400 +Subject: [PATCH 1/4] virtiofsd: Whitelist fchmod +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Max Reitz +Message-id: <20210618162117.97775-2-mreitz@redhat.com> +Patchwork-id: 101719 +O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] virtiofsd: Whitelist fchmod +Bugzilla: 1967914 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Vivek Goyal +RH-Acked-by: Connor Kuehl + +lo_setattr() invokes fchmod() in a rarely used code path, so it should +be whitelisted or virtiofsd will crash with EBADSYS. + +Said code path can be triggered for example as follows: + +On the host, in the shared directory, create a file with the sticky bit +set and a security.capability xattr: +(1) # touch foo +(2) # chmod u+s foo +(3) # setcap '' foo + +Then in the guest let some process truncate that file after it has +dropped all of its capabilities (at least CAP_FSETID): + +int main(int argc, char *argv[]) +{ + capng_setpid(getpid()); + capng_clear(CAPNG_SELECT_BOTH); + capng_updatev(CAPNG_ADD, CAPNG_PERMITTED | CAPNG_EFFECTIVE, 0); + capng_apply(CAPNG_SELECT_BOTH); + + ftruncate(open(argv[1], O_RDWR), 0); +} + +This will cause the guest kernel to drop the sticky bit (i.e. perform a +mode change) as part of the truncate (where FATTR_FH is set), and that +will cause virtiofsd to invoke fchmod() instead of fchmodat(). + +(A similar configuration exists further below with futimens() vs. +utimensat(), but the former is not a syscall but just a wrapper for the +latter, so no further whitelisting is required.) + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1842667 +Reported-by: Qian Cai +Cc: qemu-stable@nongnu.org +Signed-off-by: Max Reitz +Message-Id: <20200608093111.14942-1-mreitz@redhat.com> +Reviewed-by: Dr. David Alan Gilbert +Reviewed-by: Vivek Goyal +Signed-off-by: Dr. David Alan Gilbert +(cherry picked from commit 63659fe74e76f5c5285466f0c5cfbdca65b3688e) +Signed-off-by: Max Reitz +Signed-off-by: Danilo C. L. de Paula +--- + tools/virtiofsd/seccomp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/virtiofsd/seccomp.c b/tools/virtiofsd/seccomp.c +index bd9e7b083c..3b1522acdd 100644 +--- a/tools/virtiofsd/seccomp.c ++++ b/tools/virtiofsd/seccomp.c +@@ -42,6 +42,7 @@ static const int syscall_whitelist[] = { + SCMP_SYS(exit_group), + SCMP_SYS(fallocate), + SCMP_SYS(fchdir), ++ SCMP_SYS(fchmod), + SCMP_SYS(fchmodat), + SCMP_SYS(fchownat), + SCMP_SYS(fcntl), +-- +2.27.0 + diff --git a/SOURCES/kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch b/SOURCES/kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch index f577210..aabe041 100644 --- a/SOURCES/kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch +++ b/SOURCES/kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch @@ -1,7 +1,7 @@ -From 33e907b7be4636a726d40a3d68cab24574bc597a Mon Sep 17 00:00:00 2001 +From f38f51d422e82d1241b678960dd6a033ffa398da Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Wed, 21 Apr 2021 22:30:05 -0400 -Subject: [PATCH 6/8] xhci: fix valid.max_access_size to access address +Subject: [PATCH 6/7] xhci: fix valid.max_access_size to access address registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -11,7 +11,7 @@ RH-Author: Jon Maloy Message-id: <20210421223006.19650-6-jmaloy@redhat.com> Patchwork-id: 101483 O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 5/6] xhci: fix valid.max_access_size to access address registers -Bugzilla: 1944621 +Bugzilla: 1842478 RH-Acked-by: Stefano Garzarella RH-Acked-by: Philippe Mathieu-Daudé RH-Acked-by: Laszlo Ersek diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index d88bcd7..f2f5fb5 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -61,13 +61,13 @@ Requires: %{name}-block-ssh = %{epoch}:%{version}-%{release} # Macro to properly setup RHEL/RHEV conflict handling %define rhev_ma_conflicts() \ -Obsoletes: %1-ma \ -Obsoletes: %1-rhev +Obsoletes: %1-ma <= %{epoch}:%{version}-%{release} \ +Obsoletes: %1-rhev <= %{epoch}:%{version}-%{release} Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 4.2.0 -Release: 48%{?dist}.3 +Release: 59%{?dist} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 15 License: GPLv2 and GPLv2+ and CC-BY @@ -1130,46 +1130,124 @@ Patch489: kvm-x86-cpu-Populate-SVM-CPUID-feature-bits.patch Patch490: kvm-i386-Add-the-support-for-AMD-EPYC-3rd-generation-pro.patch # For bz#1917451 - CVE-2020-29443 virt:rhel/qemu-kvm: QEMU: ide: atapi: OOB access while processing read commands [rhel-8.4.0] Patch491: kvm-ide-atapi-check-logical-block-address-and-read-size-.patch -# For bz#1939494 - CVE-2020-27617 virt:rhel/qemu-kvm: QEMU: net: an assert failure via eth_get_gso_type [rhel-8.4.0.z] +# For bz#1892350 - CVE-2020-27617 virt:rhel/qemu-kvm: QEMU: net: an assert failure via eth_get_gso_type [rhel-8.5.0] Patch492: kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch -# For bz#1944621 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.4.0.z] -Patch493: kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch -# For bz#1944621 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.4.0.z] -Patch494: kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch -# For bz#1944621 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.4.0.z] -Patch495: kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch -# For bz#1944621 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.4.0.z] -Patch496: kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch -# For bz#1944621 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.4.0.z] -Patch497: kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch -# For bz#1944621 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.4.0.z] -Patch498: kvm-softmmu-memory-Log-invalid-memory-accesses.patch -# For bz#1952986 - CVE-2021-20221 virt:rhel/qemu-kvm: qemu: out-of-bound heap buffer access via an interrupt ID field [rhel-8.4.0.z] -Patch499: kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch -# For bz#1975679 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm) [rhel-8.4.0.z] -Patch500: kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch -# For bz#1975679 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm) [rhel-8.4.0.z] -Patch501: kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch -# For bz#1975679 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm) [rhel-8.4.0.z] -Patch502: kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch503: kvm-net-introduce-qemu_receive_packet.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch504: kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch505: kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch506: kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch507: kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch508: kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch509: kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch510: kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch -# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z] -Patch511: kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch +# For bz#1930092 - CVE-2021-20257 virt:rhel/qemu-kvm: QEMU: net: e1000: infinite loop while processing transmit descriptors [rhel-8.5.0] +Patch493: kvm-e1000-fail-early-for-evil-descriptor.patch +# For bz#1859175 - CVE-2020-15859 virt:rhel/qemu-kvm: QEMU: net: e1000e: use-after-free while sending packets [rhel-8] +Patch494: kvm-net-forbid-the-reentrant-RX.patch +# For bz#1855250 - qemu-img convert uses possibly slow pre-zeroing on block storage +Patch495: kvm-qemu-img-convert-Don-t-pre-zero-images.patch +# For bz#1932823 - after upgrade from 4.3 to 4.4 audio stops working in guests after couple of seconds +Patch496: kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch +# For bz#1925430 - CVE-2021-20221 virt:rhel/qemu-kvm: qemu: out-of-bound heap buffer access via an interrupt ID field [rhel-8.5.0] +Patch497: kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch +# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0] +Patch498: kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch +# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0] +Patch499: kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch +# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0] +Patch500: kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch +# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0] +Patch501: kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch +# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0] +Patch502: kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch +# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0] +Patch503: kvm-softmmu-memory-Log-invalid-memory-accesses.patch +# For bz#1940450 - RHEL8.5 - Mediated Device already in use by same domain we are booting (vfio-ccw/Multipath Testing) (kvm) - qemu-kvm part (also has kernel and libvirt parts) +Patch504: kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch +# For bz#1940450 - RHEL8.5 - Mediated Device already in use by same domain we are booting (vfio-ccw/Multipath Testing) (kvm) - qemu-kvm part (also has kernel and libvirt parts) +Patch505: kvm-vfio-ccw-Connect-the-device-request-notifier.patch +# For bz#1942880 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm) +Patch506: kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch +# For bz#1942880 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm) +Patch507: kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch +# For bz#1942880 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm) +Patch508: kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch +# For bz#1877163 - [FJ 8.3 Bug] The progress bar of the "virt-clone --nonsparse" command shows the progress rate exceeding 100%. +Patch509: kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch +# For bz#1944861 - Qemu-img convert fails when source image is on gpfs +Patch510: kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch +# For bz#1969768 - [ppc64le] Hotplug vcpu device hit call trace:[qemu output] KVM: unknown exit, hardware reason 7fff9ce87ed8 +Patch511: kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch +# For bz#1969768 - [ppc64le] Hotplug vcpu device hit call trace:[qemu output] KVM: unknown exit, hardware reason 7fff9ce87ed8 +Patch512: kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch +# For bz#1967914 - [virtio-fs] virtiofsd quit when coping file to a folder in virtio-fs mounted volume(windows guest) +Patch513: kvm-virtiofsd-Whitelist-fchmod.patch +# For bz#1957866 - RHEL8.4 - EEH capability disabled on KVM guest and recovery of PCI passthru device fails(CX5 / mlx5_core) (qemu-kvm) +Patch514: kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch +# For bz#1970912 - Deployment fails with "Invalid or missing agent token received" +Patch515: kvm-Compress-lines-for-immediate-return.patch +# For bz#1970912 - Deployment fails with "Invalid or missing agent token received" +Patch516: kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch517: kvm-net-introduce-qemu_receive_packet.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch518: kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch519: kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch520: kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch521: kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch522: kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch523: kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch524: kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch +# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow +Patch525: kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch +# For bz#1967716 - RFE: rebuild guest agent to include public ssh injection api support +Patch526: kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch +# For bz#1967716 - RFE: rebuild guest agent to include public ssh injection api support +Patch527: kvm-qga-add-ssh-add-remove-authorized-keys.patch +# For bz#1967716 - RFE: rebuild guest agent to include public ssh injection api support +Patch528: kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch +# For bz#1967716 - RFE: rebuild guest agent to include public ssh injection api support +Patch529: kvm-qga-add-ssh-get-authorized-keys.patch +# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8] +# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8] +# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8] +# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8] +Patch530: kvm-Add-mtod_check.patch +# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8] +# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8] +# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8] +# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8] +Patch531: kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch +# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8] +Patch532: kvm-bootp-check-bootp_input-buffer-size.patch +# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8] +Patch533: kvm-upd6-check-udp6_input-buffer-size.patch +# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8] +Patch534: kvm-tftp-check-tftp_input-buffer-size.patch +# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8] +# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8] +# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8] +# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8] +Patch535: kvm-tftp-introduce-a-header-structure.patch +# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8] +Patch536: kvm-udp-check-upd_input-buffer-size.patch +# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8] +# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8] +# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8] +# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8] +Patch537: kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch +# For bz#1982134 - QEMU core dump while booting guest with a non-exist fd on tap +Patch538: kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch +# For bz#1982134 - QEMU core dump while booting guest with a non-exist fd on tap +Patch539: kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch +# For bz#1969848 - qemu-img convert hangs on aarch64 +Patch540: kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch +# For bz#1969848 - qemu-img convert hangs on aarch64 +Patch541: kvm-async-use-explicit-memory-barriers.patch +# For bz#1967496 - [virtio-fs] nfs/xfstest generic/089 generic/478 generic/632 failed +Patch542: kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch +# For bz#1967496 - [virtio-fs] nfs/xfstest generic/089 generic/478 generic/632 failed +Patch543: kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch +# For bz#1994041 - qemu-kvm scsi: change default passthrough timeout to non-infinite +Patch544: kvm-scsi-make-io_timeout-configurable.patch BuildRequires: wget BuildRequires: rpm-build @@ -2118,7 +2196,52 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %changelog -* Wed Jul 21 2021 Danilo Cesar Lemes de Paula - 4.2.0-48.el8_4.3 +* Fri Oct 01 2021 Jon Maloy - 4.2.0-59 +- kvm-scsi-make-io_timeout-configurable.patch [bz#1994041] +- Resolves: bz#1994041 + (qemu-kvm scsi: change default passthrough timeout to non-infinite) + +* Wed Aug 18 2021 Danilo Cesar Lemes de Paula - 4.2.0-58.el8 +- kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch [bz#1967496] +- kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch [bz#1967496] +- Resolves: bz#1967496 + ([virtio-fs] nfs/xfstest generic/089 generic/478 generic/632 failed) + +* Wed Aug 04 2021 Miroslav Rezanina - 4.2.0-57 +- kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch [bz#1969848] +- kvm-async-use-explicit-memory-barriers.patch [bz#1969848] +- Resolves: bz#1969848 + (qemu-img convert hangs on aarch64) + +* Thu Jul 29 2021 Miroslav Rezanina - 4.2.0-56 +- kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch [bz#1967716] +- kvm-qga-add-ssh-add-remove-authorized-keys.patch [bz#1967716] +- kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch [bz#1967716] +- kvm-qga-add-ssh-get-authorized-keys.patch [bz#1967716] +- kvm-Add-mtod_check.patch [bz#1970819 bz#1970835 bz#1970843 bz#1970853] +- kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch [bz#1970819 bz#1970835 bz#1970843 bz#1970853] +- kvm-bootp-check-bootp_input-buffer-size.patch [bz#1970819] +- kvm-upd6-check-udp6_input-buffer-size.patch [bz#1970835] +- kvm-tftp-check-tftp_input-buffer-size.patch [bz#1970843] +- kvm-tftp-introduce-a-header-structure.patch [bz#1970819 bz#1970835 bz#1970843 bz#1970853] +- kvm-udp-check-upd_input-buffer-size.patch [bz#1970853] +- kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch [bz#1970819 bz#1970835 bz#1970843 bz#1970853] +- kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch [bz#1982134] +- kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch [bz#1982134] +- Resolves: bz#1967716 + (RFE: rebuild guest agent to include public ssh injection api support) +- Resolves: bz#1970819 + (CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8]) +- Resolves: bz#1970835 + (CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8]) +- Resolves: bz#1970843 + (CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8]) +- Resolves: bz#1970853 + (CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8]) +- Resolves: bz#1982134 + (QEMU core dump while booting guest with a non-exist fd on tap) + +* Fri Jul 23 2021 Danilo Cesar Lemes de Paula - 4.2.0-55.el8 - kvm-net-introduce-qemu_receive_packet.patch [bz#1932917] - kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch [bz#1932917] - kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch [bz#1932917] @@ -2129,30 +2252,77 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ - kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch [bz#1932917] - kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch [bz#1932917] - Resolves: bz#1932917 - (CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow [rhel-8.4.z]) - -* Tue Jul 06 2021 Danilo Cesar Lemes de Paula - 4.2.0-48.el8_4.2 -- kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch [bz#1975679] -- kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch [bz#1975679] -- kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch [bz#1975679] -- Resolves: bz#1975679 - (RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm) [rhel-8.4.0.z]) - -* Thu Jun 03 2021 Danilo Cesar Lemes de Paula - 4.2.0-48.el8_4 -- kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch [bz#1939494] -- kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch [bz#1944621] -- kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch [bz#1944621] -- kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch [bz#1944621] -- kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch [bz#1944621] -- kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch [bz#1944621] -- kvm-softmmu-memory-Log-invalid-memory-accesses.patch [bz#1944621] -- kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch [bz#1952986] -- Resolves: bz#1939494 - (CVE-2020-27617 virt:rhel/qemu-kvm: QEMU: net: an assert failure via eth_get_gso_type [rhel-8.4.0.z]) -- Resolves: bz#1944621 - (CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.4.0.z]) -- Resolves: bz#1952986 - (CVE-2021-20221 virt:rhel/qemu-kvm: qemu: out-of-bound heap buffer access via an interrupt ID field [rhel-8.4.0.z]) + (CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow) + +* Thu Jul 22 2021 Danilo Cesar Lemes de Paula - 4.2.0-54.el8 +- kvm-redhat-Fix-unversioned-Obsoletes-warning.patch [bz#1967329] +- Resolves: bz#1967329 + (Make qemu-kvm use versioned obsoletes for qemu-kvm-ma and qemu-kvm-rhev) + +* Fri Jul 02 2021 Danilo Cesar Lemes de Paula - 4.2.0-53.el8 +- kvm-virtiofsd-Whitelist-fchmod.patch [bz#1967914] +- kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch [bz#1957866] +- kvm-Compress-lines-for-immediate-return.patch [bz#1970912] +- kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch [bz#1970912] +- Resolves: bz#1967914 + ([virtio-fs] virtiofsd quit when coping file to a folder in virtio-fs mounted volume(windows guest)) +- Resolves: bz#1957866 + (RHEL8.4 - EEH capability disabled on KVM guest and recovery of PCI passthru device fails(CX5 / mlx5_core) (qemu-kvm)) +- Resolves: bz#1970912 + (Deployment fails with "Invalid or missing agent token received") + +* Fri Jun 11 2021 Danilo Cesar Lemes de Paula - 4.2.0-52.el8 +- kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch [bz#1877163] +- kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch [bz#1944861] +- kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch [bz#1969768] +- kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch [bz#1969768] +- Resolves: bz#1877163 + ([FJ 8.3 Bug] The progress bar of the "virt-clone --nonsparse" command shows the progress rate exceeding 100%.) +- Resolves: bz#1944861 + (Qemu-img convert fails when source image is on gpfs) +- Resolves: bz#1969768 + ([ppc64le] Hotplug vcpu device hit call trace:[qemu output] KVM: unknown exit, hardware reason 7fff9ce87ed8) + +* Tue May 25 2021 Danilo Cesar Lemes de Paula - 4.2.0-51.el8 +- kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch [bz#1940450] +- kvm-vfio-ccw-Connect-the-device-request-notifier.patch [bz#1940450] +- kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch [bz#1942880] +- kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch [bz#1942880] +- kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch [bz#1942880] +- Resolves: bz#1940450 + (RHEL8.5 - Mediated Device already in use by same domain we are booting (vfio-ccw/Multipath Testing) (kvm) - qemu-kvm part (also has kernel and libvirt parts)) +- Resolves: bz#1942880 + (RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm)) + +* Wed May 05 2021 Danilo Cesar Lemes de Paula - 4.2.0-50.el8 +- kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch [bz#1925430] +- kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch [bz#1842478] +- kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch [bz#1842478] +- kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch [bz#1842478] +- kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch [bz#1842478] +- kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch [bz#1842478] +- kvm-softmmu-memory-Log-invalid-memory-accesses.patch [bz#1842478] +- Resolves: bz#1925430 + (CVE-2021-20221 virt:rhel/qemu-kvm: qemu: out-of-bound heap buffer access via an interrupt ID field [rhel-8.5.0]) +- Resolves: bz#1842478 + (CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0]) + +* Wed Apr 28 2021 Danilo Cesar Lemes de Paula - 4.2.0-49.el8 +- kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch [bz#1892350] +- kvm-e1000-fail-early-for-evil-descriptor.patch [bz#1930092] +- kvm-net-forbid-the-reentrant-RX.patch [bz#1859175] +- kvm-qemu-img-convert-Don-t-pre-zero-images.patch [bz#1855250] +- kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch [bz#1932823] +- Resolves: bz#1892350 + (CVE-2020-27617 virt:rhel/qemu-kvm: QEMU: net: an assert failure via eth_get_gso_type [rhel-8.5.0]) +- Resolves: bz#1930092 + (CVE-2021-20257 virt:rhel/qemu-kvm: QEMU: net: e1000: infinite loop while processing transmit descriptors [rhel-8.5.0]) +- Resolves: bz#1859175 + (CVE-2020-15859 virt:rhel/qemu-kvm: QEMU: net: e1000e: use-after-free while sending packets [rhel-8]) +- Resolves: bz#1855250 + (qemu-img convert uses possibly slow pre-zeroing on block storage) +- Resolves: bz#1932823 + (after upgrade from 4.3 to 4.4 audio stops working in guests after couple of seconds) * Tue Mar 16 2021 Danilo Cesar Lemes de Paula - 4.2.0-48.el8 - kvm-ide-atapi-check-logical-block-address-and-read-size-.patch [bz#1917451]