All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <christian.brauner@ubuntu.com>
To: CGEL <cgel.zte@gmail.com>
Cc: peterz@infradead.org, tglx@linutronix.de,
	linux-kernel@vger.kernel.org,
	Ran Xiaokai <ran.xiaokai@zte.com.cn>,
	James Morris <jamorris@linux.microsoft.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Kees Cook <keescook@chromium.org>, NeilBrown <neilb@suse.de>
Subject: Re: [PATCH] set_user: add capability check when rlimit(RLIMIT_NPROC) exceeds
Date: Tue, 3 Aug 2021 16:07:02 +0200	[thread overview]
Message-ID: <20210803140702.f3rdnka3e2x6vj4r@wittgenstein> (raw)
In-Reply-To: <20210803100354.GA607722@www>

On Tue, Aug 03, 2021 at 03:03:54AM -0700, CGEL wrote:
> On Fri, Jul 30, 2021 at 01:23:31AM -0700, CGEL wrote:
> > On Wed, Jul 28, 2021 at 01:59:30PM +0200, Christian Brauner wrote:
> > > [Ccing a few people that did the PF_NPROC_EXCEEDED changes]
> > > 
> > > 
> > > Hey Cgel,
> > > Hey Ran,
> > > 
> > > The gist seems to me that this code wants to make sure that a program
> > > can't successfully exec if it has gone through a set*id() transition
> > > while exceeding its RLIMIT_NPROC.
> > > 
> > > But I agree that the semantics here are a bit strange.
> > > 
> > > Iicu, a capable but non-INIT_USER caller getting PF_NPROC_EXCEEDED set
> > > during a set*id() transition wouldn't be able to exec right away if they
> > > still exceed their RLIMIT_NPROC at the time of exec. So their exec would
> > > fail in fs/exec.c:
> > > 
> > > 	if ((current->flags & PF_NPROC_EXCEEDED) &&
> > > 	    is_ucounts_overlimit(current_ucounts(), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) {
> > > 		retval = -EAGAIN;
> > > 		goto out_ret;
> > > 	}
> > > 
> > > However, if the caller were to fork() right after the set*id()
> > > transition but before the exec while still exceeding their RLIMIT_NPROC
> > > then they would get PF_NPROC_EXCEEDED cleared (while the child would
> > > inherit it):
> > > 
> > > 	retval = -EAGAIN;
> > > 	if (is_ucounts_overlimit(task_ucounts(p), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) {
> > > 		if (p->real_cred->user != INIT_USER &&
> > > 		    !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN))
> > > 			goto bad_fork_free;
> > > 	}
> > > 	current->flags &= ~PF_NPROC_EXCEEDED;
> > > 
> > > which means a subsequent exec by the capable caller would now succeed
> > > even though they could still exceed their RLIMIT_NPROC limit.
> > > 
> > > So at first glance, it seems that set_user() should probably get the
> > > same check as it can be circumvented today unless I misunderstand the
> > > original motivation.
> > > 
> > > Christian
> > 
> > Hi Christian,
> > 
> > I think i didn't give enough information in the commit message.
> > When switch to a capable but non-INIT_SUER and the RLIMIT_NPROC limit already exceeded,
> > and calls these funcs:
> > 1. set_xxuid()->exec() 
> >              ---> fail
> > 2. set_xxuid()->fork()->exec()
> >              ---> success
> > Kernel should have the same behavior to uer space.
> > Also i think non init_user CAN exceed the limit when with proper capability,
> > so in the patch, set_user() clear PF_NPROC_EXCEEDED flag if capable()
> > returns true.
> 
> Hi, Christian
> 
> Do you have any further comments on this patch?
> is there anything i did not give enough infomation ?

Yeah, this is fine and how I understood it too. I don't see anything
obviously wrong with it and the weird detour workaround via fork() seems
inconsistent. So if I don't here anyone come up with a good reason the
current behavior makes sense I'll pick this up.

Christian

  reply	other threads:[~2021-08-03 14:07 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-28  7:26 [PATCH] set_user: add capability check when rlimit(RLIMIT_NPROC) exceeds cgel.zte
2021-07-28 11:59 ` Christian Brauner
2021-07-30  8:23   ` CGEL
2021-08-03 10:03     ` CGEL
2021-08-03 14:07       ` Christian Brauner [this message]
2021-09-07 21:30         ` Solar Designer
2021-09-08 10:24           ` Solar Designer
2021-09-13 10:01             ` Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210803140702.f3rdnka3e2x6vj4r@wittgenstein \
    --to=christian.brauner@ubuntu.com \
    --cc=cgel.zte@gmail.com \
    --cc=jamorris@linux.microsoft.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=neilb@suse.de \
    --cc=peterz@infradead.org \
    --cc=ran.xiaokai@zte.com.cn \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.