]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Oct 2023 17:46:41 +0000 (19:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Oct 2023 17:46:41 +0000 (19:46 +0200)
added patches:
fs-ntfs3-fix-deadlock-in-mark_as_free_ex.patch
fs-ntfs3-fix-panic-about-slab-out-of-bounds-caused-by-ntfs_list_ea.patch
fs-ntfs3-fix-possible-null-pointer-dereference-in-hdr_find_e.patch
netfilter-nft_payload-fix-wrong-mac-header-matching.patch
tcp-check-mptcp-level-constraints-for-backlog-coalescing.patch
x86-sev-check-for-user-space-ioio-pointing-to-kernel-space.patch
x86-sev-check-iobm-for-ioio-exceptions-from-user-space.patch
x86-sev-disable-mmio-emulation-from-user-mode.patch

queue-5.15/fs-ntfs3-fix-deadlock-in-mark_as_free_ex.patch [new file with mode: 0644]
queue-5.15/fs-ntfs3-fix-panic-about-slab-out-of-bounds-caused-by-ntfs_list_ea.patch [new file with mode: 0644]
queue-5.15/fs-ntfs3-fix-possible-null-pointer-dereference-in-hdr_find_e.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_payload-fix-wrong-mac-header-matching.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tcp-check-mptcp-level-constraints-for-backlog-coalescing.patch [new file with mode: 0644]
queue-5.15/x86-sev-check-for-user-space-ioio-pointing-to-kernel-space.patch [new file with mode: 0644]
queue-5.15/x86-sev-check-iobm-for-ioio-exceptions-from-user-space.patch [new file with mode: 0644]
queue-5.15/x86-sev-disable-mmio-emulation-from-user-mode.patch [new file with mode: 0644]

diff --git a/queue-5.15/fs-ntfs3-fix-deadlock-in-mark_as_free_ex.patch b/queue-5.15/fs-ntfs3-fix-deadlock-in-mark_as_free_ex.patch
new file mode 100644 (file)
index 0000000..1f67c91
--- /dev/null
@@ -0,0 +1,41 @@
+From bfbe5b31caa74ab97f1784fe9ade5f45e0d3de91 Mon Sep 17 00:00:00 2001
+From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Date: Fri, 30 Jun 2023 16:22:53 +0400
+Subject: fs/ntfs3: fix deadlock in mark_as_free_ex
+
+From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+
+commit bfbe5b31caa74ab97f1784fe9ade5f45e0d3de91 upstream.
+
+Reported-by: syzbot+e94d98936a0ed08bde43@syzkaller.appspotmail.com
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ntfs3/fsntfs.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/ntfs3/fsntfs.c
++++ b/fs/ntfs3/fsntfs.c
+@@ -2458,10 +2458,12 @@ void mark_as_free_ex(struct ntfs_sb_info
+ {
+       CLST end, i;
+       struct wnd_bitmap *wnd = &sbi->used.bitmap;
++      bool dirty = false;
+       down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
+       if (!wnd_is_used(wnd, lcn, len)) {
+-              ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
++              /* mark volume as dirty out of wnd->rw_lock */
++              dirty = true;
+               end = lcn + len;
+               len = 0;
+@@ -2493,6 +2495,8 @@ void mark_as_free_ex(struct ntfs_sb_info
+ out:
+       up_write(&wnd->rw_lock);
++      if (dirty)
++              ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
+ }
+ /*
diff --git a/queue-5.15/fs-ntfs3-fix-panic-about-slab-out-of-bounds-caused-by-ntfs_list_ea.patch b/queue-5.15/fs-ntfs3-fix-panic-about-slab-out-of-bounds-caused-by-ntfs_list_ea.patch
new file mode 100644 (file)
index 0000000..94b11ba
--- /dev/null
@@ -0,0 +1,64 @@
+From 8e7e27b2ee1e19c4040d4987e345f678a74c0aed Mon Sep 17 00:00:00 2001
+From: Zeng Heng <zengheng4@huawei.com>
+Date: Thu, 20 Apr 2023 15:46:22 +0800
+Subject: fs/ntfs3: fix panic about slab-out-of-bounds caused by ntfs_list_ea()
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+commit 8e7e27b2ee1e19c4040d4987e345f678a74c0aed upstream.
+
+Here is a BUG report about linux-6.1 from syzbot, but it still remains
+within upstream:
+
+BUG: KASAN: slab-out-of-bounds in ntfs_list_ea fs/ntfs3/xattr.c:191 [inline]
+BUG: KASAN: slab-out-of-bounds in ntfs_listxattr+0x401/0x570 fs/ntfs3/xattr.c:710
+Read of size 1 at addr ffff888021acaf3d by task syz-executor128/3632
+
+Call Trace:
+ kasan_report+0x139/0x170 mm/kasan/report.c:495
+ ntfs_list_ea fs/ntfs3/xattr.c:191 [inline]
+ ntfs_listxattr+0x401/0x570 fs/ntfs3/xattr.c:710
+ vfs_listxattr fs/xattr.c:457 [inline]
+ listxattr+0x293/0x2d0 fs/xattr.c:804
+ path_listxattr fs/xattr.c:828 [inline]
+ __do_sys_llistxattr fs/xattr.c:846 [inline]
+
+Before derefering field members of `ea` in unpacked_ea_size(), we need to
+check whether the EA_FULL struct is located in access validate range.
+
+Similarly, when derefering `ea->name` field member, we need to check
+whethe the ea->name is located in access validate range, too.
+
+Fixes: be71b5cba2e6 ("fs/ntfs3: Add attrib operations")
+Reported-by: syzbot+9fcea5ef6dc4dc72d334@syzkaller.appspotmail.com
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+[almaz.alexandrovich@paragon-software.com: took the ret variable out of the loop block]
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ntfs3/xattr.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/fs/ntfs3/xattr.c
++++ b/fs/ntfs3/xattr.c
+@@ -209,7 +209,8 @@ static ssize_t ntfs_list_ea(struct ntfs_
+       size = le32_to_cpu(info->size);
+       /* Enumerate all xattrs. */
+-      for (ret = 0, off = 0; off < size; off += ea_size) {
++      ret = 0;
++      for (off = 0; off + sizeof(struct EA_FULL) < size; off += ea_size) {
+               ea = Add2Ptr(ea_all, off);
+               ea_size = unpacked_ea_size(ea);
+@@ -217,6 +218,10 @@ static ssize_t ntfs_list_ea(struct ntfs_
+                       break;
+               if (buffer) {
++                      /* Check if we can use field ea->name */
++                      if (off + ea_size > size)
++                              break;
++
+                       if (ret + ea->name_len + 1 > bytes_per_buffer) {
+                               err = -ERANGE;
+                               goto out;
diff --git a/queue-5.15/fs-ntfs3-fix-possible-null-pointer-dereference-in-hdr_find_e.patch b/queue-5.15/fs-ntfs3-fix-possible-null-pointer-dereference-in-hdr_find_e.patch
new file mode 100644 (file)
index 0000000..a2be8c9
--- /dev/null
@@ -0,0 +1,53 @@
+From 1f9b94af923c88539426ed811ae7e9543834a5c5 Mon Sep 17 00:00:00 2001
+From: Ziqi Zhao <astrajoan@yahoo.com>
+Date: Wed, 9 Aug 2023 12:11:18 -0700
+Subject: fs/ntfs3: Fix possible null-pointer dereference in hdr_find_e()
+
+From: Ziqi Zhao <astrajoan@yahoo.com>
+
+commit 1f9b94af923c88539426ed811ae7e9543834a5c5 upstream.
+
+Upon investigation of the C reproducer provided by Syzbot, it seemed
+the reproducer was trying to mount a corrupted NTFS filesystem, then
+issue a rename syscall to some nodes in the filesystem. This can be
+shown by modifying the reproducer to only include the mount syscall,
+and investigating the filesystem by e.g. `ls` and `rm` commands. As a
+result, during the problematic call to `hdr_fine_e`, the `inode` being
+supplied did not go through `indx_init`, hence the `cmp` function
+pointer was never set.
+
+The fix is simply to check whether `cmp` is not set, and return NULL
+if that's the case, in order to be consistent with other error
+scenarios of the `hdr_find_e` method. The rationale behind this patch
+is that:
+
+- We should prevent crashing the kernel even if the mounted filesystem
+  is corrupted. Any syscalls made on the filesystem could return
+  invalid, but the kernel should be able to sustain these calls.
+
+- Only very specific corruption would lead to this bug, so it would be
+  a pretty rare case in actual usage anyways. Therefore, introducing a
+  check to specifically protect against this bug seems appropriate.
+  Because of its rarity, an `unlikely` clause is used to wrap around
+  this nullity check.
+
+Reported-by: syzbot+60cf892fc31d1f4358fc@syzkaller.appspotmail.com
+Signed-off-by: Ziqi Zhao <astrajoan@yahoo.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ntfs3/index.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -729,6 +729,9 @@ static struct NTFS_DE *hdr_find_e(const
+       u32 total = le32_to_cpu(hdr->total);
+       u16 offs[128];
++      if (unlikely(!cmp))
++              return NULL;
++
+ fill_table:
+       if (end > total)
+               return NULL;
diff --git a/queue-5.15/netfilter-nft_payload-fix-wrong-mac-header-matching.patch b/queue-5.15/netfilter-nft_payload-fix-wrong-mac-header-matching.patch
new file mode 100644 (file)
index 0000000..360d6e5
--- /dev/null
@@ -0,0 +1,37 @@
+From d351c1ea2de3e36e608fc355d8ae7d0cc80e6cd6 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Sun, 8 Oct 2023 19:36:53 +0200
+Subject: netfilter: nft_payload: fix wrong mac header matching
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Florian Westphal <fw@strlen.de>
+
+commit d351c1ea2de3e36e608fc355d8ae7d0cc80e6cd6 upstream.
+
+mcast packets get looped back to the local machine.
+Such packets have a 0-length mac header, we should treat
+this like "mac header not set" and abort rule evaluation.
+
+As-is, we just copy data from the network header instead.
+
+Fixes: 96518518cc41 ("netfilter: add nftables")
+Reported-by: Blažej Krajňák <krajnak@levonet.sk>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nft_payload.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/netfilter/nft_payload.c
++++ b/net/netfilter/nft_payload.c
+@@ -133,7 +133,7 @@ void nft_payload_eval(const struct nft_e
+       switch (priv->base) {
+       case NFT_PAYLOAD_LL_HEADER:
+-              if (!skb_mac_header_was_set(skb))
++              if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) == 0)
+                       goto err;
+               if (skb_vlan_tag_present(skb)) {
index 0c564b212e2863754eee8aa58a4296952ce59149..bf5569cf324bf243b4f1c256d501558165a7e3e1 100644 (file)
@@ -15,3 +15,11 @@ ice-reset-first-in-crash-dump-kernels.patch
 nfc-nci-fix-possible-null-pointer-dereference-in-send_acknowledge.patch
 regmap-fix-null-deref-on-lookup.patch
 kvm-x86-mask-lvtpc-when-handling-a-pmi.patch
+x86-sev-disable-mmio-emulation-from-user-mode.patch
+x86-sev-check-iobm-for-ioio-exceptions-from-user-space.patch
+x86-sev-check-for-user-space-ioio-pointing-to-kernel-space.patch
+tcp-check-mptcp-level-constraints-for-backlog-coalescing.patch
+fs-ntfs3-fix-possible-null-pointer-dereference-in-hdr_find_e.patch
+fs-ntfs3-fix-panic-about-slab-out-of-bounds-caused-by-ntfs_list_ea.patch
+fs-ntfs3-fix-deadlock-in-mark_as_free_ex.patch
+netfilter-nft_payload-fix-wrong-mac-header-matching.patch
diff --git a/queue-5.15/tcp-check-mptcp-level-constraints-for-backlog-coalescing.patch b/queue-5.15/tcp-check-mptcp-level-constraints-for-backlog-coalescing.patch
new file mode 100644 (file)
index 0000000..f40bb3a
--- /dev/null
@@ -0,0 +1,47 @@
+From 6db8a37dfc541e059851652cfd4f0bb13b8ff6af Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Wed, 18 Oct 2023 11:23:53 -0700
+Subject: tcp: check mptcp-level constraints for backlog coalescing
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit 6db8a37dfc541e059851652cfd4f0bb13b8ff6af upstream.
+
+The MPTCP protocol can acquire the subflow-level socket lock and
+cause the tcp backlog usage. When inserting new skbs into the
+backlog, the stack will try to coalesce them.
+
+Currently, we have no check in place to ensure that such coalescing
+will respect the MPTCP-level DSS, and that may cause data stream
+corruption, as reported by Christoph.
+
+Address the issue by adding the relevant admission check for coalescing
+in tcp_add_backlog().
+
+Note the issue is not easy to reproduce, as the MPTCP protocol tries
+hard to avoid acquiring the subflow-level socket lock.
+
+Fixes: 648ef4b88673 ("mptcp: Implement MPTCP receive path")
+Cc: stable@vger.kernel.org
+Reported-by: Christoph Paasch <cpaasch@apple.com>
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/420
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20231018-send-net-20231018-v1-2-17ecb002e41d@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_ipv4.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -1863,6 +1863,7 @@ bool tcp_add_backlog(struct sock *sk, st
+ #ifdef CONFIG_TLS_DEVICE
+           tail->decrypted != skb->decrypted ||
+ #endif
++          !mptcp_skb_can_collapse(tail, skb) ||
+           thtail->doff != th->doff ||
+           memcmp(thtail + 1, th + 1, hdrlen - sizeof(*th)))
+               goto no_coalesce;
diff --git a/queue-5.15/x86-sev-check-for-user-space-ioio-pointing-to-kernel-space.patch b/queue-5.15/x86-sev-check-for-user-space-ioio-pointing-to-kernel-space.patch
new file mode 100644 (file)
index 0000000..4246b44
--- /dev/null
@@ -0,0 +1,95 @@
+From 10c7d584179b7c6248e5d8c04f9f143c3c257a67 Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Mon, 16 Oct 2023 14:42:50 +0200
+Subject: x86/sev: Check for user-space IOIO pointing to kernel space
+
+From: Joerg Roedel <jroedel@suse.de>
+
+Upstream commit: 63e44bc52047f182601e7817da969a105aa1f721
+
+Check the memory operand of INS/OUTS before emulating the instruction.
+The #VC exception can get raised from user-space, but the memory operand
+can be manipulated to access kernel memory before the emulation actually
+begins and after the exception handler has run.
+
+  [ bp: Massage commit message. ]
+
+Fixes: 597cfe48212a ("x86/boot/compressed/64: Setup a GHCB-based VC Exception handler")
+Reported-by: Tom Dohrmann <erbse.13@gmx.de>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/boot/compressed/sev.c |    5 +++++
+ arch/x86/kernel/sev-shared.c   |   31 +++++++++++++++++++++++++++++--
+ 2 files changed, 34 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/boot/compressed/sev.c
++++ b/arch/x86/boot/compressed/sev.c
+@@ -110,6 +110,11 @@ static enum es_result vc_ioio_check(stru
+       return ES_OK;
+ }
++static bool fault_in_kernel_space(unsigned long address)
++{
++      return false;
++}
++
+ #undef __init
+ #undef __pa
+ #define __init
+--- a/arch/x86/kernel/sev-shared.c
++++ b/arch/x86/kernel/sev-shared.c
+@@ -213,6 +213,23 @@ fail:
+       sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST);
+ }
++static enum es_result vc_insn_string_check(struct es_em_ctxt *ctxt,
++                                         unsigned long address,
++                                         bool write)
++{
++      if (user_mode(ctxt->regs) && fault_in_kernel_space(address)) {
++              ctxt->fi.vector     = X86_TRAP_PF;
++              ctxt->fi.error_code = X86_PF_USER;
++              ctxt->fi.cr2        = address;
++              if (write)
++                      ctxt->fi.error_code |= X86_PF_WRITE;
++
++              return ES_EXCEPTION;
++      }
++
++      return ES_OK;
++}
++
+ static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt,
+                                         void *src, char *buf,
+                                         unsigned int data_size,
+@@ -220,7 +237,12 @@ static enum es_result vc_insn_string_rea
+                                         bool backwards)
+ {
+       int i, b = backwards ? -1 : 1;
+-      enum es_result ret = ES_OK;
++      unsigned long address = (unsigned long)src;
++      enum es_result ret;
++
++      ret = vc_insn_string_check(ctxt, address, false);
++      if (ret != ES_OK)
++              return ret;
+       for (i = 0; i < count; i++) {
+               void *s = src + (i * data_size * b);
+@@ -241,7 +263,12 @@ static enum es_result vc_insn_string_wri
+                                          bool backwards)
+ {
+       int i, s = backwards ? -1 : 1;
+-      enum es_result ret = ES_OK;
++      unsigned long address = (unsigned long)dst;
++      enum es_result ret;
++
++      ret = vc_insn_string_check(ctxt, address, true);
++      if (ret != ES_OK)
++              return ret;
+       for (i = 0; i < count; i++) {
+               void *d = dst + (i * data_size * s);
diff --git a/queue-5.15/x86-sev-check-iobm-for-ioio-exceptions-from-user-space.patch b/queue-5.15/x86-sev-check-iobm-for-ioio-exceptions-from-user-space.patch
new file mode 100644 (file)
index 0000000..f8c3f42
--- /dev/null
@@ -0,0 +1,172 @@
+From 01872a2e086f8431ccba86b3f71c8ba1f017ba08 Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Wed, 21 Jun 2023 17:42:42 +0200
+Subject: x86/sev: Check IOBM for IOIO exceptions from user-space
+
+From: Joerg Roedel <jroedel@suse.de>
+
+Upstream commit: b9cb9c45583b911e0db71d09caa6b56469eb2bdf
+
+Check the IO permission bitmap (if present) before emulating IOIO #VC
+exceptions for user-space. These permissions are checked by hardware
+already before the #VC is raised, but due to the VC-handler decoding
+race it needs to be checked again in software.
+
+Fixes: 25189d08e516 ("x86/sev-es: Add support for handling IOIO exceptions")
+Reported-by: Tom Dohrmann <erbse.13@gmx.de>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Tested-by: Tom Dohrmann <erbse.13@gmx.de>
+Cc: <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/boot/compressed/sev.c |    5 +++++
+ arch/x86/kernel/sev-shared.c   |   22 +++++++++++++++-------
+ arch/x86/kernel/sev.c          |   27 +++++++++++++++++++++++++++
+ 3 files changed, 47 insertions(+), 7 deletions(-)
+
+--- a/arch/x86/boot/compressed/sev.c
++++ b/arch/x86/boot/compressed/sev.c
+@@ -105,6 +105,11 @@ static enum es_result vc_read_mem(struct
+       return ES_OK;
+ }
++static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size)
++{
++      return ES_OK;
++}
++
+ #undef __init
+ #undef __pa
+ #define __init
+--- a/arch/x86/kernel/sev-shared.c
++++ b/arch/x86/kernel/sev-shared.c
+@@ -277,6 +277,9 @@ static enum es_result vc_insn_string_wri
+ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
+ {
+       struct insn *insn = &ctxt->insn;
++      size_t size;
++      u64 port;
++
+       *exitinfo = 0;
+       switch (insn->opcode.bytes[0]) {
+@@ -285,7 +288,7 @@ static enum es_result vc_ioio_exitinfo(s
+       case 0x6d:
+               *exitinfo |= IOIO_TYPE_INS;
+               *exitinfo |= IOIO_SEG_ES;
+-              *exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
++              port       = ctxt->regs->dx & 0xffff;
+               break;
+       /* OUTS opcodes */
+@@ -293,41 +296,43 @@ static enum es_result vc_ioio_exitinfo(s
+       case 0x6f:
+               *exitinfo |= IOIO_TYPE_OUTS;
+               *exitinfo |= IOIO_SEG_DS;
+-              *exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
++              port       = ctxt->regs->dx & 0xffff;
+               break;
+       /* IN immediate opcodes */
+       case 0xe4:
+       case 0xe5:
+               *exitinfo |= IOIO_TYPE_IN;
+-              *exitinfo |= (u8)insn->immediate.value << 16;
++              port       = (u8)insn->immediate.value & 0xffff;
+               break;
+       /* OUT immediate opcodes */
+       case 0xe6:
+       case 0xe7:
+               *exitinfo |= IOIO_TYPE_OUT;
+-              *exitinfo |= (u8)insn->immediate.value << 16;
++              port       = (u8)insn->immediate.value & 0xffff;
+               break;
+       /* IN register opcodes */
+       case 0xec:
+       case 0xed:
+               *exitinfo |= IOIO_TYPE_IN;
+-              *exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
++              port       = ctxt->regs->dx & 0xffff;
+               break;
+       /* OUT register opcodes */
+       case 0xee:
+       case 0xef:
+               *exitinfo |= IOIO_TYPE_OUT;
+-              *exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
++              port       = ctxt->regs->dx & 0xffff;
+               break;
+       default:
+               return ES_DECODE_FAILED;
+       }
++      *exitinfo |= port << 16;
++
+       switch (insn->opcode.bytes[0]) {
+       case 0x6c:
+       case 0x6e:
+@@ -337,12 +342,15 @@ static enum es_result vc_ioio_exitinfo(s
+       case 0xee:
+               /* Single byte opcodes */
+               *exitinfo |= IOIO_DATA_8;
++              size       = 1;
+               break;
+       default:
+               /* Length determined by instruction parsing */
+               *exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16
+                                                    : IOIO_DATA_32;
++              size       = (insn->opnd_bytes == 2) ? 2 : 4;
+       }
++
+       switch (insn->addr_bytes) {
+       case 2:
+               *exitinfo |= IOIO_ADDR_16;
+@@ -358,7 +366,7 @@ static enum es_result vc_ioio_exitinfo(s
+       if (insn_has_rep_prefix(insn))
+               *exitinfo |= IOIO_REP;
+-      return ES_OK;
++      return vc_ioio_check(ctxt, (u16)port, size);
+ }
+ static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
+--- a/arch/x86/kernel/sev.c
++++ b/arch/x86/kernel/sev.c
+@@ -482,6 +482,33 @@ static enum es_result vc_slow_virt_to_ph
+       return ES_OK;
+ }
++static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size)
++{
++      BUG_ON(size > 4);
++
++      if (user_mode(ctxt->regs)) {
++              struct thread_struct *t = &current->thread;
++              struct io_bitmap *iobm = t->io_bitmap;
++              size_t idx;
++
++              if (!iobm)
++                      goto fault;
++
++              for (idx = port; idx < port + size; ++idx) {
++                      if (test_bit(idx, iobm->bitmap))
++                              goto fault;
++              }
++      }
++
++      return ES_OK;
++
++fault:
++      ctxt->fi.vector = X86_TRAP_GP;
++      ctxt->fi.error_code = 0;
++
++      return ES_EXCEPTION;
++}
++
+ /* Include code shared with pre-decompression boot stage */
+ #include "sev-shared.c"
diff --git a/queue-5.15/x86-sev-disable-mmio-emulation-from-user-mode.patch b/queue-5.15/x86-sev-disable-mmio-emulation-from-user-mode.patch
new file mode 100644 (file)
index 0000000..b92db32
--- /dev/null
@@ -0,0 +1,42 @@
+From 479772d1158852575c27697588815b6c34abaed9 Mon Sep 17 00:00:00 2001
+From: "Borislav Petkov (AMD)" <bp@alien8.de>
+Date: Thu, 5 Oct 2023 11:06:36 +0200
+Subject: x86/sev: Disable MMIO emulation from user mode
+
+From: "Borislav Petkov (AMD)" <bp@alien8.de>
+
+Upstream commit: a37cd2a59d0cb270b1bba568fd3a3b8668b9d3ba
+
+A virt scenario can be constructed where MMIO memory can be user memory.
+When that happens, a race condition opens between when the hardware
+raises the #VC and when the #VC handler gets to emulate the instruction.
+
+If the MOVS is replaced with a MOVS accessing kernel memory in that
+small race window, then write to kernel memory happens as the access
+checks are not done at emulation time.
+
+Disable MMIO emulation in user mode temporarily until a sensible use
+case appears and justifies properly handling the race window.
+
+Fixes: 0118b604c2c9 ("x86/sev-es: Handle MMIO String Instructions")
+Reported-by: Tom Dohrmann <erbse.13@gmx.de>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Tested-by: Tom Dohrmann <erbse.13@gmx.de>
+Cc: <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/sev.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/x86/kernel/sev.c
++++ b/arch/x86/kernel/sev.c
+@@ -1004,6 +1004,9 @@ static enum es_result vc_handle_mmio(str
+       enum es_result ret;
+       long *reg_data;
++      if (user_mode(ctxt->regs))
++              return ES_UNSUPPORTED;
++
+       switch (insn->opcode.bytes[0]) {
+       /* MMIO Write */
+       case 0x88: