Commit c923a8e7 authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

ucounts: Move RLIMIT_NPROC handling after set_user

During set*id() which cred->ucounts to charge the the current process
to is not known until after set_cred_ucounts.  So move the
RLIMIT_NPROC checking into a new helper flag_nproc_exceeded and call
flag_nproc_exceeded after set_cred_ucounts.

This is very much an arbitrary subset of the places where we currently
change the RLIMIT_NPROC accounting, designed to preserve the existing
logic.

Fixing the existing logic will be the subject of another series of
changes.

Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/20220216155832.680775-4-ebiederm@xmission.com


Fixes: 21d1c5e3 ("Reimplement RLIMIT_NPROC on top of ucounts")
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent a55d0729
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -472,6 +472,16 @@ static int set_user(struct cred *new)
	if (!new_user)
		return -EAGAIN;

	free_uid(new->user);
	new->user = new_user;
	return 0;
}

static void flag_nproc_exceeded(struct cred *new)
{
	if (new->ucounts == current_ucounts())
		return;

	/*
	 * We don't fail in case of NPROC limit excess here because too many
	 * poorly written programs don't check set*uid() return code, assuming
@@ -480,14 +490,10 @@ 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)
			new->user != INIT_USER)
		current->flags |= PF_NPROC_EXCEEDED;
	else
		current->flags &= ~PF_NPROC_EXCEEDED;

	free_uid(new->user);
	new->user = new_user;
	return 0;
}

/*
@@ -562,6 +568,7 @@ long __sys_setreuid(uid_t ruid, uid_t euid)
	if (retval < 0)
		goto error;

	flag_nproc_exceeded(new);
	return commit_creds(new);

error:
@@ -624,6 +631,7 @@ long __sys_setuid(uid_t uid)
	if (retval < 0)
		goto error;

	flag_nproc_exceeded(new);
	return commit_creds(new);

error:
@@ -703,6 +711,7 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
	if (retval < 0)
		goto error;

	flag_nproc_exceeded(new);
	return commit_creds(new);

error: