Commit 00b21f70 authored by Mostafa Saleh's avatar Mostafa Saleh
Browse files

ANDROID: KVM: arm64: Fix UAF in pkvm_unmap_range



pkvm_unmap_range uses for_ppage_node_in_range to iterate over pinned
pages, then it erases the pin page with rb_erase.
However, for_ppage_node_in_range will use this pointer to get the
next node after the current node was freed.

This makes kfence screams on pVM teardown:

[  123.716319][  T192] BUG: KFENCE: use-after-free read in rb_next+0x0/0x50
[  123.716319][  T192]
[  123.717897][  T192] Use-after-free read at 0x00000000aa928570 (in kfence-#52):
[  123.718885][  T192]  rb_next+0x0/0x50
[  123.719585][  T192]  kvm_arch_flush_shadow_all+0x44/0x60
[  123.720428][  T192]  kvm_mmu_notifier_release+0x34/0x70
[  123.721333][  T192]  __mmu_notifier_release+0x80/0x1ec
[  123.722219][  T192]  exit_mmap+0x39c/0x3c0
[  123.722978][  T192]  __mmput+0x34/0x17c
[  123.723693][  T192]  mmput+0x54/0x64
[  123.724328][  T192]  do_exit+0x2c0/0xa54
[  123.725000][  T192]  do_group_exit+0x38/0x94
[  123.726027][  T192]  get_signal+0x9bc/0x9cc
[  123.726730][  T192]  do_notify_resume+0x1c0/0xa00
[  123.727479][  T192]  el0_svc+0x11c/0x120
[  123.728141][  T192]  el0t_64_sync_handler+0x128/0x134
[  123.728898][  T192]  el0t_64_sync+0x1a8/0x1ac
[  123.730018][  T192]
[  123.730436][  T192] kfence-#52: 0x00000000aa928570-0x00000000aedc398c, size=40, cache=kmalloc-cg-64
[  123.730436][  T192]
[  123.731795][  T192] allocated by task 202 on cpu 0 at 51.087078s:
[  123.732971][  T192]  __kmem_cache_alloc_node+0x1f0/0x2bc
[  123.734008][  T192]  kmalloc_trace+0x44/0x138
[  123.734695][  T192]  kvm_handle_guest_abort+0x3fc/0x106c
[  123.735484][  T192]  handle_exit+0xa8/0x2c4
[  123.736158][  T192]  kvm_arch_vcpu_ioctl_run+0x204/0x8c8
[  123.736934][  T192]  kvm_vcpu_ioctl+0x1c4/0x760
[  123.737989][  T192]  __arm64_sys_ioctl+0xb4/0xfc
[  123.738705][  T192]  invoke_syscall+0x4c/0x11c
[  123.739409][  T192]  el0_svc_common.constprop.0+0x44/0xec
[  123.740189][  T192]  do_el0_svc+0x20/0x30
[  123.740843][  T192]  el0_svc+0x44/0x120
[  123.741726][  T192]  el0t_64_sync_handler+0x128/0x134
[  123.742479][  T192]  el0t_64_sync+0x1a8/0x1ac
[  123.743174][  T192]
[  123.743609][  T192] freed by task 192 on cpu 3 at 123.714463s:
[  123.744558][  T192]  __unmap_stage2_range.isra.0+0x1b0/0x1ec
[  123.745736][  T192]  kvm_arch_flush_shadow_all+0x44/0x60
[  123.746520][  T192]  kvm_mmu_notifier_release+0x34/0x70
[  123.747303][  T192]  __mmu_notifier_release+0x80/0x1ec
[  123.748068][  T192]  exit_mmap+0x39c/0x3c0
[  123.748727][  T192]  __mmput+0x34/0x17c
[  123.749637][  T192]  mmput+0x54/0x64
[  123.750246][  T192]  do_exit+0x2c0/0xa54
[  123.750887][  T192]  do_group_exit+0x38/0x94
[  123.751572][  T192]  get_signal+0x9bc/0x9cc
[  123.752233][  T192]  do_notify_resume+0x1c0/0xa00
[  123.752946][  T192]  el0_svc+0x11c/0x120
[  123.753852][  T192]  el0t_64_sync_handler+0x128/0x134
[  123.754609][  T192]  el0t_64_sync+0x1a8/0x1ac
[  123.755303][  T192]
[  123.755717][  T192] CPU: 3 PID: 192 Comm: ioeventfd-worke Tainted: G    B              6.6.17mostafa+ #12
[  123.756957][  T192] Hardware name: linux,dummy-virt (DT)
[  123.758007][  T192] ==================================================================

To fix that, we use a temp variable to hold the next entry before
getting into the loop.

Bug: 278749606

Change-Id: Ibb7907c3bbe53a4643ad5f945888529938bd063d
Signed-off-by: default avatarMostafa Saleh <smostafa@google.com>
parent 9fb9c28f
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment