lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <dea526f077ece04e3ff60249bc0d7d9c0cf5e5f7.1675669136.git-series.apopple@nvidia.com>
Date:   Mon,  6 Feb 2023 18:47:52 +1100
From:   Alistair Popple <apopple@...dia.com>
To:     linux-mm@...ck.org, cgroups@...r.kernel.org
Cc:     linux-kernel@...r.kernel.org, jgg@...dia.com, jhubbard@...dia.com,
        tjmercier@...gle.com, hannes@...xchg.org, surenb@...gle.com,
        mkoutny@...e.com, daniel@...ll.ch,
        "Daniel P . Berrange" <berrange@...hat.com>,
        Alex Williamson <alex.williamson@...hat.com>,
        Alistair Popple <apopple@...dia.com>
Subject: [PATCH 15/19] mm/util: Extend vm_account to charge pages against the pin cgroup

The vm_account_pinned() functions currently only account pages against
pinned_vm/locked_vm and enforce limits against RLIMIT_MEMLOCK. Extend
these to account pages and enforce limits using the pin count cgroup.

Accounting of pages will fail if either RLIMIT_MEMLOCK or the cgroup
limit is exceeded. Unlike rlimit enforcement which can be bypassed if
the user has CAP_IPC_LOCK cgroup limits can not be bypassed.

Signed-off-by: Alistair Popple <apopple@...dia.com>
Cc: linux-kernel@...r.kernel.org
Cc: linux-mm@...ck.org
---
 include/linux/vm_account.h |  1 +
 mm/util.c                  | 26 ++++++++++++++++++++------
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/include/linux/vm_account.h b/include/linux/vm_account.h
index b4b2e90..4fd5d3a 100644
--- a/include/linux/vm_account.h
+++ b/include/linux/vm_account.h
@@ -31,6 +31,7 @@ struct vm_account {
 	struct task_struct *task;
 	struct mm_struct *mm;
 	struct user_struct *user;
+	struct pins_cgroup *pins_cg;
 	enum vm_account_flags flags;
 };
 
diff --git a/mm/util.c b/mm/util.c
index d8c19f8..0e93625 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -453,6 +453,7 @@ void vm_account_init(struct vm_account *vm_account, struct task_struct *task,
 
 	mmgrab(task->mm);
 	vm_account->mm = task->mm;
+	vm_account->pins_cg = get_pins_cg(task);
 	vm_account->flags = flags;
 }
 EXPORT_SYMBOL_GPL(vm_account_init);
@@ -472,6 +473,7 @@ void vm_account_release(struct vm_account *vm_account)
 		free_uid(vm_account->user);
 
 	mmdrop(vm_account->mm);
+	put_pins_cg(vm_account->pins_cg);
 }
 EXPORT_SYMBOL_GPL(vm_account_release);
 
@@ -502,6 +504,17 @@ static int vm_account_cmpxchg(struct vm_account *vm_account,
 	}
 }
 
+static void vm_unaccount_legacy(struct vm_account *vm_account,
+				unsigned long npages)
+{
+	if (vm_account->flags & VM_ACCOUNT_USER) {
+		atomic_long_sub(npages, &vm_account->user->locked_vm);
+		atomic64_sub(npages, &vm_account->mm->pinned_vm);
+	} else {
+		atomic64_sub(npages, &vm_account->mm->pinned_vm);
+	}
+}
+
 /**
  * vm_account_pinned - Charge pinned or locked memory to the vm_account.
  * @vm_account: pointer to an initialised vm_account.
@@ -537,6 +550,11 @@ int vm_account_pinned(struct vm_account *vm_account, unsigned long npages)
 	if (vm_account->flags & VM_ACCOUNT_USER)
 		atomic64_add(npages, &vm_account->mm->pinned_vm);
 
+	if (!pins_try_charge(vm_account->pins_cg, npages)) {
+		vm_unaccount_legacy(vm_account, npages);
+		return -ENOMEM;
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(vm_account_pinned);
@@ -548,12 +566,8 @@ EXPORT_SYMBOL_GPL(vm_account_pinned);
  */
 void vm_unaccount_pinned(struct vm_account *vm_account, unsigned long npages)
 {
-	if (vm_account->flags & VM_ACCOUNT_USER) {
-		atomic_long_sub(npages, &vm_account->user->locked_vm);
-		atomic64_sub(npages, &vm_account->mm->pinned_vm);
-	} else {
-		atomic64_sub(npages, &vm_account->mm->pinned_vm);
-	}
+	vm_unaccount_legacy(vm_account, npages);
+	pins_uncharge(vm_account->pins_cg, npages);
 }
 EXPORT_SYMBOL_GPL(vm_unaccount_pinned);
 
-- 
git-series 0.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ