diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2011-11-17 02:20:58 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-04-07 20:11:46 -0400 |
commit | 7b44ab978b77a91b327058a0f4db7e6fcdb90b92 (patch) | |
tree | 632c872f0b88d001f1bddce2c0aacd77bf062454 /kernel/sys.c | |
parent | 5673a94c14574d7c6495c320c6b0e480673d54bd (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.c | 34 |
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 | ||