aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
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