A non-empty CPU page pool always allocates pages even when
vm_page_alloc_paused is set. An unprivileged thread can therefore
acquire a signicant number of pages until the pool is empty. The cycle
can continue for a longer period if the pool is replenished by a VM
privileged thread before the unprivileged thread requests more pages
and in extreme cases can result in complete system memory exhaustion.
---
 vm/vm_page.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/vm/vm_page.c b/vm/vm_page.c
index 47eeb042..5cdf0c7b 100644
--- a/vm/vm_page.c
+++ b/vm/vm_page.c
@@ -687,6 +687,11 @@ vm_page_seg_alloc(struct vm_page_seg *seg, unsigned int 
order,
     assert(order < VM_PAGE_NR_FREE_LISTS);
 
     if (order == 0) {
+
+        if (vm_page_alloc_paused && current_thread()
+           && !current_thread()->vm_privilege)
+         return NULL;
+
         thread_pin();
         cpu_pool = vm_page_cpu_pool_get(seg);
         simple_lock(&cpu_pool->lock);
-- 
2.47.3


Reply via email to