aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/fault.c2
-rw-r--r--fs/ioprio.c8
-rw-r--r--include/linux/cred.h16
-rw-r--r--include/linux/user_namespace.h8
-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
-rw-r--r--mm/oom_kill.c4
-rw-r--r--security/commoncap.c3
10 files changed, 59 insertions, 62 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 3ecfd1aaf214..76dcd9d8e0bc 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -582,7 +582,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code,
582 pte_t *pte = lookup_address(address, &level); 582 pte_t *pte = lookup_address(address, &level);
583 583
584 if (pte && pte_present(*pte) && !pte_exec(*pte)) 584 if (pte && pte_present(*pte) && !pte_exec(*pte))
585 printk(nx_warning, current_uid()); 585 printk(nx_warning, from_kuid(&init_user_ns, current_uid()));
586 } 586 }
587 587
588 printk(KERN_ALERT "BUG: unable to handle kernel "); 588 printk(KERN_ALERT "BUG: unable to handle kernel ");
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 8e35e964d9ed..2072e41785d2 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -123,9 +123,7 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
123 break; 123 break;
124 124
125 do_each_thread(g, p) { 125 do_each_thread(g, p) {
126 const struct cred *tcred = __task_cred(p); 126 if (!uid_eq(task_uid(p), uid))
127 kuid_t tcred_uid = make_kuid(tcred->user_ns, tcred->uid);
128 if (!uid_eq(tcred_uid, uid))
129 continue; 127 continue;
130 ret = set_task_ioprio(p, ioprio); 128 ret = set_task_ioprio(p, ioprio);
131 if (ret) 129 if (ret)
@@ -220,9 +218,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
220 break; 218 break;
221 219
222 do_each_thread(g, p) { 220 do_each_thread(g, p) {
223 const struct cred *tcred = __task_cred(p); 221 if (!uid_eq(task_uid(p), user->uid))
224 kuid_t tcred_uid = make_kuid(tcred->user_ns, tcred->uid);
225 if (!uid_eq(tcred_uid, user->uid))
226 continue; 222 continue;
227 tmpio = get_task_ioprio(p); 223 tmpio = get_task_ioprio(p);
228 if (tmpio < 0) 224 if (tmpio < 0)
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 0ab3cda4a774..fac0579258fc 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -123,14 +123,14 @@ struct cred {
123#define CRED_MAGIC 0x43736564 123#define CRED_MAGIC 0x43736564
124#define CRED_MAGIC_DEAD 0x44656144 124#define CRED_MAGIC_DEAD 0x44656144
125#endif 125#endif
126 uid_t uid; /* real UID of the task */ 126 kuid_t uid; /* real UID of the task */
127 gid_t gid; /* real GID of the task */ 127 kgid_t gid; /* real GID of the task */
128 uid_t suid; /* saved UID of the task */ 128 kuid_t suid; /* saved UID of the task */
129 gid_t sgid; /* saved GID of the task */ 129 kgid_t sgid; /* saved GID of the task */
130 uid_t euid; /* effective UID of the task */ 130 kuid_t euid; /* effective UID of the task */
131 gid_t egid; /* effective GID of the task */ 131 kgid_t egid; /* effective GID of the task */
132 uid_t fsuid; /* UID for VFS ops */ 132 kuid_t fsuid; /* UID for VFS ops */
133 gid_t fsgid; /* GID for VFS ops */ 133 kgid_t fsgid; /* GID for VFS ops */
134 unsigned securebits; /* SUID-less security management */ 134 unsigned securebits; /* SUID-less security management */
135 kernel_cap_t cap_inheritable; /* caps our children can inherit */ 135 kernel_cap_t cap_inheritable; /* caps our children can inherit */
136 kernel_cap_t cap_permitted; /* caps we're permitted */ 136 kernel_cap_t cap_permitted; /* caps we're permitted */
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 4c9846d90741..a2c61457cba1 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -70,15 +70,15 @@ static inline void put_user_ns(struct user_namespace *ns)
70#endif 70#endif
71 71
72static inline uid_t user_ns_map_uid(struct user_namespace *to, 72static inline uid_t user_ns_map_uid(struct user_namespace *to,
73 const struct cred *cred, uid_t uid) 73 const struct cred *cred, kuid_t uid)
74{ 74{
75 return from_kuid_munged(to, make_kuid(cred->user_ns, uid)); 75 return from_kuid_munged(to, uid);
76} 76}
77 77
78static inline gid_t user_ns_map_gid(struct user_namespace *to, 78static inline gid_t user_ns_map_gid(struct user_namespace *to,
79 const struct cred *cred, gid_t gid) 79 const struct cred *cred, kgid_t gid)
80{ 80{
81 return from_kgid_munged(to, make_kgid(cred->user_ns, gid)); 81 return from_kgid_munged(to, gid);
82} 82}
83 83
84#endif /* _LINUX_USER_H */ 84#endif /* _LINUX_USER_H */
diff --git a/kernel/cred.c b/kernel/cred.c
index 7a0d80669886..eddc5e2e9587 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 e2c5d84f2dac..2734dc965f69 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 f0c43b4b6657..39962818c008 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 7eff867bfac5..86602316422d 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
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 46bf2ed5594c..9f09a1fde9f9 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -410,8 +410,8 @@ static void dump_tasks(const struct mem_cgroup *memcg, const nodemask_t *nodemas
410 } 410 }
411 411
412 pr_info("[%5d] %5d %5d %8lu %8lu %3u %3d %5d %s\n", 412 pr_info("[%5d] %5d %5d %8lu %8lu %3u %3d %5d %s\n",
413 task->pid, task_uid(task), task->tgid, 413 task->pid, from_kuid(&init_user_ns, task_uid(task)),
414 task->mm->total_vm, get_mm_rss(task->mm), 414 task->tgid, task->mm->total_vm, get_mm_rss(task->mm),
415 task_cpu(task), task->signal->oom_adj, 415 task_cpu(task), task->signal->oom_adj,
416 task->signal->oom_score_adj, task->comm); 416 task->signal->oom_score_adj, task->comm);
417 task_unlock(task); 417 task_unlock(task);
diff --git a/security/commoncap.c b/security/commoncap.c
index f2399d8afbe0..dbd465a59286 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -77,8 +77,7 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
77{ 77{
78 for (;;) { 78 for (;;) {
79 /* The owner of the user namespace has all caps. */ 79 /* The owner of the user namespace has all caps. */
80 if (targ_ns != &init_user_ns && uid_eq(targ_ns->owner, 80 if (targ_ns != &init_user_ns && uid_eq(targ_ns->owner, cred->euid))
81 make_kuid(cred->user_ns, cred->euid)))
82 return 0; 81 return 0;
83 82
84 /* Do we have the necessary capabilities? */ 83 /* Do we have the necessary capabilities? */