aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-02-08 10:00:08 -0500
committerEric W. Biederman <ebiederm@xmission.com>2012-05-03 06:28:38 -0400
commit078de5f706ece36afd73bb4b8283314132d2dfdf (patch)
tree0dee00713f9cb5e2516260a66b8df99ef7d03e4d /kernel
parentae2975bc3476243b45a1e2344236d7920c268f38 (diff)
userns: Store uid and gid values in struct cred with kuid_t and kgid_t types
cred.h and a few trivial users of struct cred are changed. The rest of the users of struct cred are left for other patches as there are too many changes to make in one go and leave the change reviewable. If the user namespace is disabled and CONFIG_UIDGID_STRICT_TYPE_CHECKS are disabled the code will contiue to compile and behave correctly. Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cred.c36
-rw-r--r--kernel/signal.c14
-rw-r--r--kernel/sys.c26
-rw-r--r--kernel/user_namespace.c4
4 files changed, 41 insertions, 39 deletions
diff --git a/kernel/cred.c b/kernel/cred.c
index 7a0d8066988..eddc5e2e958 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -49,6 +49,14 @@ struct cred init_cred = {
49 .subscribers = ATOMIC_INIT(2), 49 .subscribers = ATOMIC_INIT(2),
50 .magic = CRED_MAGIC, 50 .magic = CRED_MAGIC,
51#endif 51#endif
52 .uid = GLOBAL_ROOT_UID,
53 .gid = GLOBAL_ROOT_GID,
54 .suid = GLOBAL_ROOT_UID,
55 .sgid = GLOBAL_ROOT_GID,
56 .euid = GLOBAL_ROOT_UID,
57 .egid = GLOBAL_ROOT_GID,
58 .fsuid = GLOBAL_ROOT_UID,
59 .fsgid = GLOBAL_ROOT_GID,
52 .securebits = SECUREBITS_DEFAULT, 60 .securebits = SECUREBITS_DEFAULT,
53 .cap_inheritable = CAP_EMPTY_SET, 61 .cap_inheritable = CAP_EMPTY_SET,
54 .cap_permitted = CAP_FULL_SET, 62 .cap_permitted = CAP_FULL_SET,
@@ -488,10 +496,10 @@ int commit_creds(struct cred *new)
488 get_cred(new); /* we will require a ref for the subj creds too */ 496 get_cred(new); /* we will require a ref for the subj creds too */
489 497
490 /* dumpability changes */ 498 /* dumpability changes */
491 if (old->euid != new->euid || 499 if (!uid_eq(old->euid, new->euid) ||
492 old->egid != new->egid || 500 !gid_eq(old->egid, new->egid) ||
493 old->fsuid != new->fsuid || 501 !uid_eq(old->fsuid, new->fsuid) ||
494 old->fsgid != new->fsgid || 502 !gid_eq(old->fsgid, new->fsgid) ||
495 !cap_issubset(new->cap_permitted, old->cap_permitted)) { 503 !cap_issubset(new->cap_permitted, old->cap_permitted)) {
496 if (task->mm) 504 if (task->mm)
497 set_dumpable(task->mm, suid_dumpable); 505 set_dumpable(task->mm, suid_dumpable);
@@ -500,9 +508,9 @@ int commit_creds(struct cred *new)
500 } 508 }
501 509
502 /* alter the thread keyring */ 510 /* alter the thread keyring */
503 if (new->fsuid != old->fsuid) 511 if (!uid_eq(new->fsuid, old->fsuid))
504 key_fsuid_changed(task); 512 key_fsuid_changed(task);
505 if (new->fsgid != old->fsgid) 513 if (!gid_eq(new->fsgid, old->fsgid))
506 key_fsgid_changed(task); 514 key_fsgid_changed(task);
507 515
508 /* do it 516 /* do it
@@ -519,16 +527,16 @@ int commit_creds(struct cred *new)
519 alter_cred_subscribers(old, -2); 527 alter_cred_subscribers(old, -2);
520 528
521 /* send notifications */ 529 /* send notifications */
522 if (new->uid != old->uid || 530 if (!uid_eq(new->uid, old->uid) ||
523 new->euid != old->euid || 531 !uid_eq(new->euid, old->euid) ||
524 new->suid != old->suid || 532 !uid_eq(new->suid, old->suid) ||
525 new->fsuid != old->fsuid) 533 !uid_eq(new->fsuid, old->fsuid))
526 proc_id_connector(task, PROC_EVENT_UID); 534 proc_id_connector(task, PROC_EVENT_UID);
527 535
528 if (new->gid != old->gid || 536 if (!gid_eq(new->gid, old->gid) ||
529 new->egid != old->egid || 537 !gid_eq(new->egid, old->egid) ||
530 new->sgid != old->sgid || 538 !gid_eq(new->sgid, old->sgid) ||
531 new->fsgid != old->fsgid) 539 !gid_eq(new->fsgid, old->fsgid))
532 proc_id_connector(task, PROC_EVENT_GID); 540 proc_id_connector(task, PROC_EVENT_GID);
533 541
534 /* release the old obj and subj refs both */ 542 /* release the old obj and subj refs both */
diff --git a/kernel/signal.c b/kernel/signal.c
index e2c5d84f2da..2734dc965f6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1038,8 +1038,10 @@ static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_str
1038 if (SI_FROMKERNEL(info)) 1038 if (SI_FROMKERNEL(info))
1039 return; 1039 return;
1040 1040
1041 info->si_uid = user_ns_map_uid(task_cred_xxx(t, user_ns), 1041 rcu_read_lock();
1042 current_cred(), info->si_uid); 1042 info->si_uid = from_kuid_munged(task_cred_xxx(t, user_ns),
1043 make_kuid(current_user_ns(), info->si_uid));
1044 rcu_read_unlock();
1043} 1045}
1044#else 1046#else
1045static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_struct *t) 1047static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_struct *t)
@@ -1106,7 +1108,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
1106 q->info.si_code = SI_USER; 1108 q->info.si_code = SI_USER;
1107 q->info.si_pid = task_tgid_nr_ns(current, 1109 q->info.si_pid = task_tgid_nr_ns(current,
1108 task_active_pid_ns(t)); 1110 task_active_pid_ns(t));
1109 q->info.si_uid = current_uid(); 1111 q->info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
1110 break; 1112 break;
1111 case (unsigned long) SEND_SIG_PRIV: 1113 case (unsigned long) SEND_SIG_PRIV:
1112 q->info.si_signo = sig; 1114 q->info.si_signo = sig;
@@ -1973,7 +1975,7 @@ static void ptrace_do_notify(int signr, int exit_code, int why)
1973 info.si_signo = signr; 1975 info.si_signo = signr;
1974 info.si_code = exit_code; 1976 info.si_code = exit_code;
1975 info.si_pid = task_pid_vnr(current); 1977 info.si_pid = task_pid_vnr(current);
1976 info.si_uid = current_uid(); 1978 info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
1977 1979
1978 /* Let the debugger run. */ 1980 /* Let the debugger run. */
1979 ptrace_stop(exit_code, why, 1, &info); 1981 ptrace_stop(exit_code, why, 1, &info);
@@ -2828,7 +2830,7 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
2828 info.si_errno = 0; 2830 info.si_errno = 0;
2829 info.si_code = SI_USER; 2831 info.si_code = SI_USER;
2830 info.si_pid = task_tgid_vnr(current); 2832 info.si_pid = task_tgid_vnr(current);
2831 info.si_uid = current_uid(); 2833 info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
2832 2834
2833 return kill_something_info(sig, &info, pid); 2835 return kill_something_info(sig, &info, pid);
2834} 2836}
@@ -2871,7 +2873,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig)
2871 info.si_errno = 0; 2873 info.si_errno = 0;
2872 info.si_code = SI_TKILL; 2874 info.si_code = SI_TKILL;
2873 info.si_pid = task_tgid_vnr(current); 2875 info.si_pid = task_tgid_vnr(current);
2874 info.si_uid = current_uid(); 2876 info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
2875 2877
2876 return do_send_specific(tgid, pid, sig, &info); 2878 return do_send_specific(tgid, pid, sig, &info);
2877} 2879}
diff --git a/kernel/sys.c b/kernel/sys.c
index f0c43b4b665..39962818c00 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -175,7 +175,6 @@ 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 kuid_t uid;
180 179
181 if (which > PRIO_USER || which < PRIO_PROCESS) 180 if (which > PRIO_USER || which < PRIO_PROCESS)
@@ -209,22 +208,19 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
209 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 208 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
210 break; 209 break;
211 case PRIO_USER: 210 case PRIO_USER:
212 cred_uid = make_kuid(cred->user_ns, cred->uid);
213 uid = make_kuid(cred->user_ns, who); 211 uid = make_kuid(cred->user_ns, who);
214 user = cred->user; 212 user = cred->user;
215 if (!who) 213 if (!who)
216 uid = cred_uid; 214 uid = cred->uid;
217 else if (!uid_eq(uid, cred_uid) && 215 else if (!uid_eq(uid, cred->uid) &&
218 !(user = find_user(uid))) 216 !(user = find_user(uid)))
219 goto out_unlock; /* No processes for this user */ 217 goto out_unlock; /* No processes for this user */
220 218
221 do_each_thread(g, p) { 219 do_each_thread(g, p) {
222 const struct cred *tcred = __task_cred(p); 220 if (uid_eq(task_uid(p), uid))
223 kuid_t tcred_uid = make_kuid(tcred->user_ns, tcred->uid);
224 if (uid_eq(tcred_uid, uid))
225 error = set_one_prio(p, niceval, error); 221 error = set_one_prio(p, niceval, error);
226 } while_each_thread(g, p); 222 } while_each_thread(g, p);
227 if (!uid_eq(uid, cred_uid)) 223 if (!uid_eq(uid, cred->uid))
228 free_uid(user); /* For find_user() */ 224 free_uid(user); /* For find_user() */
229 break; 225 break;
230 } 226 }
@@ -248,7 +244,6 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
248 const struct cred *cred = current_cred(); 244 const struct cred *cred = current_cred();
249 long niceval, retval = -ESRCH; 245 long niceval, retval = -ESRCH;
250 struct pid *pgrp; 246 struct pid *pgrp;
251 kuid_t cred_uid;
252 kuid_t uid; 247 kuid_t uid;
253 248
254 if (which > PRIO_USER || which < PRIO_PROCESS) 249 if (which > PRIO_USER || which < PRIO_PROCESS)
@@ -280,25 +275,22 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
280 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 275 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
281 break; 276 break;
282 case PRIO_USER: 277 case PRIO_USER:
283 cred_uid = make_kuid(cred->user_ns, cred->uid);
284 uid = make_kuid(cred->user_ns, who); 278 uid = make_kuid(cred->user_ns, who);
285 user = cred->user; 279 user = cred->user;
286 if (!who) 280 if (!who)
287 uid = cred_uid; 281 uid = cred->uid;
288 else if (!uid_eq(uid, cred_uid) && 282 else if (!uid_eq(uid, cred->uid) &&
289 !(user = find_user(uid))) 283 !(user = find_user(uid)))
290 goto out_unlock; /* No processes for this user */ 284 goto out_unlock; /* No processes for this user */
291 285
292 do_each_thread(g, p) { 286 do_each_thread(g, p) {
293 const struct cred *tcred = __task_cred(p); 287 if (uid_eq(task_uid(p), uid)) {
294 kuid_t tcred_uid = make_kuid(tcred->user_ns, tcred->uid);
295 if (uid_eq(tcred_uid, uid)) {
296 niceval = 20 - task_nice(p); 288 niceval = 20 - task_nice(p);
297 if (niceval > retval) 289 if (niceval > retval)
298 retval = niceval; 290 retval = niceval;
299 } 291 }
300 } while_each_thread(g, p); 292 } while_each_thread(g, p);
301 if (!uid_eq(uid, cred_uid)) 293 if (!uid_eq(uid, cred->uid))
302 free_uid(user); /* for find_user() */ 294 free_uid(user); /* for find_user() */
303 break; 295 break;
304 } 296 }
@@ -641,7 +633,7 @@ static int set_user(struct cred *new)
641{ 633{
642 struct user_struct *new_user; 634 struct user_struct *new_user;
643 635
644 new_user = alloc_uid(make_kuid(new->user_ns, new->uid)); 636 new_user = alloc_uid(new->uid);
645 if (!new_user) 637 if (!new_user)
646 return -EAGAIN; 638 return -EAGAIN;
647 639
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 7eff867bfac..86602316422 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -36,8 +36,8 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
36int create_user_ns(struct cred *new) 36int create_user_ns(struct cred *new)
37{ 37{
38 struct user_namespace *ns, *parent_ns = new->user_ns; 38 struct user_namespace *ns, *parent_ns = new->user_ns;
39 kuid_t owner = make_kuid(new->user_ns, new->euid); 39 kuid_t owner = new->euid;
40 kgid_t group = make_kgid(new->user_ns, new->egid); 40 kgid_t group = new->egid;
41 41
42 /* The creator needs a mapping in the parent user namespace 42 /* The creator needs a mapping in the parent user namespace
43 * or else we won't be able to reasonably tell userspace who 43 * or else we won't be able to reasonably tell userspace who