From nobody Wed Jul 1 09:54:44 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7413C433EF for ; Thu, 23 Dec 2021 20:00:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245166AbhLWUAA (ORCPT ); Thu, 23 Dec 2021 15:00:00 -0500 Received: from out02.mta.xmission.com ([166.70.13.232]:50748 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244949AbhLWT76 (ORCPT ); Thu, 23 Dec 2021 14:59:58 -0500 Received: from in01.mta.xmission.com ([166.70.13.51]:47638) by out02.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n0UFp-009TeO-MD; Thu, 23 Dec 2021 12:59:57 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:58712 helo=email.froward.int.ebiederm.org.xmission.com) by in01.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n0UFo-008ZE1-HM; Thu, 23 Dec 2021 12:59:57 -0700 From: ebiederm@xmission.com (Eric W. Biederman) To: Linus Torvalds Cc: Alexey Gladkov , , Linux Containers User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) Date: Thu, 23 Dec 2021 13:59:49 -0600 Message-ID: <87o857t7m2.fsf@email.froward.int.ebiederm.org> MIME-Version: 1.0 X-XM-SPF: eid=1n0UFo-008ZE1-HM;;;mid=<87o857t7m2.fsf@email.froward.int.ebiederm.org>;;;hst=in01.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1+aAthlIBm9kU5qZSimccXbh7/1NOk6y0A= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [GIT PULL] ucount fix for v5.16-rc7 X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in01.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Linus, Please pull the ucount-rlimit-fixes-for-v5.16 branch from the git tree: git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git= ucount-rlimit-fixes-for-v5.16 HEAD: 59ec71575ab440cd5ca0aa53b2a2985b3639fad4 ucounts: Fix rlimit max va= lues check This fixes a silly logic bug in the ucount rlimits code, where it was comparing against the wrong limit. As the fix is quite small it is included in it's entirety below. Resent because I left off the subject line last time. Eric From 59ec71575ab440cd5ca0aa53b2a2985b3639fad4 Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Mon, 29 Nov 2021 21:37:25 +0100 Subject: [PATCH] ucounts: Fix rlimit max values check The semantics of the rlimit max values differs from ucounts itself. When creating a new userns, we store the current rlimit of the process in ucount_max. Thus, the value of the limit in the parent userns is saved in the created one. The problem is that now we are taking the maximum value for counter from the same userns. So for init_user_ns it will always be RLIM_INFINITY. To fix the problem we need to check the counter value with the max value stored in userns. Reproducer: su - test -c "ulimit -u 3; sleep 5 & sleep 6 & unshare -U --map-root-user s= h -c 'sleep 7 & sleep 8 & date; wait'" Before: [1] 175 [2] 176 Fri Nov 26 13:48:20 UTC 2021 [1]- Done sleep 5 [2]+ Done sleep 6 After: [1] 167 [2] 168 sh: fork: retry: Resource temporarily unavailable sh: fork: retry: Resource temporarily unavailable sh: fork: retry: Resource temporarily unavailable sh: fork: retry: Resource temporarily unavailable sh: fork: retry: Resource temporarily unavailable sh: fork: retry: Resource temporarily unavailable sh: fork: retry: Resource temporarily unavailable sh: fork: Interrupted system call [1]- Done sleep 5 [2]+ Done sleep 6 Fixes: c54b245d0118 ("Merge branch 'for-linus' of git://git.kernel.org/pub/= scm/linux/kernel/git/ebiederm/user-namespace") Reported-by: Gleb Fotengauer-Malinovskiy Signed-off-by: "Eric W. Biederman" Signed-off-by: Alexey Gladkov Link: https://lkml.kernel.org/r/024ec805f6e16896f0b23e094773790d171d2c1c.16= 38218242.git.legion@kernel.org Signed-off-by: Eric W. Biederman --- kernel/ucount.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/ucount.c b/kernel/ucount.c index 4f5613dac227..7b32c356ebc5 100644 --- a/kernel/ucount.c +++ b/kernel/ucount.c @@ -264,15 +264,16 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_= type type) long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, lo= ng v) { struct ucounts *iter; + long max =3D LONG_MAX; long ret =3D 0; =20 for (iter =3D ucounts; iter; iter =3D iter->ns->ucounts) { - long max =3D READ_ONCE(iter->ns->ucount_max[type]); long new =3D atomic_long_add_return(v, &iter->ucount[type]); if (new < 0 || new > max) ret =3D LONG_MAX; else if (iter =3D=3D ucounts) ret =3D new; + max =3D READ_ONCE(iter->ns->ucount_max[type]); } return ret; } @@ -312,15 +313,16 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, = enum ucount_type type) { /* Caller must hold a reference to ucounts */ struct ucounts *iter; + long max =3D LONG_MAX; long dec, ret =3D 0; =20 for (iter =3D ucounts; iter; iter =3D iter->ns->ucounts) { - long max =3D READ_ONCE(iter->ns->ucount_max[type]); long new =3D atomic_long_add_return(1, &iter->ucount[type]); if (new < 0 || new > max) goto unwind; if (iter =3D=3D ucounts) ret =3D new; + max =3D READ_ONCE(iter->ns->ucount_max[type]); /* * Grab an extra ucount reference for the caller when * the rlimit count was previously 0. @@ -339,15 +341,16 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, = enum ucount_type type) return 0; } =20 -bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, = unsigned long max) +bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, = unsigned long rlimit) { struct ucounts *iter; - if (get_ucounts_value(ucounts, type) > max) - return true; + long max =3D rlimit; + if (rlimit > LONG_MAX) + max =3D LONG_MAX; for (iter =3D ucounts; iter; iter =3D iter->ns->ucounts) { - max =3D READ_ONCE(iter->ns->ucount_max[type]); if (get_ucounts_value(iter, type) > max) return true; + max =3D READ_ONCE(iter->ns->ucount_max[type]); } return false; } --=20 2.29.2