Guest effectable page reference leak

An error handling path in the processing of MMU_MACHPHYS_UPDATE failed to drop a page reference which was acquired in an earlier processing step.

page的reference counting error,导致DoS攻击。

在处理MMU_MACHPHYS_UPDATE的hypercall的时候,对于一个translated guest (HVM),执行流是这样的:


在page_get_owner_and_reference会对page->count_info进行加一操作,但是最后发现其是HVM,则会返回错误码,但是没有对reference counter进行减一, 导致page的reference counter出错。


If a reference is erroneously taken, the domain can never be properly cleaned up. Repeating this across many domains will run through system memory.

An alternative would be to leak 232 refs on the same page, at which point the integer overflows and Xen will hit a BUG() check and crash.

improper error handling (fail to drop page reference)



fix a reference counting error in MMU_MACHPHYS_UPDATE

Any domain which can pass the XSM check against a translated guest can cause a page reference to be leaked.

While shuffling the order of checks, drop the quite pointless MEM_LOG(). This brings the check in line with similar checks in the vicinity.

Discovered while reviewing the XSA-109/110 followup series.

--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -3619,6 +3619,12 @@ long do_mmu_update(
         case MMU_MACHPHYS_UPDATE:
+            if ( unlikely(paging_mode_translate(pg_owner)) )
+            {
+                rc = -EINVAL;
+                break;
+            }
             mfn = req.ptr >> PAGE_SHIFT;
             gpfn = req.val;
@@ -3638,13 +3644,6 @@ long do_mmu_update(
-            if ( unlikely(paging_mode_translate(pg_owner)) )
-            {
-                MEM_LOG("Mach-phys update on auto-translate guest");
-                rc = -EINVAL;
-                break;
-            }
             set_gpfn_from_mfn(mfn, gpfn);
             paging_mark_dirty(pg_owner, mfn);


Malicious or buggy stub domain kernels or tool stacks otherwise living outside of Domain0 can mount a denial of service attack which, if successful, can affect the whole system.