Linux-HyperV List
 help / color / mirror / Atom feed
* [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module
@ 2026-05-04 18:59 Stanislav Kinsburskii
  2026-05-04 19:04 ` [PATCH v3] mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access Stanislav Kinsburskii
  2026-05-04 19:06 ` [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module Stanislav Kinsburskii
  0 siblings, 2 replies; 4+ messages in thread
From: Stanislav Kinsburskii @ 2026-05-04 18:59 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli; +Cc: linux-hyperv, linux-kernel

This series addresses bugs found during a continued review of the
mshv_root module introduced by commit 621191d709b14 ("Drivers: hv:
Introduce mshv_root module to expose /dev/mshv to VMMs").

Changes since v2:
- "Fix mshv_prepare_pinned_region error path for unencrypted
  partitions": removed inline mshv_region_invalidate() to prevent
  zeroing mreg_pages before mshv_region_destroy() can unmap partial
  SLAT mappings; for encrypted share-failure, memset the page array
  without unpinning (pages are host-inaccessible).
- "Consolidate irqfd interrupt injection paths": fixed data race in
  mshv_irqfd_assign EPOLLIN path — girq_ent is now snapshotted inside
  the seqcount loop (matching mshv_irqfd_wakeup) to prevent a
  concurrent routing update from injecting vector 0 to VP 0.
- "Add missing vp_index bounds check in intercept ISR": added
  array_index_nospec() after the bounds check to prevent speculative
  out-of-bounds array access.
- "Add store/load ordering for VP array publish": added missing
  smp_load_acquire in mshv_try_assert_irq_fast.

Changes since v1:
- Added 8 new patches addressing issues found by Sashiko (automated
  review) covering the irqfd, portid, scheduler message, and VP
  lifecycle paths.
- Consolidated the irqfd fast/slow injection paths to eliminate
  duplicated seqcount reads and fix the GSI 0 validity bypass.
- Added memory ordering for the lockless VP array.

The fixes range from data corruption and use-after-free to silent
functional failures and sleeping-while-atomic:

 Memory region management:
  - Integer overflow on userspace-controlled allocation size
    (mshv_region_create)
  - Silent success on map failure for unencrypted partitions
    (mshv_prepare_pinned_region)
  - u64 overflow in region overlap check allowing overlapping mappings

 IRQ/eventfd path:
  - IRQ state leak and type truncation in hypercall helpers
  - Missing locking and hlist_del vs hlist_del_init race in irqfd
    deassign
  - Defensive synchronize_srcu in irqfd shutdown (follows KVM pattern)
  - NULL pointer dereference on spurious interrupt to non-existent VP
    (mshv_try_assert_irq_fast)
  - Broken seqcount read protection — torn reads of interrupt routing
  - Duplicated and inconsistent validity checks between fast/slow
    injection paths; fast path could inject vector 0 spuriously
  - Level-triggered check on uninitialized data making interrupt
    resampling completely non-functional
  - Duplicate GSI 0 detection using the wrong predicate

 Port ID table:
  - Use-after-RCU in mshv_portid_lookup (dereference outside read-side
    critical section)
  - Sleeping under spinlock in mshv_portid_alloc (GFP_KERNEL inside
    idr_lock)
  - Use kfree_rcu for deferred free without blocking

 SynIC / ISR paths:
  - Missing VP index bounds check in intercept ISR (OOB in interrupt
    context from untrusted hypervisor data)
  - Missing store/load ordering for VP array publish — lockless ISR
    readers could observe partially-initialized VP
  - Missing bounds validation in scheduler messages
    (handle_pair_message vp_count, handle_bitset_message bank_mask)

 Miscellaneous:
  - Missing error code on VP allocation failure (silent success to
    userspace)

Kudos to Claude and Sashiko for assisting with analysis and
implementation.


---

Stanislav Kinsburskii (18):
      mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access
      mshv: Fix potential integer overflow in mshv_region_create
      mshv: Fix mshv_prepare_pinned_region error path for unencrypted partitions
      mshv: Fix potential u64 overflow in region overlap check
      mshv: Fix race in mshv_irqfd_deassign
      mshv: Add defensive synchronize_srcu in irqfd shutdown
      mshv: Add NULL check for vp in mshv_try_assert_irq_fast
      mshv: Fix broken seqcount read protection
      mshv: Consolidate irqfd interrupt injection paths
      mshv: Fix level-triggered check on uninitialized data
      mshv: Fix duplicate GSI detection for GSI 0
      mshv: Fix use-after-RCU in mshv_portid_lookup
      mshv: Fix sleeping under spinlock in mshv_portid_alloc
      mshv: Use kfree_rcu in mshv_portid_free
      mshv: Add missing vp_index bounds check in intercept ISR
      mshv: Add store/load ordering for VP array publish
      mshv: Validate scheduler message bounds from hypervisor
      mshv: Fix missing error code on VP allocation failure


 drivers/hv/mshv_eventfd.c      |  108 +++++++++++++++++++++++++---------------
 drivers/hv/mshv_irq.c          |    2 -
 drivers/hv/mshv_portid_table.c |   12 ++--
 drivers/hv/mshv_regions.c      |    2 -
 drivers/hv/mshv_root_hv_call.c |   18 ++-----
 drivers/hv/mshv_root_main.c    |   39 ++++++++++----
 drivers/hv/mshv_synic.c        |   36 +++++++++++--
 7 files changed, 136 insertions(+), 81 deletions(-)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3] mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access
  2026-05-04 18:59 [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module Stanislav Kinsburskii
@ 2026-05-04 19:04 ` Stanislav Kinsburskii
  2026-05-04 19:06 ` [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module Stanislav Kinsburskii
  1 sibling, 0 replies; 4+ messages in thread
From: Stanislav Kinsburskii @ 2026-05-04 19:04 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli; +Cc: linux-hyperv, linux-kernel

The bounds check inside the PFN-filling loop can return -EINVAL while
interrupts are disabled via local_irq_save(), leaking IRQ state.

Remove the check — it is redundant because the loop invariant
(done + i < page_count == page_struct_count >> large_shift) guarantees
(done + i) << large_shift < page_struct_count always holds.

While here, fix type mismatches: change 'int done' to 'u64 done' and
use u64 for loop and batch-size variables so they match the u64
page_count they are compared against.

Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs")
Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
---
 drivers/hv/mshv_root_hv_call.c |   18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index 129456bd72aba..cc580225e9e45 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -1042,7 +1042,7 @@ int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
 {
 	struct hv_input_modify_sparse_spa_page_host_access *input_page;
 	u64 status;
-	int done = 0;
+	u64 done = 0;
 	unsigned long irq_flags, large_shift = 0;
 	u64 page_count = page_struct_count;
 	u16 code = acquire ? HVCALL_ACQUIRE_SPARSE_SPA_PAGE_HOST_ACCESS :
@@ -1059,9 +1059,9 @@ int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
 	}
 
 	while (done < page_count) {
-		ulong i, completed, remain = page_count - done;
-		int rep_count = min(remain,
-				    HV_MODIFY_SPARSE_SPA_PAGE_HOST_ACCESS_MAX_PAGE_COUNT);
+		u64 i, completed, remain = page_count - done;
+		u64 rep_count = min_t(u64, remain,
+				      HV_MODIFY_SPARSE_SPA_PAGE_HOST_ACCESS_MAX_PAGE_COUNT);
 
 		local_irq_save(irq_flags);
 		input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
@@ -1075,15 +1075,9 @@ int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
 		input_page->flags = flags;
 		input_page->host_access = host_access;
 
-		for (i = 0; i < rep_count; i++) {
-			u64 index = (done + i) << large_shift;
-
-			if (index >= page_struct_count)
-				return -EINVAL;
-
+		for (i = 0; i < rep_count; i++)
 			input_page->spa_page_list[i] =
-						page_to_pfn(pages[index]);
-		}
+				page_to_pfn(pages[(done + i) << large_shift]);
 
 		status = hv_do_rep_hypercall(code, rep_count, 0, input_page,
 					     NULL);



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module
  2026-05-04 18:59 [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module Stanislav Kinsburskii
  2026-05-04 19:04 ` [PATCH v3] mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access Stanislav Kinsburskii
@ 2026-05-04 19:06 ` Stanislav Kinsburskii
  1 sibling, 0 replies; 4+ messages in thread
From: Stanislav Kinsburskii @ 2026-05-04 19:06 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli; +Cc: linux-hyperv, linux-kernel

On Mon, May 04, 2026 at 06:59:01PM +0000, Stanislav Kinsburskii wrote:
> This series addresses bugs found during a continued review of the
> mshv_root module introduced by commit 621191d709b14 ("Drivers: hv:
> Introduce mshv_root module to expose /dev/mshv to VMMs").
> 

THis series is malformed.
Please disregard.

Thanks,
Stanislav

> Changes since v2:
> - "Fix mshv_prepare_pinned_region error path for unencrypted
>   partitions": removed inline mshv_region_invalidate() to prevent
>   zeroing mreg_pages before mshv_region_destroy() can unmap partial
>   SLAT mappings; for encrypted share-failure, memset the page array
>   without unpinning (pages are host-inaccessible).
> - "Consolidate irqfd interrupt injection paths": fixed data race in
>   mshv_irqfd_assign EPOLLIN path — girq_ent is now snapshotted inside
>   the seqcount loop (matching mshv_irqfd_wakeup) to prevent a
>   concurrent routing update from injecting vector 0 to VP 0.
> - "Add missing vp_index bounds check in intercept ISR": added
>   array_index_nospec() after the bounds check to prevent speculative
>   out-of-bounds array access.
> - "Add store/load ordering for VP array publish": added missing
>   smp_load_acquire in mshv_try_assert_irq_fast.
> 
> Changes since v1:
> - Added 8 new patches addressing issues found by Sashiko (automated
>   review) covering the irqfd, portid, scheduler message, and VP
>   lifecycle paths.
> - Consolidated the irqfd fast/slow injection paths to eliminate
>   duplicated seqcount reads and fix the GSI 0 validity bypass.
> - Added memory ordering for the lockless VP array.
> 
> The fixes range from data corruption and use-after-free to silent
> functional failures and sleeping-while-atomic:
> 
>  Memory region management:
>   - Integer overflow on userspace-controlled allocation size
>     (mshv_region_create)
>   - Silent success on map failure for unencrypted partitions
>     (mshv_prepare_pinned_region)
>   - u64 overflow in region overlap check allowing overlapping mappings
> 
>  IRQ/eventfd path:
>   - IRQ state leak and type truncation in hypercall helpers
>   - Missing locking and hlist_del vs hlist_del_init race in irqfd
>     deassign
>   - Defensive synchronize_srcu in irqfd shutdown (follows KVM pattern)
>   - NULL pointer dereference on spurious interrupt to non-existent VP
>     (mshv_try_assert_irq_fast)
>   - Broken seqcount read protection — torn reads of interrupt routing
>   - Duplicated and inconsistent validity checks between fast/slow
>     injection paths; fast path could inject vector 0 spuriously
>   - Level-triggered check on uninitialized data making interrupt
>     resampling completely non-functional
>   - Duplicate GSI 0 detection using the wrong predicate
> 
>  Port ID table:
>   - Use-after-RCU in mshv_portid_lookup (dereference outside read-side
>     critical section)
>   - Sleeping under spinlock in mshv_portid_alloc (GFP_KERNEL inside
>     idr_lock)
>   - Use kfree_rcu for deferred free without blocking
> 
>  SynIC / ISR paths:
>   - Missing VP index bounds check in intercept ISR (OOB in interrupt
>     context from untrusted hypervisor data)
>   - Missing store/load ordering for VP array publish — lockless ISR
>     readers could observe partially-initialized VP
>   - Missing bounds validation in scheduler messages
>     (handle_pair_message vp_count, handle_bitset_message bank_mask)
> 
>  Miscellaneous:
>   - Missing error code on VP allocation failure (silent success to
>     userspace)
> 
> Kudos to Claude and Sashiko for assisting with analysis and
> implementation.
> 
> 
> ---
> 
> Stanislav Kinsburskii (18):
>       mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access
>       mshv: Fix potential integer overflow in mshv_region_create
>       mshv: Fix mshv_prepare_pinned_region error path for unencrypted partitions
>       mshv: Fix potential u64 overflow in region overlap check
>       mshv: Fix race in mshv_irqfd_deassign
>       mshv: Add defensive synchronize_srcu in irqfd shutdown
>       mshv: Add NULL check for vp in mshv_try_assert_irq_fast
>       mshv: Fix broken seqcount read protection
>       mshv: Consolidate irqfd interrupt injection paths
>       mshv: Fix level-triggered check on uninitialized data
>       mshv: Fix duplicate GSI detection for GSI 0
>       mshv: Fix use-after-RCU in mshv_portid_lookup
>       mshv: Fix sleeping under spinlock in mshv_portid_alloc
>       mshv: Use kfree_rcu in mshv_portid_free
>       mshv: Add missing vp_index bounds check in intercept ISR
>       mshv: Add store/load ordering for VP array publish
>       mshv: Validate scheduler message bounds from hypervisor
>       mshv: Fix missing error code on VP allocation failure
> 
> 
>  drivers/hv/mshv_eventfd.c      |  108 +++++++++++++++++++++++++---------------
>  drivers/hv/mshv_irq.c          |    2 -
>  drivers/hv/mshv_portid_table.c |   12 ++--
>  drivers/hv/mshv_regions.c      |    2 -
>  drivers/hv/mshv_root_hv_call.c |   18 ++-----
>  drivers/hv/mshv_root_main.c    |   39 ++++++++++----
>  drivers/hv/mshv_synic.c        |   36 +++++++++++--
>  7 files changed, 136 insertions(+), 81 deletions(-)
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module
@ 2026-05-04 19:08 Stanislav Kinsburskii
  0 siblings, 0 replies; 4+ messages in thread
From: Stanislav Kinsburskii @ 2026-05-04 19:08 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli; +Cc: linux-hyperv, linux-kernel

This series addresses bugs found during a continued review of the
mshv_root module mostly introduced by commit 621191d709b14 ("Drivers: hv:
Introduce mshv_root module to expose /dev/mshv to VMMs").

Changes since v2:
- "Fix mshv_prepare_pinned_region error path for unencrypted
  partitions": removed inline mshv_region_invalidate() to prevent
  zeroing mreg_pages before mshv_region_destroy() can unmap partial
  SLAT mappings; for encrypted share-failure, memset the page array
  without unpinning (pages are host-inaccessible).
- "Consolidate irqfd interrupt injection paths": fixed data race in
  mshv_irqfd_assign EPOLLIN path — girq_ent is now snapshotted inside
  the seqcount loop (matching mshv_irqfd_wakeup) to prevent a
  concurrent routing update from injecting vector 0 to VP 0.
- "Add missing vp_index bounds check in intercept ISR": added
  array_index_nospec() after the bounds check to prevent speculative
  out-of-bounds array access.
- "Add store/load ordering for VP array publish": added missing
  smp_load_acquire in mshv_try_assert_irq_fast.

Changes since v1:
- Added 8 new patches addressing issues found by Sashiko (automated
  review) covering the irqfd, portid, scheduler message, and VP
  lifecycle paths.
- Consolidated the irqfd fast/slow injection paths to eliminate
  duplicated seqcount reads and fix the GSI 0 validity bypass.
- Added memory ordering for the lockless VP array.

The fixes range from data corruption and use-after-free to silent
functional failures and sleeping-while-atomic:

 Memory region management:
  - Integer overflow on userspace-controlled allocation size
    (mshv_region_create)
  - Silent success on map failure for unencrypted partitions
    (mshv_prepare_pinned_region)
  - u64 overflow in region overlap check allowing overlapping mappings

 IRQ/eventfd path:
  - IRQ state leak and type truncation in hypercall helpers
  - Missing locking and hlist_del vs hlist_del_init race in irqfd
    deassign
  - Defensive synchronize_srcu in irqfd shutdown (follows KVM pattern)
  - NULL pointer dereference on spurious interrupt to non-existent VP
    (mshv_try_assert_irq_fast)
  - Broken seqcount read protection — torn reads of interrupt routing
  - Duplicated and inconsistent validity checks between fast/slow
    injection paths; fast path could inject vector 0 spuriously
  - Level-triggered check on uninitialized data making interrupt
    resampling completely non-functional
  - Duplicate GSI 0 detection using the wrong predicate

 Port ID table:
  - Use-after-RCU in mshv_portid_lookup (dereference outside read-side
    critical section)
  - Sleeping under spinlock in mshv_portid_alloc (GFP_KERNEL inside
    idr_lock)
  - Use kfree_rcu for deferred free without blocking

 SynIC / ISR paths:
  - Missing VP index bounds check in intercept ISR (OOB in interrupt
    context from untrusted hypervisor data)
  - Missing store/load ordering for VP array publish — lockless ISR
    readers could observe partially-initialized VP
  - Missing bounds validation in scheduler messages
    (handle_pair_message vp_count, handle_bitset_message bank_mask)

 Miscellaneous:
  - Missing error code on VP allocation failure (silent success to
    userspace)

Kudos to Claude and Sashiko for assisting with analysis and
implementation.

---

Stanislav Kinsburskii (18):
      mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access
      mshv: Fix potential integer overflow in mshv_region_create
      mshv: Fix mshv_prepare_pinned_region error path for unencrypted partitions
      mshv: Fix potential u64 overflow in region overlap check
      mshv: Fix race in mshv_irqfd_deassign
      mshv: Add defensive synchronize_srcu in irqfd shutdown
      mshv: Add NULL check for vp in mshv_try_assert_irq_fast
      mshv: Fix broken seqcount read protection
      mshv: Consolidate irqfd interrupt injection paths
      mshv: Fix level-triggered check on uninitialized data
      mshv: Fix duplicate GSI detection for GSI 0
      mshv: Fix use-after-RCU in mshv_portid_lookup
      mshv: Fix sleeping under spinlock in mshv_portid_alloc
      mshv: Use kfree_rcu in mshv_portid_free
      mshv: Add missing vp_index bounds check in intercept ISR
      mshv: Add store/load ordering for VP array publish
      mshv: Validate scheduler message bounds from hypervisor
      mshv: Fix missing error code on VP allocation failure


 drivers/hv/mshv_eventfd.c      |  108 +++++++++++++++++++++++++---------------
 drivers/hv/mshv_irq.c          |    2 -
 drivers/hv/mshv_portid_table.c |   12 ++--
 drivers/hv/mshv_regions.c      |    2 -
 drivers/hv/mshv_root_hv_call.c |   18 ++-----
 drivers/hv/mshv_root_main.c    |   39 ++++++++++----
 drivers/hv/mshv_synic.c        |   36 +++++++++++--
 7 files changed, 136 insertions(+), 81 deletions(-)


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-05-04 19:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-04 18:59 [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module Stanislav Kinsburskii
2026-05-04 19:04 ` [PATCH v3] mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access Stanislav Kinsburskii
2026-05-04 19:06 ` [PATCH v3 00/18] mshv: Bug fixes across the mshv_root module Stanislav Kinsburskii
  -- strict thread matches above, loose matches on Subject: below --
2026-05-04 19:08 Stanislav Kinsburskii

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox