kernel/cred.c | 9 ++------- kernel/fork.c | 10 +++++----- kernel/sys.c | 20 ++++++++++++++------ kernel/ucount.c | 3 ++- 4 files changed, 23 insertions(+), 19 deletions(-)
Michal Koutný recently found some bugs in the enforcement of
RLIMIT_NPROC in the recent ucount rlimit implementation.
I saw some additional bugs and some cleaner ways to fix the problem so
instead of starting with his fixes these are my own.
I have rewritten about half my fixes since the last time this was
posted. There is this notion (not entirely wrong) that the code should
be consistent and make sense. When I dug in I discovered that has not
been the case for the last 20 years. Fixing the long standing
inconsistencies is something that seems to warrent wider vetting on
linux-api.
So with this set of patches I have developed a very conservative
approach changing only what is necessary to fix the bugs that I can
see clearly. Cleanups and anything that is making the code more
consistent can follow after we have the code working as it has
historically.
Anyone who can please take a look and tell me if I am doing something silly.
Eric W. Biederman (5):
rlimit: Fix RLIMIT_NPROC enforcement failure caused by capability calls in set_user
ucounts: Enforce RLIMIT_NPROC not RLIMIT_NPROC+1
ucounts: Base set_cred_ucounts changes on the real user
ucounts: Move RLIMIT_NPROC handling after set_user
ucounts: Handle wrapping in is_ucounts_overlimit
kernel/cred.c | 9 ++-------
kernel/fork.c | 10 +++++-----
kernel/sys.c | 20 ++++++++++++++------
kernel/ucount.c | 3 ++-
4 files changed, 23 insertions(+), 19 deletions(-)
Eric
Linus,
Please pull the ucount-rlimit-fixes-for-v5.17 branch from the git tree:
git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git ucount-rlimit-fixes-for-v5.17
HEAD: 0cbae9e24fa7d6c6e9f828562f084da82217a0c5 ucounts: Handle wrapping in is_ucounts_overlimit
Michal Koutný recently found some bugs in the enforcement of
RLIMIT_NPROC in the recent ucount rlimit implementation.
I saw some additional bugs and some cleaner ways to fix the problem so
instead of starting with his fixes these are my own.
I have rewritten about half my fixes since the last time this was
posted. There is this notion (not entirely wrong) that the code should
be consistent and make sense. When I dug in I discovered that has not
been the case for the last 20 years. Fixing the long standing
inconsistencies is something that seems to warrent wider vetting on
linux-api.
So with this set of patches I have developed a very conservative
approach changing only what is necessary to fix the bugs that I can
see clearly. Cleanups and anything that is making the code more
consistent can follow after we have the code working as it has
historically.
I had hoped to let this sit in linux-next for a few days just to be
doubly certain all is well. But these patches are all trivial and
linux-next is on holiday.
v2: https://lkml.kernel.org/r/87ilteiz4a.fsf_-_@email.froward.int.ebiederm.org>
v1: https://lkml.kernel.org/r/87o83e2mbu.fsf@email.froward.int.ebiederm.org>
Eric W. Biederman (5):
rlimit: Fix RLIMIT_NPROC enforcement failure caused by capability calls in set_user
ucounts: Enforce RLIMIT_NPROC not RLIMIT_NPROC+1
ucounts: Base set_cred_ucounts changes on the real user
ucounts: Move RLIMIT_NPROC handling after set_user
ucounts: Handle wrapping in is_ucounts_overlimit
kernel/cred.c | 9 ++-------
kernel/fork.c | 10 +++++-----
kernel/sys.c | 20 ++++++++++++++------
kernel/ucount.c | 3 ++-
4 files changed, 23 insertions(+), 19 deletions(-)
p.s. I should say that the problem is not so much inconsistencies
(although those exist) but that it is very difficult to figure out what
the code should be doing in the case of RLIMIT_NPROC.
All other rlimits are only enforced where the resource is acquired
(allocated). RLIMIT_NPROC by necessity needs to be enforced in
an additional location, and our current implementation stumbled
it's way into that implementation.
Eric
The pull request you sent on Fri, 18 Feb 2022 09:34:24 -0600: > git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git ucount-rlimit-fixes-for-v5.17 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/2d3409ebc87f4bc4ed23bd39e78db9ffc29eec44 Thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/prtracker.html
Linus,
Please pull the ucount-rlimit-fixes-for-v5.17 branch from the git tree:
git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git ucount-rlimit-fixes-for-v5.17
HEAD: 0ac983f512033cb7b5e210c9589768ad25b1e36b ucounts: Fix systemd LimitNPROC with private users regression
Etienne Dechamps recently found a regression caused by enforcing
RLIMIT_NPROC for root where the rlimit was not previously enforced.
Michal Koutný had previously pointed out the inconsistency in enforcing
the RLIMIT_NPROC that had been on the root owned process after the root
user creates a user namespace.
Which makes the fix for the regression simply removing the
inconsistency.
From: "Eric W. Biederman" <ebiederm@xmission.com>
Date: Thu, 24 Feb 2022 08:32:28 -0600
Subject: [PATCH] ucounts: Fix systemd LimitNPROC with private users regression
Long story short recursively enforcing RLIMIT_NPROC when it is not
enforced on the process that creates a new user namespace, causes
currently working code to fail. There is no reason to enforce
RLIMIT_NPROC recursively when we don't enforce it normally so update
the code to detect this case.
I would like to simply use capable(CAP_SYS_RESOURCE) to detect when
RLIMIT_NPROC is not enforced upon the caller. Unfortunately because
RLIMIT_NPROC is charged and checked for enforcement based upon the
real uid, using capable() which is euid based is inconsistent with reality.
Come as close as possible to testing for capable(CAP_SYS_RESOURCE) by
testing for when the real uid would match the conditions when
CAP_SYS_RESOURCE would be present if the real uid was the effective
uid.
Reported-by: Etienne Dechamps <etienne@edechamps.fr>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215596
Link: https://lkml.kernel.org/r/e9589141-cfeb-90cd-2d0e-83a62787239a@edechamps.fr
Link: https://lkml.kernel.org/r/87sfs8jmpz.fsf_-_@email.froward.int.ebiederm.org
Cc: stable@vger.kernel.org
Fixes: 21d1c5e386bc ("Reimplement RLIMIT_NPROC on top of ucounts")
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
kernel/user_namespace.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 6b2e3ca7ee99..5481ba44a8d6 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -58,6 +58,18 @@ static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
cred->user_ns = user_ns;
}
+static unsigned long enforced_nproc_rlimit(void)
+{
+ unsigned long limit = RLIM_INFINITY;
+
+ /* Is RLIMIT_NPROC currently enforced? */
+ if (!uid_eq(current_uid(), GLOBAL_ROOT_UID) ||
+ (current_user_ns() != &init_user_ns))
+ limit = rlimit(RLIMIT_NPROC);
+
+ return limit;
+}
+
/*
* Create a new user namespace, deriving the creator from the user in the
* passed credentials, and replacing that user with the new root user for the
@@ -122,7 +134,7 @@ int create_user_ns(struct cred *new)
for (i = 0; i < MAX_PER_NAMESPACE_UCOUNTS; i++) {
ns->ucount_max[i] = INT_MAX;
}
- set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC));
+ set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_NPROC, enforced_nproc_rlimit());
set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_MSGQUEUE, rlimit(RLIMIT_MSGQUEUE));
set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_SIGPENDING, rlimit(RLIMIT_SIGPENDING));
set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_MEMLOCK, rlimit(RLIMIT_MEMLOCK));
--
2.29.2
The pull request you sent on Wed, 02 Mar 2022 18:12:40 -0600: > git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git ucount-rlimit-fixes-for-v5.17 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/5859a2b1991101d6b978f3feb5325dad39421f29 Thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/prtracker.html
© 2016 - 2026 Red Hat, Inc.