From: sashiko-bot@kernel.org
To: "Claudio Imbrenda" <imbrenda@linux.ibm.com>
Cc: "Alexander Gordeev" <agordeev@linux.ibm.com>,
kvm@vger.kernel.org,
"Christian Borntraeger" <borntraeger@linux.ibm.vom>,
"Vasily Gorbik" <gor@linux.ibm.com>,
"Heiko Carstens" <hca@linux.ibm.com>,
linux-s390@vger.kernel.org
Subject: Re: [PATCH v2 4/9] KVM: s390: Fix dirty marking in adapter_indicators_set*()
Date: Wed, 12 Aug 2026 11:00:58 +0000 [thread overview]
Message-ID: <20260812110058.EBD3D1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260812104436.109741-5-imbrenda@linux.ibm.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Replacing set_page_dirty_lock() with set_page_dirty() on GUP-pinned pages introduces a Use-After-Free vulnerability due to a race with file truncation.
- [High] Ordering mark_page_dirty() before memory modification creates a race condition with dirty log harvesting, risking lost updates during live migration.
--
--- Patch [4]: [PATCH v2 4/9] KVM: s390: Fix dirty marking in adapter_indicators_set*() ---
commit 8bb6adeda8416869b198540515723990915f8390
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: Fix dirty marking in adapter_indicators_set*()
This commit updates dirty page marking for adapter indicators in KVM s390.
It adds missing calls to set_page_dirty() and mark_page_dirty() in the fast
path and reorganizes the slow path, replacing set_page_dirty_lock() with
set_page_dirty() for pinned pages.
> diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
> index 608ff95d53bac..e79f636c7544d 100644
> --- a/arch/s390/kvm/interrupt.c
> +++ b/arch/s390/kvm/interrupt.c
[ ... ]
> @@ -2997,21 +2999,20 @@ static int adapter_indicators_set(struct kvm *kvm,
> ind_page = pin_map_page(kvm, adapter_int->ind_addr, 0);
> if (!ind_page)
> return -1;
> - idx = srcu_read_lock(&kvm->srcu);
> map = page_address(ind_page);
> bit = get_ind_bit(adapter_int->ind_addr,
> adapter_int->ind_offset, adapter->swap);
> set_bit(bit, map);
> - mark_page_dirty(kvm, adapter_int->ind_gaddr >> PAGE_SHIFT);
> - set_page_dirty_lock(ind_page);
> - srcu_read_unlock(&kvm->srcu, idx);
> + set_page_dirty(ind_page);
[Severity: High]
Is it safe to replace set_page_dirty_lock() with set_page_dirty() here?
For short-term GUP-pinned memory like this ind_page, the memory can be backed
by any filesystem. Without the folio lock, a concurrent file truncation could
unmap the folio and free the mapping.
If set_page_dirty() reads folio->mapping concurrently, could it dereference
freed memory when calling mapping->a_ops->dirty_folio()?
> unpin_user_page(ind_page);
> } else {
> map = page_address(ind_info->page);
> bit = get_ind_bit(ind_info->addr, adapter_int->ind_offset, adapter->swap);
> set_bit(bit, map);
> + set_page_dirty(ind_info->page);
> spin_unlock_irqrestore(&adapter->maps_lock, flags);
> }
> + mark_page_dirty(kvm, gpa_to_gfn(adapter_int->ind_gaddr));
>
> spin_lock_irqsave(&adapter->maps_lock, flags);
> summary_info = get_map_info(adapter, adapter_int->summary_addr);
> @@ -3020,22 +3021,21 @@ static int adapter_indicators_set(struct kvm *kvm,
> summary_page = pin_map_page(kvm, adapter_int->summary_addr, 0);
> if (WARN_ON_ONCE(!summary_page))
> return -1;
> - idx = srcu_read_lock(&kvm->srcu);
> map = page_address(summary_page);
> bit = get_ind_bit(adapter_int->summary_addr,
> adapter_int->summary_offset, adapter->swap);
> summary_set = test_and_set_bit(bit, map);
> - mark_page_dirty(kvm, adapter_int->summary_gaddr >> PAGE_SHIFT);
> - set_page_dirty_lock(summary_page);
> - srcu_read_unlock(&kvm->srcu, idx);
> + set_page_dirty(summary_page);
[Severity: High]
Similarly, could calling set_page_dirty() instead of set_page_dirty_lock() on
the GUP-pinned summary_page lead to a use-after-free if the file is truncated
concurrently?
> unpin_user_page(summary_page);
> } else {
> map = page_address(summary_info->page);
> bit = get_ind_bit(summary_info->addr, adapter_int->summary_offset,
> adapter->swap);
> summary_set = test_and_set_bit(bit, map);
> + set_page_dirty(summary_info->page);
> spin_unlock_irqrestore(&adapter->maps_lock, flags);
> }
> + mark_page_dirty(kvm, gpa_to_gfn(adapter_int->summary_gaddr));
>
> return summary_set ? 0 : 1;
> }
> @@ -3045,26 +3045,30 @@ static int adapter_indicators_set_fast(struct kvm *kvm,
> struct kvm_s390_adapter_int *adapter_int,
> int setbit)
> {
[ ... ]
> map = page_address(ind_info->page);
> bit = get_ind_bit(ind_info->addr, adapter_int->ind_offset, adapter->swap);
> - if (setbit)
> + if (setbit) {
> + mark_page_dirty(kvm, gpa_to_gfn(adapter_int->ind_gaddr));
> + set_page_dirty(ind_info->page);
> set_bit(bit, map);
> + }
[Severity: High]
Does calling mark_page_dirty() before actually modifying the memory with
set_bit() create a race condition with dirty log harvesting?
If userspace harvests the KVM dirty log between mark_page_dirty() and
set_bit(), it might clear the dirty bit in KVM's tracking and read the old
unmodified page.
When set_bit() then executes, the page would no longer be marked dirty, and
the change wouldn't be migrated to the destination.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260812104436.109741-1-imbrenda@linux.ibm.com?part=4
next prev parent reply other threads:[~2026-08-12 11:00 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-12 10:44 [PATCH v2 0/9] KVM: s390: And then... even more fixes again Claudio Imbrenda
2026-08-12 10:44 ` [PATCH v2 1/9] KVM: s390: Properly handle NULL pointer in dat_cond_set_storage_key() Claudio Imbrenda
2026-08-12 10:55 ` sashiko-bot
2026-08-12 10:44 ` [PATCH v2 2/9] KVM: s390: Use srcu in kvm_arch_vcpu_unlocked_ioctl() Claudio Imbrenda
2026-08-12 10:58 ` sashiko-bot
2026-08-12 11:02 ` Christoph Schlameuss
2026-08-12 10:44 ` [PATCH v2 3/9] KVM: s390: Fix get_all_floating_irqs() Claudio Imbrenda
2026-08-12 10:55 ` Christian Borntraeger
2026-08-12 10:55 ` sashiko-bot
2026-08-12 14:06 ` Christoph Schlameuss
2026-08-12 10:44 ` [PATCH v2 4/9] KVM: s390: Fix dirty marking in adapter_indicators_set*() Claudio Imbrenda
2026-08-12 11:00 ` sashiko-bot [this message]
2026-08-12 11:03 ` Christian Borntraeger
2026-08-12 11:37 ` Claudio Imbrenda
2026-08-12 10:44 ` [PATCH v2 5/9] KVM: s390: Fix pgste_get_trylock_multiple() Claudio Imbrenda
2026-08-12 10:50 ` sashiko-bot
2026-08-12 11:11 ` Christoph Schlameuss
2026-08-12 10:44 ` [PATCH v2 6/9] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status Claudio Imbrenda
2026-08-12 10:53 ` sashiko-bot
2026-08-12 12:59 ` Christoph Schlameuss
2026-08-12 13:11 ` Claudio Imbrenda
2026-08-12 13:23 ` Christoph Schlameuss
2026-08-12 10:44 ` [PATCH v2 7/9] KVM: s390: Fix kvm_s390_clear_pv_state() Claudio Imbrenda
2026-08-12 10:53 ` sashiko-bot
2026-08-12 13:02 ` Christoph Schlameuss
2026-08-12 10:44 ` [PATCH v2 8/9] KVM: s390: Fix potential tiny kernel stack leak Claudio Imbrenda
2026-08-12 10:53 ` sashiko-bot
2026-08-12 13:14 ` Christoph Schlameuss
2026-08-12 10:44 ` [PATCH v2 9/9] KVM: s390: Fix _gaccess_shadow_fault() Claudio Imbrenda
2026-08-12 11:47 ` 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=20260812110058.EBD3D1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.vom \
--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