aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2011-11-17 02:20:58 -0500
committerEric W. Biederman <ebiederm@xmission.com>2012-04-07 20:11:46 -0400
commit7b44ab978b77a91b327058a0f4db7e6fcdb90b92 (patch)
tree632c872f0b88d001f1bddce2c0aacd77bf062454 /kernel/sys.c
parent5673a94c14574d7c6495c320c6b0e480673d54bd (diff)
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.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 71852417cfc8..f0c43b4b6657 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -175,6 +175,8 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
175 const struct cred *cred = current_cred(); 175 const struct cred *cred = current_cred();
176 int error = -EINVAL; 176 int error = -EINVAL;
177 struct pid *pgrp; 177 struct pid *pgrp;
178 kuid_t cred_uid;
179 kuid_t uid;
178 180
179 if (which > PRIO_USER || which < PRIO_PROCESS) 181 if (which > PRIO_USER || which < PRIO_PROCESS)
180 goto out; 182 goto out;
@@ -207,18 +209,22 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
207 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 209 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
208 break; 210 break;
209 case PRIO_USER: 211 case PRIO_USER:
212 cred_uid = make_kuid(cred->user_ns, cred->uid);
213 uid = make_kuid(cred->user_ns, who);
210 user = cred->user; 214 user = cred->user;
211 if (!who) 215 if (!who)
212 who = cred->uid; 216 uid = cred_uid;
213 else if ((who != cred->uid) && 217 else if (!uid_eq(uid, cred_uid) &&
214 !(user = find_user(who))) 218 !(user = find_user(uid)))
215 goto out_unlock; /* No processes for this user */ 219 goto out_unlock; /* No processes for this user */
216 220
217 do_each_thread(g, p) { 221 do_each_thread(g, p) {
218 if (__task_cred(p)->uid == who) 222 const struct cred *tcred = __task_cred(p);
223 kuid_t tcred_uid = make_kuid(tcred->user_ns, tcred->uid);
224 if (uid_eq(tcred_uid, uid))
219 error = set_one_prio(p, niceval, error); 225 error = set_one_prio(p, niceval, error);
220 } while_each_thread(g, p); 226 } while_each_thread(g, p);
221 if (who != cred->uid) 227 if (!uid_eq(uid, cred_uid))
222 free_uid(user); /* For find_user() */ 228 free_uid(user); /* For find_user() */
223 break; 229 break;
224 } 230 }
@@ -242,6 +248,8 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
242 const struct cred *cred = current_cred(); 248 const struct cred *cred = current_cred();
243 long niceval, retval = -ESRCH; 249 long niceval, retval = -ESRCH;
244 struct pid *pgrp; 250 struct pid *pgrp;
251 kuid_t cred_uid;
252 kuid_t uid;
245 253
246 if (which > PRIO_USER || which < PRIO_PROCESS) 254 if (which > PRIO_USER || which < PRIO_PROCESS)
247 return -EINVAL; 255 return -EINVAL;
@@ -272,21 +280,25 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
272 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 280 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
273 break; 281 break;
274 case PRIO_USER: 282 case PRIO_USER:
283 cred_uid = make_kuid(cred->user_ns, cred->uid);
284 uid = make_kuid(cred->user_ns, who);
275 user = cred->user; 285 user = cred->user;
276 if (!who) 286 if (!who)
277 who = cred->uid; 287 uid = cred_uid;
278 else if ((who != cred->uid) && 288 else if (!uid_eq(uid, cred_uid) &&
279 !(user = find_user(who))) 289 !(user = find_user(uid)))
280 goto out_unlock; /* No processes for this user */ 290 goto out_unlock; /* No processes for this user */
281 291
282 do_each_thread(g, p) { 292 do_each_thread(g, p) {
283 if (__task_cred(p)->uid == who) { 293 const struct cred *tcred = __task_cred(p);
294 kuid_t tcred_uid = make_kuid(tcred->user_ns, tcred->uid);
295 if (uid_eq(tcred_uid, uid)) {
284 niceval = 20 - task_nice(p); 296 niceval = 20 - task_nice(p);
285 if (niceval > retval) 297 if (niceval > retval)
286 retval = niceval; 298 retval = niceval;
287 } 299 }
288 } while_each_thread(g, p); 300 } while_each_thread(g, p);
289 if (who != cred->uid) 301 if (!uid_eq(uid, cred_uid))
290 free_uid(user); /* for find_user() */ 302 free_uid(user); /* for find_user() */
291 break; 303 break;
292 } 304 }
@@ -629,7 +641,7 @@ static int set_user(struct cred *new)
629{ 641{
630 struct user_struct *new_user; 642 struct user_struct *new_user;
631 643
632 new_user = alloc_uid(current_user_ns(), new->uid); 644 new_user = alloc_uid(make_kuid(new->user_ns, new->uid));
633 if (!new_user) 645 if (!new_user)
634 return -EAGAIN; 646 return -EAGAIN;
635 647