The patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 7588dbcebcbf0193ab5b76987396d0254270b04a
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable(a)vger.kernel.org>' --in-reply-to '2023081107-secluding-shed-defa@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
7588dbcebcbf ("KVM: SEV: only access GHCB fields once")
4e15a0ddc3ff ("KVM: SEV: snapshot the GHCB before accessing it")
aa9f58415a8e ("KVM: SVM: Exit to userspace on ENOMEM/EFAULT GHCB errors")
ad5b353240c8 ("KVM: SVM: Do not terminate SEV-ES guests on GHCB validation failure")
a655276a5949 ("KVM: SEV: Fall back to vmalloc for SEV-ES scratch area if necessary")
75236f5f2299 ("KVM: SEV: Return appropriate error codes if SEV-ES scratch setup fails")
1f05833193d8 ("Merge branch 'kvm-sev-move-context' into kvm-master")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7588dbcebcbf0193ab5b76987396d0254270b04a Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini(a)redhat.com>
Date: Fri, 4 Aug 2023 12:56:36 -0400
Subject: [PATCH] KVM: SEV: only access GHCB fields once
A KVM guest using SEV-ES or SEV-SNP with multiple vCPUs can trigger
a double fetch race condition vulnerability and invoke the VMGEXIT
handler recursively.
sev_handle_vmgexit() maps the GHCB page using kvm_vcpu_map() and then
fetches the exit code using ghcb_get_sw_exit_code(). Soon after,
sev_es_validate_vmgexit() fetches the exit code again. Since the GHCB
page is shared with the guest, the guest is able to quickly swap the
values with another vCPU and hence bypass the validation. One vmexit code
that can be rejected by sev_es_validate_vmgexit() is SVM_EXIT_VMGEXIT;
if sev_handle_vmgexit() observes it in the second fetch, the call
to svm_invoke_exit_handler() will invoke sev_handle_vmgexit() again
recursively.
To avoid the race, always fetch the GHCB data from the places where
sev_es_sync_from_ghcb stores it.
Exploiting recursions on linux kernel has been proven feasible
in the past, but the impact is mitigated by stack guard pages
(CONFIG_VMAP_STACK). Still, if an attacker manages to call the handler
multiple times, they can theoretically trigger a stack overflow and
cause a denial-of-service, or potentially guest-to-host escape in kernel
configurations without stack guard pages.
Note that winning the race reliably in every iteration is very tricky
due to the very tight window of the fetches; depending on the compiler
settings, they are often consecutive because of optimization and inlining.
Tested by booting an SEV-ES RHEL9 guest.
Fixes: CVE-2023-4155
Fixes: 291bd20d5d88 ("KVM: SVM: Add initial support for a VMGEXIT VMEXIT")
Cc: stable(a)vger.kernel.org
Reported-by: Andy Nguyen <theflow(a)google.com>
Signed-off-by: Paolo Bonzini <pbonzini(a)redhat.com>
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index e898f0b2b0ba..ca4ba5fe9a01 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -2445,9 +2445,15 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
}
+static u64 kvm_ghcb_get_sw_exit_code(struct vmcb_control_area *control)
+{
+ return (((u64)control->exit_code_hi) << 32) | control->exit_code;
+}
+
static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
{
- struct kvm_vcpu *vcpu;
+ struct vmcb_control_area *control = &svm->vmcb->control;
+ struct kvm_vcpu *vcpu = &svm->vcpu;
struct ghcb *ghcb;
u64 exit_code;
u64 reason;
@@ -2458,7 +2464,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
* Retrieve the exit code now even though it may not be marked valid
* as it could help with debugging.
*/
- exit_code = ghcb_get_sw_exit_code(ghcb);
+ exit_code = kvm_ghcb_get_sw_exit_code(control);
/* Only GHCB Usage code 0 is supported */
if (ghcb->ghcb_usage) {
@@ -2473,7 +2479,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
!kvm_ghcb_sw_exit_info_2_is_valid(svm))
goto vmgexit_err;
- switch (ghcb_get_sw_exit_code(ghcb)) {
+ switch (exit_code) {
case SVM_EXIT_READ_DR7:
break;
case SVM_EXIT_WRITE_DR7:
@@ -2490,18 +2496,18 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
if (!kvm_ghcb_rax_is_valid(svm) ||
!kvm_ghcb_rcx_is_valid(svm))
goto vmgexit_err;
- if (ghcb_get_rax(ghcb) == 0xd)
+ if (vcpu->arch.regs[VCPU_REGS_RAX] == 0xd)
if (!kvm_ghcb_xcr0_is_valid(svm))
goto vmgexit_err;
break;
case SVM_EXIT_INVD:
break;
case SVM_EXIT_IOIO:
- if (ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_STR_MASK) {
+ if (control->exit_info_1 & SVM_IOIO_STR_MASK) {
if (!kvm_ghcb_sw_scratch_is_valid(svm))
goto vmgexit_err;
} else {
- if (!(ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_TYPE_MASK))
+ if (!(control->exit_info_1 & SVM_IOIO_TYPE_MASK))
if (!kvm_ghcb_rax_is_valid(svm))
goto vmgexit_err;
}
@@ -2509,7 +2515,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
case SVM_EXIT_MSR:
if (!kvm_ghcb_rcx_is_valid(svm))
goto vmgexit_err;
- if (ghcb_get_sw_exit_info_1(ghcb)) {
+ if (control->exit_info_1) {
if (!kvm_ghcb_rax_is_valid(svm) ||
!kvm_ghcb_rdx_is_valid(svm))
goto vmgexit_err;
@@ -2553,8 +2559,6 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
return 0;
vmgexit_err:
- vcpu = &svm->vcpu;
-
if (reason == GHCB_ERR_INVALID_USAGE) {
vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n",
ghcb->ghcb_usage);
@@ -2852,8 +2856,6 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
trace_kvm_vmgexit_enter(vcpu->vcpu_id, ghcb);
- exit_code = ghcb_get_sw_exit_code(ghcb);
-
sev_es_sync_from_ghcb(svm);
ret = sev_es_validate_vmgexit(svm);
if (ret)
@@ -2862,6 +2864,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
ghcb_set_sw_exit_info_1(ghcb, 0);
ghcb_set_sw_exit_info_2(ghcb, 0);
+ exit_code = kvm_ghcb_get_sw_exit_code(control);
switch (exit_code) {
case SVM_VMGEXIT_MMIO_READ:
ret = setup_vmgexit_scratch(svm, true, control->exit_info_2);
I'm announcing the release of the 5.15.126 kernel.
All users of the 5.15 kernel series must upgrade.
The updated 5.15.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-5.15.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks,
greg k-h
------------
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Alan Stern (1):
net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb
Aleksa Sarai (1):
open: make RESOLVE_CACHED correctly test for O_TMPFILE
Alexander Stein (1):
drm/imx/ipuv3: Fix front porch adjustment upon hactive aligning
Alexandra Winter (1):
s390/qeth: Don't call dev_close/dev_open (DOWN/UP)
Aneesh Kumar K.V (1):
powerpc/mm/altmap: Fix altmap boundary check
Arseniy Krasnov (1):
mtd: rawnand: meson: fix OOB available bytes for ECC
Benjamin Poirier (1):
vxlan: Fix nexthop hash size
Borislav Petkov (AMD) (1):
x86/CPU/AMD: Do not leak quotient data after a division by 0
Chengfeng Ye (1):
mISDN: hfcpci: Fix potential deadlock on &hc->lock
Christophe JAILLET (1):
mtd: rawnand: fsl_upm: Fix an off-by one test in fun_exec_op()
Chunfeng Yun (1):
PM / wakeirq: support enabling wake-up irq after runtime_suspend called
Dan Carpenter (1):
net: ll_temac: fix error checking of irq_of_parse_and_map()
Dinh Nguyen (1):
arm64: dts: stratix10: fix incorrect I2C property for SCL signal
Eric Dumazet (12):
net: annotate data-races around sk->sk_max_pacing_rate
net: add missing READ_ONCE(sk->sk_rcvlowat) annotation
net: add missing READ_ONCE(sk->sk_sndbuf) annotation
net: add missing READ_ONCE(sk->sk_rcvbuf) annotation
net: add missing data-race annotations around sk->sk_peek_off
net: add missing data-race annotation for sk_ll_usec
tcp_metrics: fix addr_same() helper
tcp_metrics: annotate data-races around tm->tcpm_stamp
tcp_metrics: annotate data-races around tm->tcpm_lock
tcp_metrics: annotate data-races around tm->tcpm_vals[]
tcp_metrics: annotate data-races around tm->tcpm_net
tcp_metrics: fix data-race in tcpm_suck_dst() vs fastopen
Georg Müller (1):
perf test uprobe_from_different_cu: Skip if there is no gcc
Greg Kroah-Hartman (1):
Linux 5.15.126
Guchun Chen (1):
drm/ttm: check null pointer before accessing when swapping
Heiko Carstens (1):
KVM: s390: fix sthyi error handling
Hou Tao (2):
bpf, cpumap: Handle skb as well when clean up ptr_ring
bpf, cpumap: Make sure kthread is running before map update returns
Hugo Villeneuve (1):
arm64: dts: imx8mn-var-som: add missing pull-up for onboard PHY reset pinmux
Ilan Peer (1):
wifi: cfg80211: Fix return value in scan logic
Ilya Dryomov (2):
libceph: fix potential hang in ceph_osdc_notify()
rbd: prevent busy loop when requesting exclusive lock
Jamal Hadi Salim (1):
net: sched: cls_u32: Fix match key mis-addressing
Jan Kara (2):
fs: Protect reconfiguration of sb read-write from racing writes
ext2: Drop fragment support
Jens Axboe (1):
io_uring: gate iowait schedule on having pending requests
Jianbo Liu (2):
net/mlx5: fs_core: Make find_closest_ft more generic
net/mlx5: fs_core: Skip the FTs in the same FS_TYPE_PRIO_CHAINS fs_prio
Jiri Olsa (1):
bpf: Disable preemption in bpf_event_output
Johan Hovold (2):
soundwire: fix enumeration completion
PM: sleep: wakeirq: fix wake irq arming
Johan Jonker (2):
mtd: rawnand: rockchip: fix oobfree offset and description
mtd: rawnand: rockchip: Align hwecc vs. raw page helper layouts
Jonas Gorski (1):
prestera: fix fallback to previous version on same major version
Konstantin Khorenko (1):
qed: Fix scheduling in a tasklet while getting stats
Krzysztof Kozlowski (1):
firmware: arm_scmi: Drop OF node reference in the transport channel setup
Kuniyuki Iwashima (1):
net/sched: taprio: Limit TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME to INT_MAX.
Laszlo Ersek (2):
net: tun_chr_open(): set sk_uid from current_fsuid()
net: tap_open(): set sk_uid from current_fsuid()
Lin Ma (3):
bpf: Add length check for SK_DIAG_BPF_STORAGE_REQ_MAP_FD parsing
rtnetlink: let rtnl_bridge_setlink checks IFLA_BRIDGE_MODE length
net: dcb: choose correct policy to parse DCB_ATTR_BCN
Linus Torvalds (1):
file: reinstate f_pos locking optimization for regular files
Mark Brown (1):
net: netsec: Ignore 'phy-mode' on SynQuacer in DT mode
Michael Jeanson (1):
selftests/rseq: check if libc rseq support is registered
Michael Kelley (1):
scsi: storvsc: Limit max_sectors for virtual Fibre Channel devices
Olivier Maignial (1):
mtd: spinand: toshiba: Fix ecc_get_status
Paul Fertser (1):
wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D (DBDC)
Peter Zijlstra (1):
perf: Fix function pointer case
Pierre-Louis Bossart (1):
soundwire: bus: pm_runtime_request_resume on peripheral attachment
Prabhakar Kushwaha (1):
qed: Fix kernel-doc warnings
Prince Kumar Maurya (1):
fs/sysv: Null check to prevent null-ptr-deref bug
Robin Murphy (4):
iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
iommu/arm-smmu-v3: Add explicit feature for nesting
iommu/arm-smmu-v3: Document nesting-related errata
Roger Quadros (1):
mtd: rawnand: omap_elm: Fix incorrect type in assignment
Ross Maynard (1):
USB: zaurus: Add ID for A-300/B-500/C-700
Sean Christopherson (1):
selftests/rseq: Play nice with binaries statically linked against glibc 2.35+
Shay Drory (1):
net/mlx5: Free irqs only on shutdown callback
Steffen Maier (1):
scsi: zfcp: Defer fc_rport blocking until after ADISC response
Sungjong Seo (1):
exfat: release s_lock before calling dir_emit()
Sungwoo Kim (1):
Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb
Suzuki K Poulose (2):
arm64: errata: Add workaround for TSB flush failures
arm64: errata: Add detection for TRBE write to out-of-range
Tetsuo Handa (1):
fs/ntfs3: Use __GFP_NOWARN allocation at ntfs_load_attr_list()
Tomas Glozar (1):
bpf: sockmap: Remove preempt_disable in sock_map_sk_acquire
Xiubo Li (1):
ceph: defer stopping mdsc delayed_work
Yang Yingliang (1):
net: ll_temac: Switch to use dev_err_probe() helper
Yuanjun Gong (3):
net/mlx5e: fix return value check in mlx5e_ipsec_remove_trailer()
net: dsa: fix value check in bcm_sf2_sw_probe()
net: korina: handle clk prepare error in korina_probe()
Yue Haibing (1):
ip6mr: Fix skb_under_panic in ip6mr_cache_report()
Zhengchao Shao (1):
net/mlx5: DR, fix memory leak in mlx5dr_cmd_create_reformat_ctx
gaoming (1):
exfat: use kvmalloc_array/kvfree instead of kmalloc_array/kfree
ndesaulniers(a)google.com (1):
word-at-a-time: use the same return type for has_zero regardless of endianness
valis (3):
net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after-free
net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after-free
net/sched: cls_route: No longer copy tcf_result on update to avoid use-after-free
LKFT build plans updated with toolchain gcc-13 and here is the report.
Stable rc 6.1 arm64 builds with gcc-13 failed and the bisection is pointing
to this as first bad commit,
# first fixed commit: [e6a71160cc145e18ab45195abf89884112e02dfb]
gcc-plugins: Reorganize gimple includes for GCC 13
Thanks Anders for bisecting this problem against Linux 6.2-rc6.
Build errors:
---------------
In file included from /builds/linux/scripts/gcc-plugins/gcc-common.h:75,
from /builds/linux/scripts/gcc-plugins/stackleak_plugin.c:30:
/usr/lib/gcc-cross/aarch64-linux-gnu/13/plugin/include/gimple-fold.h:72:32:
error: use of enum 'gsi_iterator_update' without previous declaration
72 | enum gsi_iterator_update,
| ^~~~~~~~~~~~~~~~~~
Reported-by: Linux Kernel Functional Testing <lkft(a)linaro.org>
Links:
--------
- https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.1.y-sanity/build…
- https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.1.y-sanity/build…
- https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.1.y-sanity/build…
--
Linaro LKFT
https://lkft.linaro.org