diff options
| author | Eric W. Biederman <ebiederm@xmission.com> | 2011-11-16 23:20:58 -0800 | 
|---|---|---|
| committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-04-07 17:11:46 -0700 | 
| commit | 7b44ab978b77a91b327058a0f4db7e6fcdb90b92 (patch) | |
| tree | 632c872f0b88d001f1bddce2c0aacd77bf062454 /kernel/sys.c | |
| parent | 5673a94c14574d7c6495c320c6b0e480673d54bd (diff) | |
| download | olio-linux-3.10-7b44ab978b77a91b327058a0f4db7e6fcdb90b92.tar.xz olio-linux-3.10-7b44ab978b77a91b327058a0f4db7e6fcdb90b92.zip  | |
userns: Disassociate user_struct from the user_namespace.
Modify alloc_uid to take a kuid and make the user hash table global.
Stop holding a reference to the user namespace in struct user_struct.
This simplifies the code and makes the per user accounting not
care about which user namespace a uid happens to appear in.
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'kernel/sys.c')
| -rw-r--r-- | kernel/sys.c | 34 | 
1 files changed, 23 insertions, 11 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 71852417cfc..f0c43b4b665 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -175,6 +175,8 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)  	const struct cred *cred = current_cred();  	int error = -EINVAL;  	struct pid *pgrp; +	kuid_t cred_uid; +	kuid_t uid;  	if (which > PRIO_USER || which < PRIO_PROCESS)  		goto out; @@ -207,18 +209,22 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)  			} while_each_pid_thread(pgrp, PIDTYPE_PGID, p);  			break;  		case PRIO_USER: +			cred_uid = make_kuid(cred->user_ns, cred->uid); +			uid = make_kuid(cred->user_ns, who);  			user = cred->user;  			if (!who) -				who = cred->uid; -			else if ((who != cred->uid) && -				 !(user = find_user(who))) +				uid = cred_uid; +			else if (!uid_eq(uid, cred_uid) && +				 !(user = find_user(uid)))  				goto out_unlock;	/* No processes for this user */  			do_each_thread(g, p) { -				if (__task_cred(p)->uid == who) +				const struct cred *tcred = __task_cred(p); +				kuid_t tcred_uid = make_kuid(tcred->user_ns, tcred->uid); +				if (uid_eq(tcred_uid, uid))  					error = set_one_prio(p, niceval, error);  			} while_each_thread(g, p); -			if (who != cred->uid) +			if (!uid_eq(uid, cred_uid))  				free_uid(user);		/* For find_user() */  			break;  	} @@ -242,6 +248,8 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)  	const struct cred *cred = current_cred();  	long niceval, retval = -ESRCH;  	struct pid *pgrp; +	kuid_t cred_uid; +	kuid_t uid;  	if (which > PRIO_USER || which < PRIO_PROCESS)  		return -EINVAL; @@ -272,21 +280,25 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)  			} while_each_pid_thread(pgrp, PIDTYPE_PGID, p);  			break;  		case PRIO_USER: +			cred_uid = make_kuid(cred->user_ns, cred->uid); +			uid = make_kuid(cred->user_ns, who);  			user = cred->user;  			if (!who) -				who = cred->uid; -			else if ((who != cred->uid) && -				 !(user = find_user(who))) +				uid = cred_uid; +			else if (!uid_eq(uid, cred_uid) && +				 !(user = find_user(uid)))  				goto out_unlock;	/* No processes for this user */  			do_each_thread(g, p) { -				if (__task_cred(p)->uid == who) { +				const struct cred *tcred = __task_cred(p); +				kuid_t tcred_uid = make_kuid(tcred->user_ns, tcred->uid); +				if (uid_eq(tcred_uid, uid)) {  					niceval = 20 - task_nice(p);  					if (niceval > retval)  						retval = niceval;  				}  			} while_each_thread(g, p); -			if (who != cred->uid) +			if (!uid_eq(uid, cred_uid))  				free_uid(user);		/* for find_user() */  			break;  	} @@ -629,7 +641,7 @@ static int set_user(struct cred *new)  {  	struct user_struct *new_user; -	new_user = alloc_uid(current_user_ns(), new->uid); +	new_user = alloc_uid(make_kuid(new->user_ns, new->uid));  	if (!new_user)  		return -EAGAIN;  |