mshv_intercept_isr() reads vp_index from the intercept message payload
and uses it directly to index into partition->pt_vp_array without
validating it against MSHV_MAX_VPS. A malformed or corrupted hypervisor
message with a vp_index beyond the array bounds would cause an
out-of-bounds memory access in interrupt context, likely crashing the
host.

Use READ_ONCE() when reading vp_index from the shared SynIC message
page to prevent the compiler from re-fetching the value between the
bounds check and the array access.

Both handle_bitset_message() and handle_pair_message() already validate
vp_index before use. Add the same check to mshv_intercept_isr() for
consistency.

Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose 
/dev/mshv to VMMs")
Signed-off-by: Stanislav Kinsburskii <[email protected]>
---
 drivers/hv/mshv_synic.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/mshv_synic.c b/drivers/hv/mshv_synic.c
index 43f1bcbbf2d34..d4d98fa771189 100644
--- a/drivers/hv/mshv_synic.c
+++ b/drivers/hv/mshv_synic.c
@@ -382,8 +382,12 @@ mshv_intercept_isr(struct hv_message *msg)
         * (because the vp is only deleted when the partition is), no additional
         * locking is needed here
         */
-       vp_index =
-              ((struct hv_opaque_intercept_message *)msg->u.payload)->vp_index;
+       vp_index = READ_ONCE(
+              ((struct hv_opaque_intercept_message 
*)msg->u.payload)->vp_index);
+       if (unlikely(vp_index >= MSHV_MAX_VPS)) {
+               pr_debug("VP index %u out of bounds\n", vp_index);
+               goto unlock_out;
+       }
        vp = partition->pt_vp_array[vp_index];
        if (unlikely(!vp)) {
                pr_debug("failed to find VP %u\n", vp_index);



Reply via email to