From: sashiko-bot@kernel.org
To: "Claudio Imbrenda" <imbrenda@linux.ibm.com>
Cc: linux-s390@vger.kernel.org, kvm@vger.kernel.org,
"Vasily Gorbik" <gor@linux.ibm.com>,
"Alexander Gordeev" <agordeev@linux.ibm.com>,
"Heiko Carstens" <hca@linux.ibm.com>
Subject: Re: [PATCH v6 02/14] KVM: s390: Fix kvm_s390_vcpu_unsetup_cmma()
Date: Thu, 30 Jul 2026 16:55:29 +0000 [thread overview]
Message-ID: <20260730165530.276F11F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260730162714.133327-3-imbrenda@linux.ibm.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Unprivileged local memory corruption via `sca_dispose(NULL)` leading to freeing physical pages 1, 2, and 3.
- [High] Memory leak of `vcpu->arch.mc` in the error path of `kvm_arch_vcpu_create()`.
- [High] Missing lock acquisition when removing a child gmap in the vCPU creation error path.
- [High] When `uv_call` fails during `kvm_s390_pv_create_cpu()`, newly allocated `stor_base` and `sida_addr` pages are permanently leaked.
--
--- Patch [2]: [PATCH v6 02/14] KVM: s390: Fix kvm_s390_vcpu_unsetup_cmma() ---
commit b2abac5b0352ced2b250d10ad5dfc60b18cae87c
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: Fix kvm_s390_vcpu_unsetup_cmma()
In some cases kvm_s390_vcpu_unsetup_cmma() can be called with a 0
cbrlo; in such cases, if running with V != R, free_page() will attempt
to free physical page 0.
Fix by freeing cbrlo only if it's non-zero.
Fixes: b31605c12f4e ("KVM: s390: make cmma usage conditionally")
Fixes: 29b40f105ec8 ("KVM: s390: protvirt: Add initial vm and cpu lifecycle handling")
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index f86b4b0b356f4..9ec5833a09732 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -3677,7 +3677,8 @@ static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu)
>
> void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu)
> {
> - free_page((unsigned long)phys_to_virt(vcpu->arch.sie_block->cbrlo));
> + if (vcpu->arch.sie_block->cbrlo)
> + free_page((unsigned long)phys_to_virt(vcpu->arch.sie_block->cbrlo));
> vcpu->arch.sie_block->cbrlo = 0;
> }
While reviewing this code, a few other things were noticed nearby.
arch/s390/kvm/kvm-s390.c:kvm_arch_vcpu_create() {
[ ... ]
out_ucontrol_uninit:
if (kvm_is_ucontrol(vcpu->kvm)) {
gmap_remove_child(vcpu->arch.gmap);
[Severity: High]
This is a pre-existing issue, but is it possible we are missing a lock here?
In kvm_arch_vcpu_create(), if a ucontrol VM's vCPU setup fails, it calls
gmap_remove_child(vcpu->arch.gmap).
The gmap_remove_child() function expects the parent gmap's children_lock to
be held and concurrently modifies the parent gmap's children list. However,
this error path appears to omit acquiring the children_lock.
Could this lead to a data race and list corruption?
vcpu->arch.gmap = gmap_put(vcpu->arch.gmap);
}
out_free_sie_block:
free_page((unsigned long)(vcpu->arch.sie_block));
return rc;
}
[Severity: High]
This is a pre-existing issue, but what happens to the vcpu->arch.mc memory
when we take this error path?
When an error occurs in kvm_arch_vcpu_create() after vcpu->arch.mc
allocation, the code jumps to out_ucontrol_uninit and out_free_sie_block.
While it frees the sie_block and removes the gmap child, it seems to never
free the memory allocated by kvm_s390_new_mmu_cache(vcpu->arch.mc).
Can userspace repeatedly trigger vCPU creation failures to leak memory and
cause a local denial of service?
arch/s390/kvm/kvm-s390.c:kvm_arch_init_vm() {
[ ... ]
out_err:
free_page((unsigned long)kvm->arch.sie_page2);
debug_unregister(kvm->arch.dbf);
sca_dispose(kvm);
[ ... ]
}
arch/s390/kvm/kvm-s390.c:sca_dispose() {
free_pages_exact(kvm->arch.sca, sizeof(*kvm->arch.sca));
kvm->arch.sca = NULL;
}
[Severity: Critical]
This is a pre-existing issue, but is there a risk of memory corruption here?
In kvm_arch_init_vm(), if VM creation fails early, the code jumps to out_err
before kvm->arch.sca is allocated.
Since the kvm structure is zero-allocated, kvm->arch.sca is NULL.
The sca_dispose() function calls
free_pages_exact(kvm->arch.sca, sizeof(*kvm->arch.sca)). The size of
struct esca_block is roughly 16KB.
The free_pages_exact(virt, size) function loops from addr = virt to
addr + PAGE_ALIGN(size), incrementing by PAGE_SIZE, and calls
free_page(addr).
For virt == NULL, it iterates through addresses 0, 4096, 8192, and 12288.
While free_page(0) is safely ignored, free_page(4096) translates to
__free_pages(virt_to_page(4096), 0) and incorrectly frees host physical pages
1, 2, and 3 into the buddy allocator.
Can an unprivileged user trigger this trivially by calling
ioctl(KVM_CREATE_VM, 1)?
arch/s390/kvm/pv.c:kvm_s390_pv_create_cpu() {
[ ... ]
cc = uv_call(0, (u64)&uvcb);
[ ... ]
if (cc) {
u16 dummy;
kvm_s390_pv_destroy_cpu(vcpu, &dummy, &dummy);
return -EIO;
}
[ ... ]
}
arch/s390/kvm/pv.c:kvm_s390_pv_destroy_cpu() {
int cc;
if (!kvm_s390_pv_cpu_get_handle(vcpu))
return 0;
[ ... ]
}
[Severity: High]
This is a pre-existing issue, but does this error handling permanently leak
the newly allocated stor_base and sida_addr pages?
The kvm_s390_pv_create_cpu() function allocates vcpu->arch.pv.stor_base
and sida_addr. If uv_call fails, it jumps to error handling which
calls kvm_s390_pv_destroy_cpu(vcpu).
However, kvm_s390_pv_destroy_cpu() begins with an early return:
if (!kvm_s390_pv_cpu_get_handle(vcpu)) return 0;
Because vcpu->arch.pv.handle is only set upon successful uv_call completion,
the handle is 0 here. Thus, the destruction routine does nothing and bypasses
the free_pages() blocks entirely.
Could a compromised or malicious userspace trigger failures in uv_call to
repeatedly leak host memory?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730162714.133327-1-imbrenda@linux.ibm.com?part=2
next prev parent reply other threads:[~2026-07-30 16:55 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-30 16:27 [PATCH v6 00/14] KVM: s390: Misc fixes Claudio Imbrenda
2026-07-30 16:27 ` [PATCH v6 01/14] KVM: s390: Fix unlikely NULL gmap dereference Claudio Imbrenda
2026-07-30 16:50 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 02/14] KVM: s390: Fix kvm_s390_vcpu_unsetup_cmma() Claudio Imbrenda
2026-07-30 16:55 ` sashiko-bot [this message]
2026-07-30 16:27 ` [PATCH v6 03/14] KVM: s390: Fix overclearing ESCA in case of error Claudio Imbrenda
2026-07-30 17:04 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 04/14] KVM: s390: ucontrol: Fix sca_clear_ext_call() Claudio Imbrenda
2026-07-30 16:51 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 05/14] KVM: s390: Fix leaking of PGM_ADDRESSING to userspace Claudio Imbrenda
2026-07-30 16:40 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 06/14] KVM: s390: Fix race in __do_essa() Claudio Imbrenda
2026-07-30 16:47 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 07/14] KVM: s390: cmma: Fix dirty tracking when removing memslot Claudio Imbrenda
2026-07-30 16:48 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 08/14] KVM: s390: ucontrol: Add missing locking around gmap_remove_child() Claudio Imbrenda
2026-07-30 16:48 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 09/14] KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails Claudio Imbrenda
2026-07-30 16:44 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 10/14] KVM: s390: Return -EINTR if a signal is pending while faulting-in Claudio Imbrenda
2026-07-30 16:53 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 11/14] KVM: s390: Fix ordering when adding to SCA Claudio Imbrenda
2026-07-30 16:54 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 12/14] KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu() Claudio Imbrenda
2026-07-30 16:52 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 13/14] KVM: s390: Fix kvm_arch_commit_memory_region() when low on memory Claudio Imbrenda
2026-07-30 17:02 ` sashiko-bot
2026-07-30 16:27 ` [PATCH v6 14/14] KVM: s390: Move DAT table updates to kvm_arch_prepare_memory_region() Claudio Imbrenda
2026-07-30 17:01 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260730165530.276F11F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=imbrenda@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox