Received: by 2002:ac2:5a04:0:0:0:0:0 with SMTP id q4csp109124lfn; Wed, 16 Feb 2022 19:49:06 -0800 (PST) X-Google-Smtp-Source: ABdhPJyGtEYwcCTZCV0mco7c/C+2L2i2+4Gb5jnup2MJI8LWQdbkJ5RolFP6mTmSLb45zoN+ggEh X-Received: by 2002:a17:906:d20a:b0:69e:cd43:bbd with SMTP id w10-20020a170906d20a00b0069ecd430bbdmr822912ejz.219.1645069746206; Wed, 16 Feb 2022 19:49:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1645069746; cv=none; d=google.com; s=arc-20160816; b=TgekBQkWFU4cA7YbipR++YSnUDVT4rOU4HQlgudtH9jwlxE8MnU7uyi0PvkzytXp9F ksl4O4tV5UJcBYcT5D+A/S3xULwA+oNaHhgp/5oWmv/FwTsCQr3RC9eVpwsdguRC4Hxe fqtHuYSCURLNnXJMtb1Es2rq0EQG97hk3xwqo2MOdR1FtA+GiTS4sI/xo13+xtXbSM6y ZC2uSOB1JhN31MXqevou4fqpR7PBTl6nVYML4CLhRd2ko8CKLSJq1wFiCzlHg+LfeV3U PrSJWq9wLUFjUszGPxfA/ReLhEnI3tboxKn51FNJl2u4d03LYzA9VelepYr0EPoX0eMe tlHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=5PITTj4P2Jzbs3luUpUKjcny+UqPegiMKBRLrd08cKM=; b=rT3rKD4mFXsR5TsdzZxqFfmQ6VTptegHC4LA1V4qnvozuVPv3sKBQTfkJ9tShWpKLG mWIYIuaEYiHcusNz+H28j9raMX1gutwBejWEMDgbzLPdnevDSmIcwEsNRupDXCyxk+tc 85q/WeFTGWezmdInJIsMRwWqEDw18YQtwG/f27azfVC36h+Za5vE7tlKe5uPy7pPmgJe saVVNOl3wYrZqXa16iry5e2wQQmBvB/B4A8I59XrKPM3RFwMujKXh0poBYc+SiQzMf9E 8RUc2YugRIwn/zHJvNEJtmDNeHm+aiCiY3XyZmaYOK/uC1yKXtf0T/3VhJU30eG/009I 2+eA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 7si1053502ejh.752.2022.02.16.19.48.43; Wed, 16 Feb 2022 19:49:06 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233585AbiBPRmr (ORCPT + 99 others); Wed, 16 Feb 2022 12:42:47 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:40412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237293AbiBPRmp (ORCPT ); Wed, 16 Feb 2022 12:42:45 -0500 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by lindbergh.monkeyblade.net (Postfix) with SMTP id AAA781598E7 for ; Wed, 16 Feb 2022 09:42:29 -0800 (PST) Received: (qmail 28379 invoked from network); 16 Feb 2022 17:42:27 -0000 Received: from localhost (HELO pvt.openwall.com) (127.0.0.1) by localhost with SMTP; 16 Feb 2022 17:42:27 -0000 Received: by pvt.openwall.com (Postfix, from userid 503) id B379BAB88C; Wed, 16 Feb 2022 18:42:20 +0100 (CET) Date: Wed, 16 Feb 2022 18:42:20 +0100 From: Solar Designer To: "Eric W. Biederman" Cc: linux-kernel@vger.kernel.org, Alexey Gladkov , Kees Cook , Shuah Khan , Christian Brauner , Ran Xiaokai , containers@lists.linux-foundation.org, Michal Koutn?? , linux-api@vger.kernel.org, stable@vger.kernel.org Subject: Re: [PATCH v2 1/5] rlimit: Fix RLIMIT_NPROC enforcement failure caused by capability calls in set_user Message-ID: <20220216174220.GA10389@openwall.com> References: <87ilteiz4a.fsf_-_@email.froward.int.ebiederm.org> <20220216155832.680775-1-ebiederm@xmission.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20220216155832.680775-1-ebiederm@xmission.com> User-Agent: Mutt/1.4.2.3i X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Feb 16, 2022 at 09:58:28AM -0600, Eric W. Biederman wrote: > Solar Designer wrote: > > I'm not aware of anyone actually running into this issue and reporting > > it. The systems that I personally know use suexec along with rlimits > > still run older/distro kernels, so would not yet be affected. > > > > So my mention was based on my understanding of how suexec works, and > > code review. Specifically, Apache httpd has the setting RLimitNPROC, > > which makes it set RLIMIT_NPROC: > > > > https://httpd.apache.org/docs/2.4/mod/core.html#rlimitnproc > > > > The above documentation for it includes: > > > > "This applies to processes forked from Apache httpd children servicing > > requests, not the Apache httpd children themselves. This includes CGI > > scripts and SSI exec commands, but not any processes forked from the > > Apache httpd parent, such as piped logs." > > > > In code, there are: > > > > ./modules/generators/mod_cgid.c: ( (cgid_req.limits.limit_nproc_set) && ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, > > ./modules/generators/mod_cgi.c: ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, > > ./modules/filters/mod_ext_filter.c: rv = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, conf->limit_nproc); > > > > For example, in mod_cgi.c this is in run_cgi_child(). > > > > I think this means an httpd child sets RLIMIT_NPROC shortly before it > > execs suexec, which is a SUID root program. suexec then switches to the > > target user and execs the CGI script. > > > > Before 2863643fb8b9, the setuid() in suexec would set the flag, and the > > target user's process count would be checked against RLIMIT_NPROC on > > execve(). After 2863643fb8b9, the setuid() in suexec wouldn't set the > > flag because setuid() is (naturally) called when the process is still > > running as root (thus, has those limits bypass capabilities), and > > accordingly execve() would not check the target user's process count > > against RLIMIT_NPROC. > > In commit 2863643fb8b9 ("set_user: add capability check when > rlimit(RLIMIT_NPROC) exceeds") capable calls were added to set_user to > make it more consistent with fork. Unfortunately because of call site > differences those capables calls were checking the credentials of the s/capables/capable/ > user before set*id() instead of after set*id(). > > This breaks enforcement of RLIMIT_NPROC for applications that set the > rlimit and then call set*id() while holding a full set of > capabilities. The capabilities are only changed in the new credential > in security_task_fix_setuid(). > > The code in apache suexec appears to follow this pattern. > > Commit 909cc4ae86f3 ("[PATCH] Fix two bugs with process limits > (RLIMIT_NPROC)") where this check was added describes the targes of this > capability check as: > > 2/ When a root-owned process (e.g. cgiwrap) sets up process limits and then > calls setuid, the setuid should fail if the user would then be running > more than rlim_cur[RLIMIT_NPROC] processes, but it doesn't. This patch > adds an appropriate test. With this patch, and per-user process limit > imposed in cgiwrap really works. > > So the original use case also of this check also appears to match the broken > pattern. Duplicate "also" - drop one. > Restore the enforcement of RLIMIT_NPROC by removing the bad capable > checks added in set_user. This unfortunately restores the > inconsistencies state the code has been in for the last 11 years, but s/inconsistencies/inconsistent/ > dealing with the inconsistencies looks like a larger problem. > > Cc: stable@vger.kernel.org > Link: https://lore.kernel.org/all/20210907213042.GA22626@openwall.com/ > Link: https://lkml.kernel.org/r/20220212221412.GA29214@openwall.com > Fixes: 2863643fb8b9 ("set_user: add capability check when rlimit(RLIMIT_NPROC) exceeds") > History-Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git > Signed-off-by: "Eric W. Biederman" > --- > kernel/sys.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/kernel/sys.c b/kernel/sys.c > index ecc4cf019242..8dd938a3d2bf 100644 > --- a/kernel/sys.c > +++ b/kernel/sys.c > @@ -480,8 +480,7 @@ static int set_user(struct cred *new) > * failure to the execve() stage. > */ > if (is_ucounts_overlimit(new->ucounts, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC)) && > - new_user != INIT_USER && > - !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) > + new_user != INIT_USER) > current->flags |= PF_NPROC_EXCEEDED; > else > current->flags &= ~PF_NPROC_EXCEEDED; Reviewed-by: Solar Designer Alexander