Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Paolo Bonzini" <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH 24/24] KVM: x86/mmu: use kvm_page_format to test SPTEs
Date: Wed, 03 Jun 2026 11:34:01 +0000	[thread overview]
Message-ID: <20260603113402.5DF071F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260603105814.10236-25-pbonzini@redhat.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] The `spte_permission_fault()` function indexes the statically-sized 16-element `mmu->fmt.permissions` array using the raw hardware page fault error code (`fault->error_code`), leading to an out-of-bounds kernel memory read and host kernel panic when higher-order error code bits are set by hardware (e.g., AMD RMP faults).
--

commit 18ca0883f7313fb2ea6fc90d61d35c33ed81ed22
Author: Paolo Bonzini <pbonzini@redhat.com>
Date:   Wed Jun 3 10:58:14 2026 +0000

    KVM: x86/mmu: use kvm_page_format to test SPTEs
    
This commit replaces the custom is_access_allowed() implementation with 
spte_permission_fault(). The new version leverages kvm_page_format to check
SPTEs against permissions, adding support for SMEP and paving the way for
TDP entries with differing XS and XU bits.

> diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h
> index 918533e61b983..9bddfa0e02b97 100644
> --- a/arch/x86/kvm/mmu/spte.h
> +++ b/arch/x86/kvm/mmu/spte.h

[ ... ]

> @@ -496,20 +485,35 @@ static inline bool is_mmu_writable_spte(u64 spte)
>  }
>  
>  /*
> - * Returns true if the access indicated by @fault is allowed by the existing
> - * SPTE protections.  Note, the caller is responsible for checking that the
> - * SPTE is a shadow-present, leaf SPTE (either before or after).
> + * Returns true if the access indicated by @fault is forbidden by the existing
> + * SPTE protections.
>   */
> -static inline bool is_access_allowed(struct kvm_page_fault *fault, u64 spte)
> -{
> -	if (fault->exec)
> -		return is_executable_pte(spte);
> -
> -	if (fault->write)
> -		return is_writable_pte(spte);
> -
> -	/* Fault was on Read access */
> -	return spte & PT_PRESENT_MASK;
> +static inline bool spte_permission_fault(struct kvm_mmu *mmu, u64 spte,
> +					 struct kvm_page_fault *fault)
> +{
> +	unsigned int pfec = fault->error_code;
> +	int index = pfec >> 1;
> +	int pte_access;
> +
> +	if (!is_shadow_present_pte(spte))
> +		return true;
> +
> +	BUILD_BUG_ON(PT_PRESENT_MASK != ACC_READ_MASK);
> +	BUILD_BUG_ON(PT_WRITABLE_MASK != ACC_WRITE_MASK);
> +	BUILD_BUG_ON(VMX_EPT_READABLE_MASK != ACC_READ_MASK);
> +	BUILD_BUG_ON(VMX_EPT_WRITABLE_MASK != ACC_WRITE_MASK);
> +
> +	/* strip nested paging fault error codes */
> +	pte_access = spte & (PT_PRESENT_MASK | PT_WRITABLE_MASK);
> +	if (shadow_nx_mask) {
> +		pte_access |= spte & shadow_user_mask ? ACC_USER_MASK : 0;
> +		pte_access |= spte & shadow_nx_mask ? 0 : ACC_EXEC_MASK;
> +	} else {
> +		pte_access |= spte & shadow_xs_mask ? ACC_EXEC_MASK : 0;
> +		pte_access |= spte & shadow_xu_mask ? ACC_USER_EXEC_MASK : 0;
> +	}
> +
> +	return (mmu->fmt.permissions[index] >> pte_access) & 1;

[Severity: Critical]
Could this lead to an out-of-bounds read if the hardware page fault error
code contains higher-order bits?

Looking at spte_permission_fault(), the raw fault->error_code is shifted
and used directly as an index into the mmu->fmt.permissions array. Since
this array only has 16 elements, an unmasked error code with higher bits
set could easily exceed the array bounds.

For example, if an AMD RMP fault sets bit 31 (PFERR_GUEST_RMP_MASK), the
index would be 1073741824, potentially causing a host kernel panic when
accessing mmu->fmt.permissions[index]. Even without SEV-SNP, a PKRU fault
(bit 5) under shadow paging results in an index of 16, which is also out
of bounds.

Should fault->error_code be masked before computing the index?

>  }
>  
>  /*

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260603105814.10236-1-pbonzini@redhat.com?part=24

      reply	other threads:[~2026-06-03 11:34 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-03 10:57 [PATCH 00/24] KVM: apply chainsaw to struct kvm_mmu Paolo Bonzini
2026-06-03 10:57 ` [PATCH 01/24] KVM: x86: remove nested_mmu from mmu_is_nested() Paolo Bonzini
2026-06-03 10:57 ` [PATCH 02/24] KVM: nVMX: remove unnecessary code in prepare_vmcs02_rare Paolo Bonzini
2026-06-03 10:57 ` [PATCH 03/24] KVM: nSVM: invalidate cached PDPTRs across nested NPT transitions Paolo Bonzini
2026-06-03 10:57 ` [PATCH 04/24] KVM: x86: check that kvm_handle_invpcid is only invoked with shadow paging Paolo Bonzini
2026-06-03 10:57 ` [PATCH 05/24] KVM: x86/mmu: move pdptrs out of the MMU Paolo Bonzini
2026-06-03 10:57 ` [PATCH 06/24] KVM: x86/hyperv: remove unnecessary mmu_is_nested() check Paolo Bonzini
2026-06-03 10:57 ` [PATCH 07/24] KVM: x86/mmu: introduce struct kvm_pagewalk Paolo Bonzini
2026-06-03 10:57 ` [PATCH 08/24] KVM: x86/mmu: move get_guest_pgd to " Paolo Bonzini
2026-06-03 10:57 ` [PATCH 09/24] KVM: x86/mmu: move gva_to_gpa " Paolo Bonzini
2026-06-03 10:58 ` [PATCH 10/24] KVM: x86/mmu: move get_pdptr " Paolo Bonzini
2026-06-03 10:58 ` [PATCH 11/24] KVM: x86/mmu: move inject_page_fault " Paolo Bonzini
2026-06-03 10:58 ` [PATCH 12/24] KVM: x86/mmu: move CPU-related fields " Paolo Bonzini
2026-06-03 11:27   ` sashiko-bot
2026-06-03 12:36     ` Paolo Bonzini
2026-06-03 10:58 ` [PATCH 13/24] KVM: x86/mmu: change CPU-role accessor fields to take " Paolo Bonzini
2026-06-03 10:58 ` [PATCH 14/24] KVM: x86/mmu: move remaining permission fields to " Paolo Bonzini
2026-06-03 10:58 ` [PATCH 15/24] KVM: x86/mmu: pass struct kvm_pagewalk to kvm_mmu_invalidate_addr Paolo Bonzini
2026-06-03 10:58 ` [PATCH 16/24] KVM: x86/mmu: change walk_mmu to struct kvm_pagewalk Paolo Bonzini
2026-06-03 10:58 ` [PATCH 17/24] KVM: x86/mmu: change nested_mmu.w to ngva_walk Paolo Bonzini
2026-06-03 10:58 ` [PATCH 18/24] KVM: x86/mmu: make gva_walk a value Paolo Bonzini
2026-06-03 11:24   ` sashiko-bot
2026-06-03 11:47     ` Paolo Bonzini
2026-06-03 10:58 ` [PATCH 19/24] KVM: x86/mmu: pull struct kvm_pagewalk out of struct kvm_mmu Paolo Bonzini
2026-06-03 10:58 ` [PATCH 20/24] KVM: x86/mmu: cleanup functions that initialize shadow MMU Paolo Bonzini
2026-06-03 10:58 ` [PATCH 21/24] KVM: x86/mmu: pull page format to a new struct Paolo Bonzini
2026-06-03 10:58 ` [PATCH 22/24] KVM: x86/mmu: merge struct rsvd_bits_validate into struct kvm_page_format Paolo Bonzini
2026-06-03 10:58 ` [PATCH 23/24] KVM: x86/mmu: parameterize update_permission_bitmask() Paolo Bonzini
2026-06-03 10:58 ` [PATCH 24/24] KVM: x86/mmu: use kvm_page_format to test SPTEs Paolo Bonzini
2026-06-03 11:34   ` sashiko-bot [this message]

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=20260603113402.5DF071F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --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