Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 4697322

Browse files
Quentin PerretTreehugger Robot
authored andcommitted
BACKPORT: FROMLIST: KVM: arm64: Always check the state from hyp_ack_unshare()
There are multiple pKVM memory transitions where the state of a page is not cross-checked from the completer's PoV for performance reasons. For example, if a page is PKVM_PAGE_OWNED from the initiator's PoV, we should be guaranteed by construction that it is PKVM_NOPAGE for everybody else, hence allowing us to save a page-table lookup. When it was introduced, hyp_ack_unshare() followed that logic and bailed out without checking the PKVM_PAGE_SHARED_BORROWED state in the hypervisor's stage-1. This was correct as we could safely assume that all host-initiated shares were directed at the hypervisor at the time. But with the introduction of other types of shares (e.g. for FF-A or non-protected guests), it is now very much required to cross check this state to prevent the host from running __pkvm_host_unshare_hyp() on a page shared with TZ or a non-protected guest. Thankfully, if an attacker were to try this, the hyp_unmap() call from hyp_complete_unshare() would fail, hence causing to WARN() from __do_unshare() with the host lock held, which is fatal. But this is fragile at best, and can hardly be considered a security measure. Let's just do the right thing and always check the state from hyp_ack_unshare(). BACKPORT: Minor conflict with checked_tx logic. Bug: 381409114 Link: https://lore.kernel.org/kvmarm/[email protected]/ Change-Id: Id3bbd1fc3c75df506b0919f4d6f7be74b6f013f3 Signed-off-by: Quentin Perret <[email protected]>
1 parent dc8cab1 commit 4697322

File tree

1 file changed

+0
-4
lines changed

1 file changed

+0
-4
lines changed

arch/arm64/kvm/hyp/nvhe/mem_protect.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,13 +1325,9 @@ static int hyp_ack_share(const struct pkvm_checked_mem_transition *checked_tx,
13251325

13261326
static int hyp_ack_unshare(const struct pkvm_checked_mem_transition *checked_tx)
13271327
{
1328-
const struct pkvm_mem_transition *tx = checked_tx->tx;
13291328
u64 size = checked_tx->nr_pages * PAGE_SIZE;
13301329
u64 addr = checked_tx->completer_addr;
13311330

1332-
if (__hyp_ack_skip_pgtable_check(tx))
1333-
return 0;
1334-
13351331
return __hyp_check_page_state_range(addr, size,
13361332
PKVM_PAGE_SHARED_BORROWED);
13371333
}

0 commit comments

Comments
 (0)