[Devel] [PATCH RH8 2/6] memcg: accounting for ldt_struct objects

Vasily Averin vvs at virtuozzo.com
Mon Apr 12 13:26:24 MSK 2021


Unprivileged user inside memcg-limited container can create
non-accounted multi-page kernel objects for LDT.

Upper limit per mm:
/* Maximum number of LDT entries supported. */
define LDT_ENTRIES     8192
/* The size of each LDT entry. */
define LDT_ENTRY_SIZE  8

8192 * 8 = 64kB * number_of_tasks
so realistically this is in range of lower megabytes.

There are legitimate workloads with hundreds of processes and there
can be hundreds of workloads running on large machines. The
unaccounted memory can cause isolation issues between the workloads
particularly on highly utilized machines.

https://jira.sw.ru/browse/PSBM-120694
Signed-off-by: Vasily Averin <vvs at virtuozzo.com>
---
 arch/x86/kernel/ldt.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index e921b3d494d5..9edf5d442c1d 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -70,7 +70,7 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
 	if (num_entries > LDT_ENTRIES)
 		return NULL;
 
-	new_ldt = kmalloc(sizeof(struct ldt_struct), GFP_KERNEL);
+	new_ldt = kmalloc(sizeof(struct ldt_struct), GFP_KERNEL_ACCOUNT);
 	if (!new_ldt)
 		return NULL;
 
@@ -84,9 +84,9 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
 	 * than PAGE_SIZE.
 	 */
 	if (alloc_size > PAGE_SIZE)
-		new_ldt->entries = vzalloc(alloc_size);
+		new_ldt->entries = vzalloc_account(alloc_size);
 	else
-		new_ldt->entries = (void *)get_zeroed_page(GFP_KERNEL);
+		new_ldt->entries = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT);
 
 	if (!new_ldt->entries) {
 		kfree(new_ldt);
-- 
2.25.1



More information about the Devel mailing list