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