All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.