aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:12 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:12 -0500
commit76aac0e9a17742e60d408be1a706e9aaad370891 (patch)
treee873a000d9c96209726e0958e311f005c13b2ed5 /kernel
parentb103c59883f1ec6e4d548b25054608cb5724453c (diff)
CRED: Wrap task credential accesses in the core kernel
Wrap access to task credentials so that they can be separated more easily from the task_struct during the introduction of COW creds. Change most current->(|e|s|fs)[ug]id to current_(|e|s|fs)[ug]id(). Change some task->e?[ug]id to task_e?[ug]id(). In some places it makes more sense to use RCU directly rather than a convenient wrapper; these will be addressed by later patches. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: James Morris <jmorris@namei.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: linux-audit@redhat.com Cc: containers@lists.linux-foundation.org Cc: linux-mm@kvack.org Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/acct.c7
-rw-r--r--kernel/auditsc.c6
-rw-r--r--kernel/cgroup.c9
-rw-r--r--kernel/futex.c8
-rw-r--r--kernel/futex_compat.c3
-rw-r--r--kernel/ptrace.c15
-rw-r--r--kernel/sched.c11
-rw-r--r--kernel/signal.c15
-rw-r--r--kernel/sys.c16
-rw-r--r--kernel/sysctl.c2
-rw-r--r--kernel/timer.c8
-rw-r--r--kernel/user_namespace.c2
12 files changed, 58 insertions, 44 deletions
diff --git a/kernel/acct.c b/kernel/acct.c
index f6006a60df5d..d57b7cbb98b6 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -530,15 +530,14 @@ static void do_acct_process(struct bsd_acct_struct *acct,
530 do_div(elapsed, AHZ); 530 do_div(elapsed, AHZ);
531 ac.ac_btime = get_seconds() - elapsed; 531 ac.ac_btime = get_seconds() - elapsed;
532 /* we really need to bite the bullet and change layout */ 532 /* we really need to bite the bullet and change layout */
533 ac.ac_uid = current->uid; 533 current_uid_gid(&ac.ac_uid, &ac.ac_gid);
534 ac.ac_gid = current->gid;
535#if ACCT_VERSION==2 534#if ACCT_VERSION==2
536 ac.ac_ahz = AHZ; 535 ac.ac_ahz = AHZ;
537#endif 536#endif
538#if ACCT_VERSION==1 || ACCT_VERSION==2 537#if ACCT_VERSION==1 || ACCT_VERSION==2
539 /* backward-compatible 16 bit fields */ 538 /* backward-compatible 16 bit fields */
540 ac.ac_uid16 = current->uid; 539 ac.ac_uid16 = ac.ac_uid;
541 ac.ac_gid16 = current->gid; 540 ac.ac_gid16 = ac.ac_gid;
542#endif 541#endif
543#if ACCT_VERSION==3 542#if ACCT_VERSION==3
544 ac.ac_pid = task_tgid_nr_ns(current, ns); 543 ac.ac_pid = task_tgid_nr_ns(current, ns);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index cef34235b362..9c7e47ae4576 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2628,7 +2628,8 @@ void audit_core_dumps(long signr)
2628{ 2628{
2629 struct audit_buffer *ab; 2629 struct audit_buffer *ab;
2630 u32 sid; 2630 u32 sid;
2631 uid_t auid = audit_get_loginuid(current); 2631 uid_t auid = audit_get_loginuid(current), uid;
2632 gid_t gid;
2632 unsigned int sessionid = audit_get_sessionid(current); 2633 unsigned int sessionid = audit_get_sessionid(current);
2633 2634
2634 if (!audit_enabled) 2635 if (!audit_enabled)
@@ -2638,8 +2639,9 @@ void audit_core_dumps(long signr)
2638 return; 2639 return;
2639 2640
2640 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); 2641 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
2642 current_uid_gid(&uid, &gid);
2641 audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", 2643 audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
2642 auid, current->uid, current->gid, sessionid); 2644 auid, uid, gid, sessionid);
2643 security_task_getsecid(current, &sid); 2645 security_task_getsecid(current, &sid);
2644 if (sid) { 2646 if (sid) {
2645 char *ctx = NULL; 2647 char *ctx = NULL;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 35eebd5510c2..78f9b310c4f3 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -571,8 +571,8 @@ static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb)
571 571
572 if (inode) { 572 if (inode) {
573 inode->i_mode = mode; 573 inode->i_mode = mode;
574 inode->i_uid = current->fsuid; 574 inode->i_uid = current_fsuid();
575 inode->i_gid = current->fsgid; 575 inode->i_gid = current_fsgid();
576 inode->i_blocks = 0; 576 inode->i_blocks = 0;
577 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 577 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
578 inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info; 578 inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info;
@@ -1279,6 +1279,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
1279static int attach_task_by_pid(struct cgroup *cgrp, u64 pid) 1279static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
1280{ 1280{
1281 struct task_struct *tsk; 1281 struct task_struct *tsk;
1282 uid_t euid;
1282 int ret; 1283 int ret;
1283 1284
1284 if (pid) { 1285 if (pid) {
@@ -1291,8 +1292,8 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
1291 get_task_struct(tsk); 1292 get_task_struct(tsk);
1292 rcu_read_unlock(); 1293 rcu_read_unlock();
1293 1294
1294 if ((current->euid) && (current->euid != tsk->uid) 1295 euid = current_euid();
1295 && (current->euid != tsk->suid)) { 1296 if (euid && euid != tsk->uid && euid != tsk->suid) {
1296 put_task_struct(tsk); 1297 put_task_struct(tsk);
1297 return -EACCES; 1298 return -EACCES;
1298 } 1299 }
diff --git a/kernel/futex.c b/kernel/futex.c
index 8af10027514b..e06962132aaf 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -439,10 +439,11 @@ static void free_pi_state(struct futex_pi_state *pi_state)
439static struct task_struct * futex_find_get_task(pid_t pid) 439static struct task_struct * futex_find_get_task(pid_t pid)
440{ 440{
441 struct task_struct *p; 441 struct task_struct *p;
442 uid_t euid = current_euid();
442 443
443 rcu_read_lock(); 444 rcu_read_lock();
444 p = find_task_by_vpid(pid); 445 p = find_task_by_vpid(pid);
445 if (!p || ((current->euid != p->euid) && (current->euid != p->uid))) 446 if (!p || (euid != p->euid && euid != p->uid))
446 p = ERR_PTR(-ESRCH); 447 p = ERR_PTR(-ESRCH);
447 else 448 else
448 get_task_struct(p); 449 get_task_struct(p);
@@ -1829,6 +1830,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
1829{ 1830{
1830 struct robust_list_head __user *head; 1831 struct robust_list_head __user *head;
1831 unsigned long ret; 1832 unsigned long ret;
1833 uid_t euid = current_euid();
1832 1834
1833 if (!futex_cmpxchg_enabled) 1835 if (!futex_cmpxchg_enabled)
1834 return -ENOSYS; 1836 return -ENOSYS;
@@ -1844,8 +1846,8 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
1844 if (!p) 1846 if (!p)
1845 goto err_unlock; 1847 goto err_unlock;
1846 ret = -EPERM; 1848 ret = -EPERM;
1847 if ((current->euid != p->euid) && (current->euid != p->uid) && 1849 if (euid != p->euid && euid != p->uid &&
1848 !capable(CAP_SYS_PTRACE)) 1850 !capable(CAP_SYS_PTRACE))
1849 goto err_unlock; 1851 goto err_unlock;
1850 head = p->robust_list; 1852 head = p->robust_list;
1851 rcu_read_unlock(); 1853 rcu_read_unlock();
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 04ac3a9e42cf..3254d4e41e88 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -135,6 +135,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
135{ 135{
136 struct compat_robust_list_head __user *head; 136 struct compat_robust_list_head __user *head;
137 unsigned long ret; 137 unsigned long ret;
138 uid_t euid = current_euid();
138 139
139 if (!futex_cmpxchg_enabled) 140 if (!futex_cmpxchg_enabled)
140 return -ENOSYS; 141 return -ENOSYS;
@@ -150,7 +151,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
150 if (!p) 151 if (!p)
151 goto err_unlock; 152 goto err_unlock;
152 ret = -EPERM; 153 ret = -EPERM;
153 if ((current->euid != p->euid) && (current->euid != p->uid) && 154 if (euid != p->euid && euid != p->uid &&
154 !capable(CAP_SYS_PTRACE)) 155 !capable(CAP_SYS_PTRACE))
155 goto err_unlock; 156 goto err_unlock;
156 head = p->compat_robust_list; 157 head = p->compat_robust_list;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 1e68e4c39e2c..937f6b5b2008 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -123,16 +123,19 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
123 * because setting up the necessary parent/child relationship 123 * because setting up the necessary parent/child relationship
124 * or halting the specified task is impossible. 124 * or halting the specified task is impossible.
125 */ 125 */
126 uid_t uid;
127 gid_t gid;
126 int dumpable = 0; 128 int dumpable = 0;
127 /* Don't let security modules deny introspection */ 129 /* Don't let security modules deny introspection */
128 if (task == current) 130 if (task == current)
129 return 0; 131 return 0;
130 if (((current->uid != task->euid) || 132 current_uid_gid(&uid, &gid);
131 (current->uid != task->suid) || 133 if ((uid != task->euid ||
132 (current->uid != task->uid) || 134 uid != task->suid ||
133 (current->gid != task->egid) || 135 uid != task->uid ||
134 (current->gid != task->sgid) || 136 gid != task->egid ||
135 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) 137 gid != task->sgid ||
138 gid != task->gid) && !capable(CAP_SYS_PTRACE))
136 return -EPERM; 139 return -EPERM;
137 smp_rmb(); 140 smp_rmb();
138 if (task->mm) 141 if (task->mm)
diff --git a/kernel/sched.c b/kernel/sched.c
index e8819bc6f462..c3b8b1fcde0d 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5128,6 +5128,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy,
5128 unsigned long flags; 5128 unsigned long flags;
5129 const struct sched_class *prev_class = p->sched_class; 5129 const struct sched_class *prev_class = p->sched_class;
5130 struct rq *rq; 5130 struct rq *rq;
5131 uid_t euid;
5131 5132
5132 /* may grab non-irq protected spin_locks */ 5133 /* may grab non-irq protected spin_locks */
5133 BUG_ON(in_interrupt()); 5134 BUG_ON(in_interrupt());
@@ -5180,8 +5181,9 @@ recheck:
5180 return -EPERM; 5181 return -EPERM;
5181 5182
5182 /* can't change other user's priorities */ 5183 /* can't change other user's priorities */
5183 if ((current->euid != p->euid) && 5184 euid = current_euid();
5184 (current->euid != p->uid)) 5185 if (euid != p->euid &&
5186 euid != p->uid)
5185 return -EPERM; 5187 return -EPERM;
5186 } 5188 }
5187 5189
@@ -5392,6 +5394,7 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)
5392 cpumask_t cpus_allowed; 5394 cpumask_t cpus_allowed;
5393 cpumask_t new_mask = *in_mask; 5395 cpumask_t new_mask = *in_mask;
5394 struct task_struct *p; 5396 struct task_struct *p;
5397 uid_t euid;
5395 int retval; 5398 int retval;
5396 5399
5397 get_online_cpus(); 5400 get_online_cpus();
@@ -5412,9 +5415,9 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)
5412 get_task_struct(p); 5415 get_task_struct(p);
5413 read_unlock(&tasklist_lock); 5416 read_unlock(&tasklist_lock);
5414 5417
5418 euid = current_euid();
5415 retval = -EPERM; 5419 retval = -EPERM;
5416 if ((current->euid != p->euid) && (current->euid != p->uid) && 5420 if (euid != p->euid && euid != p->uid && !capable(CAP_SYS_NICE))
5417 !capable(CAP_SYS_NICE))
5418 goto out_unlock; 5421 goto out_unlock;
5419 5422
5420 retval = security_task_setscheduler(p, 0, NULL); 5423 retval = security_task_setscheduler(p, 0, NULL);
diff --git a/kernel/signal.c b/kernel/signal.c
index 4530fc654455..167b535fe1a9 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -567,6 +567,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
567 struct task_struct *t) 567 struct task_struct *t)
568{ 568{
569 struct pid *sid; 569 struct pid *sid;
570 uid_t uid, euid;
570 int error; 571 int error;
571 572
572 if (!valid_signal(sig)) 573 if (!valid_signal(sig))
@@ -579,8 +580,10 @@ static int check_kill_permission(int sig, struct siginfo *info,
579 if (error) 580 if (error)
580 return error; 581 return error;
581 582
582 if ((current->euid ^ t->suid) && (current->euid ^ t->uid) && 583 uid = current_uid();
583 (current->uid ^ t->suid) && (current->uid ^ t->uid) && 584 euid = current_euid();
585 if ((euid ^ t->suid) && (euid ^ t->uid) &&
586 (uid ^ t->suid) && (uid ^ t->uid) &&
584 !capable(CAP_KILL)) { 587 !capable(CAP_KILL)) {
585 switch (sig) { 588 switch (sig) {
586 case SIGCONT: 589 case SIGCONT:
@@ -844,7 +847,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
844 q->info.si_errno = 0; 847 q->info.si_errno = 0;
845 q->info.si_code = SI_USER; 848 q->info.si_code = SI_USER;
846 q->info.si_pid = task_pid_vnr(current); 849 q->info.si_pid = task_pid_vnr(current);
847 q->info.si_uid = current->uid; 850 q->info.si_uid = current_uid();
848 break; 851 break;
849 case (unsigned long) SEND_SIG_PRIV: 852 case (unsigned long) SEND_SIG_PRIV:
850 q->info.si_signo = sig; 853 q->info.si_signo = sig;
@@ -1598,7 +1601,7 @@ void ptrace_notify(int exit_code)
1598 info.si_signo = SIGTRAP; 1601 info.si_signo = SIGTRAP;
1599 info.si_code = exit_code; 1602 info.si_code = exit_code;
1600 info.si_pid = task_pid_vnr(current); 1603 info.si_pid = task_pid_vnr(current);
1601 info.si_uid = current->uid; 1604 info.si_uid = current_uid();
1602 1605
1603 /* Let the debugger run. */ 1606 /* Let the debugger run. */
1604 spin_lock_irq(&current->sighand->siglock); 1607 spin_lock_irq(&current->sighand->siglock);
@@ -2211,7 +2214,7 @@ sys_kill(pid_t pid, int sig)
2211 info.si_errno = 0; 2214 info.si_errno = 0;
2212 info.si_code = SI_USER; 2215 info.si_code = SI_USER;
2213 info.si_pid = task_tgid_vnr(current); 2216 info.si_pid = task_tgid_vnr(current);
2214 info.si_uid = current->uid; 2217 info.si_uid = current_uid();
2215 2218
2216 return kill_something_info(sig, &info, pid); 2219 return kill_something_info(sig, &info, pid);
2217} 2220}
@@ -2228,7 +2231,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig)
2228 info.si_errno = 0; 2231 info.si_errno = 0;
2229 info.si_code = SI_TKILL; 2232 info.si_code = SI_TKILL;
2230 info.si_pid = task_tgid_vnr(current); 2233 info.si_pid = task_tgid_vnr(current);
2231 info.si_uid = current->uid; 2234 info.si_uid = current_uid();
2232 2235
2233 rcu_read_lock(); 2236 rcu_read_lock();
2234 p = find_task_by_vpid(pid); 2237 p = find_task_by_vpid(pid);
diff --git a/kernel/sys.c b/kernel/sys.c
index 31deba8f7d16..ed5c29c748ac 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -114,10 +114,10 @@ void (*pm_power_off_prepare)(void);
114 114
115static int set_one_prio(struct task_struct *p, int niceval, int error) 115static int set_one_prio(struct task_struct *p, int niceval, int error)
116{ 116{
117 uid_t euid = current_euid();
117 int no_nice; 118 int no_nice;
118 119
119 if (p->uid != current->euid && 120 if (p->uid != euid && p->euid != euid && !capable(CAP_SYS_NICE)) {
120 p->euid != current->euid && !capable(CAP_SYS_NICE)) {
121 error = -EPERM; 121 error = -EPERM;
122 goto out; 122 goto out;
123 } 123 }
@@ -176,16 +176,16 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
176 case PRIO_USER: 176 case PRIO_USER:
177 user = current->user; 177 user = current->user;
178 if (!who) 178 if (!who)
179 who = current->uid; 179 who = current_uid();
180 else 180 else
181 if ((who != current->uid) && !(user = find_user(who))) 181 if (who != current_uid() && !(user = find_user(who)))
182 goto out_unlock; /* No processes for this user */ 182 goto out_unlock; /* No processes for this user */
183 183
184 do_each_thread(g, p) 184 do_each_thread(g, p)
185 if (p->uid == who) 185 if (p->uid == who)
186 error = set_one_prio(p, niceval, error); 186 error = set_one_prio(p, niceval, error);
187 while_each_thread(g, p); 187 while_each_thread(g, p);
188 if (who != current->uid) 188 if (who != current_uid())
189 free_uid(user); /* For find_user() */ 189 free_uid(user); /* For find_user() */
190 break; 190 break;
191 } 191 }
@@ -238,9 +238,9 @@ asmlinkage long sys_getpriority(int which, int who)
238 case PRIO_USER: 238 case PRIO_USER:
239 user = current->user; 239 user = current->user;
240 if (!who) 240 if (!who)
241 who = current->uid; 241 who = current_uid();
242 else 242 else
243 if ((who != current->uid) && !(user = find_user(who))) 243 if (who != current_uid() && !(user = find_user(who)))
244 goto out_unlock; /* No processes for this user */ 244 goto out_unlock; /* No processes for this user */
245 245
246 do_each_thread(g, p) 246 do_each_thread(g, p)
@@ -250,7 +250,7 @@ asmlinkage long sys_getpriority(int which, int who)
250 retval = niceval; 250 retval = niceval;
251 } 251 }
252 while_each_thread(g, p); 252 while_each_thread(g, p);
253 if (who != current->uid) 253 if (who != current_uid())
254 free_uid(user); /* for find_user() */ 254 free_uid(user); /* for find_user() */
255 break; 255 break;
256 } 256 }
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 9d048fa2d902..511031381c33 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1641,7 +1641,7 @@ out:
1641 1641
1642static int test_perm(int mode, int op) 1642static int test_perm(int mode, int op)
1643{ 1643{
1644 if (!current->euid) 1644 if (!current_euid())
1645 mode >>= 6; 1645 mode >>= 6;
1646 else if (in_egroup_p(0)) 1646 else if (in_egroup_p(0))
1647 mode >>= 3; 1647 mode >>= 3;
diff --git a/kernel/timer.c b/kernel/timer.c
index 56becf373c58..b54e4646cee7 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1123,25 +1123,25 @@ asmlinkage long sys_getppid(void)
1123asmlinkage long sys_getuid(void) 1123asmlinkage long sys_getuid(void)
1124{ 1124{
1125 /* Only we change this so SMP safe */ 1125 /* Only we change this so SMP safe */
1126 return current->uid; 1126 return current_uid();
1127} 1127}
1128 1128
1129asmlinkage long sys_geteuid(void) 1129asmlinkage long sys_geteuid(void)
1130{ 1130{
1131 /* Only we change this so SMP safe */ 1131 /* Only we change this so SMP safe */
1132 return current->euid; 1132 return current_euid();
1133} 1133}
1134 1134
1135asmlinkage long sys_getgid(void) 1135asmlinkage long sys_getgid(void)
1136{ 1136{
1137 /* Only we change this so SMP safe */ 1137 /* Only we change this so SMP safe */
1138 return current->gid; 1138 return current_gid();
1139} 1139}
1140 1140
1141asmlinkage long sys_getegid(void) 1141asmlinkage long sys_getegid(void)
1142{ 1142{
1143 /* Only we change this so SMP safe */ 1143 /* Only we change this so SMP safe */
1144 return current->egid; 1144 return current_egid();
1145} 1145}
1146 1146
1147#endif 1147#endif
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 532858fa5b88..f82730adea00 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -38,7 +38,7 @@ static struct user_namespace *clone_user_ns(struct user_namespace *old_ns)
38 } 38 }
39 39
40 /* Reset current->user with a new one */ 40 /* Reset current->user with a new one */
41 new_user = alloc_uid(ns, current->uid); 41 new_user = alloc_uid(ns, current_uid());
42 if (!new_user) { 42 if (!new_user) {
43 free_uid(ns->root_user); 43 free_uid(ns->root_user);
44 kfree(ns); 44 kfree(ns);