linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Serge E. Hallyn" <serge@hallyn.com>
To: "Serge E. Hallyn" <serge@hallyn.com>
Cc: LSM <linux-security-module@vger.kernel.org>,
	James Morris <jmorris@namei.org>,
	Kees Cook <kees.cook@canonical.com>,
	containers@lists.linux-foundation.org,
	kernel list <linux-kernel@vger.kernel.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Alexey Dobriyan <adobriyan@gmail.com>,
	Michael Kerrisk <mtk.manpages@gmail.com>
Subject: [PATCH 6/7] user namespaces: convert all capable checks in kernel/sys.c
Date: Mon, 10 Jan 2011 21:14:07 +0000	[thread overview]
Message-ID: <20110110211406.GF22564@mail.hallyn.com> (raw)
In-Reply-To: <20110110211135.GA22446@mail.hallyn.com>

This allows setuid/setgid in containers.  It also fixes some
corner cases where kernel logic foregoes capability checks when
uids are equivalent.  The latter will need to be done throughout
the whole kernel.

Signed-off-by: Serge E. Hallyn <serge.hallyn@canonical.com>
---
 kernel/sys.c |   35 ++++++++++++++++++++---------------
 1 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/kernel/sys.c b/kernel/sys.c
index 9b9b03b..2278e87 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -125,8 +125,10 @@ static int set_one_prio(struct task_struct *p, int niceval, int error)
 	const struct cred *cred = current_cred(), *pcred = __task_cred(p);
 	int no_nice;
 
-	if (pcred->uid  != cred->euid &&
-	    pcred->euid != cred->euid && !capable(CAP_SYS_NICE)) {
+	if (pcred->user->user_ns != cred->user->user_ns &&
+	    pcred->uid  != cred->euid &&
+	    pcred->euid != cred->euid &&
+	    !ns_capable(pcred->user->user_ns, CAP_SYS_NICE)) {
 		error = -EPERM;
 		goto out;
 	}
@@ -496,7 +498,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
 	if (rgid != (gid_t) -1) {
 		if (old->gid == rgid ||
 		    old->egid == rgid ||
-		    capable(CAP_SETGID))
+		    ns_capable(current_user_ns(), CAP_SETGID))
 			new->gid = rgid;
 		else
 			goto error;
@@ -505,7 +507,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
 		if (old->gid == egid ||
 		    old->egid == egid ||
 		    old->sgid == egid ||
-		    capable(CAP_SETGID))
+		    ns_capable(current_user_ns(), CAP_SETGID))
 			new->egid = egid;
 		else
 			goto error;
@@ -540,7 +542,7 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
 	old = current_cred();
 
 	retval = -EPERM;
-	if (capable(CAP_SETGID))
+	if (ns_capable(current_user_ns(), CAP_SETGID))
 		new->gid = new->egid = new->sgid = new->fsgid = gid;
 	else if (gid == old->gid || gid == old->sgid)
 		new->egid = new->fsgid = gid;
@@ -607,7 +609,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
 		new->uid = ruid;
 		if (old->uid != ruid &&
 		    old->euid != ruid &&
-		    !capable(CAP_SETUID))
+		    !ns_capable(current_user_ns(), CAP_SETUID))
 			goto error;
 	}
 
@@ -616,7 +618,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
 		if (old->uid != euid &&
 		    old->euid != euid &&
 		    old->suid != euid &&
-		    !capable(CAP_SETUID))
+		    !ns_capable(current_user_ns(), CAP_SETUID))
 			goto error;
 	}
 
@@ -664,7 +666,7 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
 	old = current_cred();
 
 	retval = -EPERM;
-	if (capable(CAP_SETUID)) {
+	if (ns_capable(current_user_ns(), CAP_SETUID)) {
 		new->suid = new->uid = uid;
 		if (uid != old->uid) {
 			retval = set_user(new);
@@ -706,7 +708,7 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
 	old = current_cred();
 
 	retval = -EPERM;
-	if (!capable(CAP_SETUID)) {
+	if (!ns_capable(current_user_ns(), CAP_SETUID)) {
 		if (ruid != (uid_t) -1 && ruid != old->uid &&
 		    ruid != old->euid  && ruid != old->suid)
 			goto error;
@@ -770,7 +772,7 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
 	old = current_cred();
 
 	retval = -EPERM;
-	if (!capable(CAP_SETGID)) {
+	if (!ns_capable(current_user_ns(), CAP_SETGID)) {
 		if (rgid != (gid_t) -1 && rgid != old->gid &&
 		    rgid != old->egid  && rgid != old->sgid)
 			goto error;
@@ -830,7 +832,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
 
 	if (uid == old->uid  || uid == old->euid  ||
 	    uid == old->suid || uid == old->fsuid ||
-	    capable(CAP_SETUID)) {
+	    ns_capable(current_user_ns(), CAP_SETUID)) {
 		if (uid != old_fsuid) {
 			new->fsuid = uid;
 			if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
@@ -863,7 +865,7 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
 
 	if (gid == old->gid  || gid == old->egid  ||
 	    gid == old->sgid || gid == old->fsgid ||
-	    capable(CAP_SETGID)) {
+	    ns_capable(current_user_ns(), CAP_SETGID)) {
 		if (gid != old_fsgid) {
 			new->fsgid = gid;
 			goto change_okay;
@@ -1220,7 +1222,7 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
 	int errno;
 	char tmp[__NEW_UTS_LEN];
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
 		return -EPERM;
 	if (len < 0 || len > __NEW_UTS_LEN)
 		return -EINVAL;
@@ -1335,6 +1337,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
 	rlim = tsk->signal->rlim + resource;
 	task_lock(tsk->group_leader);
 	if (new_rlim) {
+		/* Keep the capable check against init_user_ns until
+		   cgroups can contain all limits */
 		if (new_rlim->rlim_max > rlim->rlim_max &&
 				!capable(CAP_SYS_RESOURCE))
 			retval = -EPERM;
@@ -1379,13 +1383,14 @@ static int check_prlimit_permission(struct task_struct *task)
 	const struct cred *cred = current_cred(), *tcred;
 
 	tcred = __task_cred(task);
-	if ((cred->uid != tcred->euid ||
+	if ((cred->user->user_ns != tcred->user->user_ns ||
+	     cred->uid != tcred->euid ||
 	     cred->uid != tcred->suid ||
 	     cred->uid != tcred->uid  ||
 	     cred->gid != tcred->egid ||
 	     cred->gid != tcred->sgid ||
 	     cred->gid != tcred->gid) &&
-	     !capable(CAP_SYS_RESOURCE)) {
+	     !ns_capable(tcred->user->user_ns, CAP_SYS_RESOURCE)) {
 		return -EPERM;
 	}
 
-- 
1.7.0.4


  parent reply	other threads:[~2011-01-10 21:12 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-10 21:11 userns: targeted capabilities v3 Serge E. Hallyn
2011-01-10 21:13 ` [PATCH 1/7] Add a user_namespace as creator/owner of uts_namespace Serge E. Hallyn
2011-01-10 21:13 ` [PATCH 2/7] security: Make capabilities relative to the user namespace Serge E. Hallyn
2011-01-10 21:13 ` [PATCH 3/7] allow sethostname in a container Serge E. Hallyn
2011-01-10 21:13 ` [PATCH 4/7] allow killing tasks in your own or child userns Serge E. Hallyn
2011-01-10 21:52   ` Bastian Blank
2011-01-10 22:51     ` Serge Hallyn
2011-01-10 23:23       ` Bastian Blank
2011-01-11  1:31         ` Serge E. Hallyn
2011-01-14 14:50           ` Bastian Blank
2011-01-15  0:31             ` Serge E. Hallyn
2011-01-15 11:30               ` Bastian Blank
2011-01-15 14:12                 ` Serge E. Hallyn
2011-01-11  4:22       ` Oren Laadan
2011-01-11  4:32         ` Serge E. Hallyn
2011-01-10 21:13 ` [PATCH 5/7] Allow ptrace from non-init user namespaces Serge E. Hallyn
2011-01-10 21:14 ` Serge E. Hallyn [this message]
2011-01-10 21:59   ` [PATCH 6/7] user namespaces: convert all capable checks in kernel/sys.c Bastian Blank
2011-01-10 22:56     ` Serge Hallyn
2011-01-11  5:27     ` Serge E. Hallyn
2011-01-14 15:02       ` Bastian Blank
2011-01-10 21:14 ` [PATCH 7/7] user namespaces: convert several capable() calls Serge E. Hallyn

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=20110110211406.GF22564@mail.hallyn.com \
    --to=serge@hallyn.com \
    --cc=adobriyan@gmail.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=ebiederm@xmission.com \
    --cc=jmorris@namei.org \
    --cc=kees.cook@canonical.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mtk.manpages@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).