aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:19 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:19 -0500
commitc69e8d9c01db2adc503464993c358901c9af9de4 (patch)
treebed94aaa9aeb7a7834d1c880f72b62a11a752c78
parent86a264abe542cfececb4df129bc45a0338d8cdb9 (diff)
CRED: Use RCU to access another task's creds and to release a task's own creds
Use RCU to access another task's creds and to release a task's own creds. This means that it will be possible for the credentials of a task to be replaced without another task (a) requiring a full lock to read them, and (b) seeing deallocated memory. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: James Morris <jmorris@namei.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--arch/ia64/kernel/perfmon.c32
-rw-r--r--drivers/connector/cn_proc.c16
-rw-r--r--fs/binfmt_elf.c8
-rw-r--r--fs/binfmt_elf_fdpic.c8
-rw-r--r--fs/fcntl.c15
-rw-r--r--fs/fuse/dir.c23
-rw-r--r--fs/ioprio.c14
-rw-r--r--fs/proc/array.c32
-rw-r--r--fs/proc/base.c32
-rw-r--r--include/linux/cred.h3
-rw-r--r--kernel/auditsc.c33
-rw-r--r--kernel/cgroup.c16
-rw-r--r--kernel/exit.c14
-rw-r--r--kernel/futex.c22
-rw-r--r--kernel/futex_compat.c7
-rw-r--r--kernel/ptrace.c22
-rw-r--r--kernel/sched.c31
-rw-r--r--kernel/signal.c49
-rw-r--r--kernel/sys.c11
-rw-r--r--kernel/tsacct.c6
-rw-r--r--mm/mempolicy.c8
-rw-r--r--mm/migrate.c8
-rw-r--r--mm/oom_kill.c6
-rw-r--r--security/commoncap.c64
-rw-r--r--security/keys/permission.c10
-rw-r--r--security/keys/process_keys.c24
-rw-r--r--security/selinux/selinuxfs.c13
-rw-r--r--security/smack/smack_lsm.c32
28 files changed, 355 insertions, 204 deletions
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index dd38db46a77a..0e499757309b 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2399,25 +2399,33 @@ error_kmem:
2399static int 2399static int
2400pfm_bad_permissions(struct task_struct *task) 2400pfm_bad_permissions(struct task_struct *task)
2401{ 2401{
2402 const struct cred *tcred;
2402 uid_t uid = current_uid(); 2403 uid_t uid = current_uid();
2403 gid_t gid = current_gid(); 2404 gid_t gid = current_gid();
2405 int ret;
2406
2407 rcu_read_lock();
2408 tcred = __task_cred(task);
2404 2409
2405 /* inspired by ptrace_attach() */ 2410 /* inspired by ptrace_attach() */
2406 DPRINT(("cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n", 2411 DPRINT(("cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n",
2407 uid, 2412 uid,
2408 gid, 2413 gid,
2409 task->euid, 2414 tcred->euid,
2410 task->suid, 2415 tcred->suid,
2411 task->uid, 2416 tcred->uid,
2412 task->egid, 2417 tcred->egid,
2413 task->sgid)); 2418 tcred->sgid));
2414 2419
2415 return (uid != task->euid) 2420 ret = ((uid != tcred->euid)
2416 || (uid != task->suid) 2421 || (uid != tcred->suid)
2417 || (uid != task->uid) 2422 || (uid != tcred->uid)
2418 || (gid != task->egid) 2423 || (gid != tcred->egid)
2419 || (gid != task->sgid) 2424 || (gid != tcred->sgid)
2420 || (gid != task->gid)) && !capable(CAP_SYS_PTRACE); 2425 || (gid != tcred->gid)) && !capable(CAP_SYS_PTRACE);
2426
2427 rcu_read_unlock();
2428 return ret;
2421} 2429}
2422 2430
2423static int 2431static int
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 354c1ff17159..c5afc98e2675 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -106,6 +106,7 @@ void proc_id_connector(struct task_struct *task, int which_id)
106 struct proc_event *ev; 106 struct proc_event *ev;
107 __u8 buffer[CN_PROC_MSG_SIZE]; 107 __u8 buffer[CN_PROC_MSG_SIZE];
108 struct timespec ts; 108 struct timespec ts;
109 const struct cred *cred;
109 110
110 if (atomic_read(&proc_event_num_listeners) < 1) 111 if (atomic_read(&proc_event_num_listeners) < 1)
111 return; 112 return;
@@ -115,14 +116,19 @@ void proc_id_connector(struct task_struct *task, int which_id)
115 ev->what = which_id; 116 ev->what = which_id;
116 ev->event_data.id.process_pid = task->pid; 117 ev->event_data.id.process_pid = task->pid;
117 ev->event_data.id.process_tgid = task->tgid; 118 ev->event_data.id.process_tgid = task->tgid;
119 rcu_read_lock();
120 cred = __task_cred(task);
118 if (which_id == PROC_EVENT_UID) { 121 if (which_id == PROC_EVENT_UID) {
119 ev->event_data.id.r.ruid = task->cred->uid; 122 ev->event_data.id.r.ruid = cred->uid;
120 ev->event_data.id.e.euid = task->cred->euid; 123 ev->event_data.id.e.euid = cred->euid;
121 } else if (which_id == PROC_EVENT_GID) { 124 } else if (which_id == PROC_EVENT_GID) {
122 ev->event_data.id.r.rgid = task->cred->gid; 125 ev->event_data.id.r.rgid = cred->gid;
123 ev->event_data.id.e.egid = task->cred->egid; 126 ev->event_data.id.e.egid = cred->egid;
124 } else 127 } else {
128 rcu_read_unlock();
125 return; 129 return;
130 }
131 rcu_read_unlock();
126 get_seq(&msg->seq, &ev->cpu); 132 get_seq(&msg->seq, &ev->cpu);
127 ktime_get_ts(&ts); /* get high res monotonic timestamp */ 133 ktime_get_ts(&ts); /* get high res monotonic timestamp */
128 put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); 134 put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 0e6655613169..9142ff5dc8e6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1361,6 +1361,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
1361static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, 1361static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1362 struct mm_struct *mm) 1362 struct mm_struct *mm)
1363{ 1363{
1364 const struct cred *cred;
1364 unsigned int i, len; 1365 unsigned int i, len;
1365 1366
1366 /* first copy the parameters from user space */ 1367 /* first copy the parameters from user space */
@@ -1388,8 +1389,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1388 psinfo->pr_zomb = psinfo->pr_sname == 'Z'; 1389 psinfo->pr_zomb = psinfo->pr_sname == 'Z';
1389 psinfo->pr_nice = task_nice(p); 1390 psinfo->pr_nice = task_nice(p);
1390 psinfo->pr_flag = p->flags; 1391 psinfo->pr_flag = p->flags;
1391 SET_UID(psinfo->pr_uid, p->cred->uid); 1392 rcu_read_lock();
1392 SET_GID(psinfo->pr_gid, p->cred->gid); 1393 cred = __task_cred(p);
1394 SET_UID(psinfo->pr_uid, cred->uid);
1395 SET_GID(psinfo->pr_gid, cred->gid);
1396 rcu_read_unlock();
1393 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname)); 1397 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
1394 1398
1395 return 0; 1399 return 0;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 1f6e8c023b4c..45dabd59936f 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1414,6 +1414,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
1414static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, 1414static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1415 struct mm_struct *mm) 1415 struct mm_struct *mm)
1416{ 1416{
1417 const struct cred *cred;
1417 unsigned int i, len; 1418 unsigned int i, len;
1418 1419
1419 /* first copy the parameters from user space */ 1420 /* first copy the parameters from user space */
@@ -1441,8 +1442,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1441 psinfo->pr_zomb = psinfo->pr_sname == 'Z'; 1442 psinfo->pr_zomb = psinfo->pr_sname == 'Z';
1442 psinfo->pr_nice = task_nice(p); 1443 psinfo->pr_nice = task_nice(p);
1443 psinfo->pr_flag = p->flags; 1444 psinfo->pr_flag = p->flags;
1444 SET_UID(psinfo->pr_uid, p->cred->uid); 1445 rcu_read_lock();
1445 SET_GID(psinfo->pr_gid, p->cred->gid); 1446 cred = __task_cred(p);
1447 SET_UID(psinfo->pr_uid, cred->uid);
1448 SET_GID(psinfo->pr_gid, cred->gid);
1449 rcu_read_unlock();
1446 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname)); 1450 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
1447 1451
1448 return 0; 1452 return 0;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index c594cc0e40fb..87c39f1f0817 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -401,10 +401,17 @@ static const long band_table[NSIGPOLL] = {
401static inline int sigio_perm(struct task_struct *p, 401static inline int sigio_perm(struct task_struct *p,
402 struct fown_struct *fown, int sig) 402 struct fown_struct *fown, int sig)
403{ 403{
404 return (((fown->euid == 0) || 404 const struct cred *cred;
405 (fown->euid == p->cred->suid) || (fown->euid == p->cred->uid) || 405 int ret;
406 (fown->uid == p->cred->suid) || (fown->uid == p->cred->uid)) && 406
407 !security_file_send_sigiotask(p, fown, sig)); 407 rcu_read_lock();
408 cred = __task_cred(p);
409 ret = ((fown->euid == 0 ||
410 fown->euid == cred->suid || fown->euid == cred->uid ||
411 fown->uid == cred->suid || fown->uid == cred->uid) &&
412 !security_file_send_sigiotask(p, fown, sig));
413 rcu_read_unlock();
414 return ret;
408} 415}
409 416
410static void send_sigio_to_task(struct task_struct *p, 417static void send_sigio_to_task(struct task_struct *p,
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index e97a98981862..95bc22bdd060 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -869,18 +869,25 @@ int fuse_update_attributes(struct inode *inode, struct kstat *stat,
869 */ 869 */
870int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) 870int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
871{ 871{
872 const struct cred *cred;
873 int ret;
874
872 if (fc->flags & FUSE_ALLOW_OTHER) 875 if (fc->flags & FUSE_ALLOW_OTHER)
873 return 1; 876 return 1;
874 877
875 if (task->cred->euid == fc->user_id && 878 rcu_read_lock();
876 task->cred->suid == fc->user_id && 879 ret = 0;
877 task->cred->uid == fc->user_id && 880 cred = __task_cred(task);
878 task->cred->egid == fc->group_id && 881 if (cred->euid == fc->user_id &&
879 task->cred->sgid == fc->group_id && 882 cred->suid == fc->user_id &&
880 task->cred->gid == fc->group_id) 883 cred->uid == fc->user_id &&
881 return 1; 884 cred->egid == fc->group_id &&
885 cred->sgid == fc->group_id &&
886 cred->gid == fc->group_id)
887 ret = 1;
888 rcu_read_unlock();
882 889
883 return 0; 890 return ret;
884} 891}
885 892
886static int fuse_access(struct inode *inode, int mask) 893static int fuse_access(struct inode *inode, int mask)
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 5112554fd210..3569e0ad86a2 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -31,10 +31,16 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
31{ 31{
32 int err; 32 int err;
33 struct io_context *ioc; 33 struct io_context *ioc;
34 const struct cred *cred = current_cred(), *tcred;
34 35
35 if (task->cred->uid != current_euid() && 36 rcu_read_lock();
36 task->cred->uid != current_uid() && !capable(CAP_SYS_NICE)) 37 tcred = __task_cred(task);
38 if (tcred->uid != cred->euid &&
39 tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) {
40 rcu_read_unlock();
37 return -EPERM; 41 return -EPERM;
42 }
43 rcu_read_unlock();
38 44
39 err = security_task_setioprio(task, ioprio); 45 err = security_task_setioprio(task, ioprio);
40 if (err) 46 if (err)
@@ -131,7 +137,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
131 break; 137 break;
132 138
133 do_each_thread(g, p) { 139 do_each_thread(g, p) {
134 if (p->cred->uid != who) 140 if (__task_cred(p)->uid != who)
135 continue; 141 continue;
136 ret = set_task_ioprio(p, ioprio); 142 ret = set_task_ioprio(p, ioprio);
137 if (ret) 143 if (ret)
@@ -224,7 +230,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
224 break; 230 break;
225 231
226 do_each_thread(g, p) { 232 do_each_thread(g, p) {
227 if (p->cred->uid != user->uid) 233 if (__task_cred(p)->uid != user->uid)
228 continue; 234 continue;
229 tmpio = get_task_ioprio(p); 235 tmpio = get_task_ioprio(p);
230 if (tmpio < 0) 236 if (tmpio < 0)
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 62fe9b2009b6..7e4877d9dcb5 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -159,6 +159,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
159 struct group_info *group_info; 159 struct group_info *group_info;
160 int g; 160 int g;
161 struct fdtable *fdt = NULL; 161 struct fdtable *fdt = NULL;
162 const struct cred *cred;
162 pid_t ppid, tpid; 163 pid_t ppid, tpid;
163 164
164 rcu_read_lock(); 165 rcu_read_lock();
@@ -170,6 +171,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
170 if (tracer) 171 if (tracer)
171 tpid = task_pid_nr_ns(tracer, ns); 172 tpid = task_pid_nr_ns(tracer, ns);
172 } 173 }
174 cred = get_cred((struct cred *) __task_cred(p));
173 seq_printf(m, 175 seq_printf(m,
174 "State:\t%s\n" 176 "State:\t%s\n"
175 "Tgid:\t%d\n" 177 "Tgid:\t%d\n"
@@ -182,8 +184,8 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
182 task_tgid_nr_ns(p, ns), 184 task_tgid_nr_ns(p, ns),
183 pid_nr_ns(pid, ns), 185 pid_nr_ns(pid, ns),
184 ppid, tpid, 186 ppid, tpid,
185 p->cred->uid, p->cred->euid, p->cred->suid, p->cred->fsuid, 187 cred->uid, cred->euid, cred->suid, cred->fsuid,
186 p->cred->gid, p->cred->egid, p->cred->sgid, p->cred->fsgid); 188 cred->gid, cred->egid, cred->sgid, cred->fsgid);
187 189
188 task_lock(p); 190 task_lock(p);
189 if (p->files) 191 if (p->files)
@@ -194,13 +196,12 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
194 fdt ? fdt->max_fds : 0); 196 fdt ? fdt->max_fds : 0);
195 rcu_read_unlock(); 197 rcu_read_unlock();
196 198
197 group_info = p->cred->group_info; 199 group_info = cred->group_info;
198 get_group_info(group_info);
199 task_unlock(p); 200 task_unlock(p);
200 201
201 for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++) 202 for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
202 seq_printf(m, "%d ", GROUP_AT(group_info, g)); 203 seq_printf(m, "%d ", GROUP_AT(group_info, g));
203 put_group_info(group_info); 204 put_cred(cred);
204 205
205 seq_printf(m, "\n"); 206 seq_printf(m, "\n");
206} 207}
@@ -262,7 +263,7 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
262 blocked = p->blocked; 263 blocked = p->blocked;
263 collect_sigign_sigcatch(p, &ignored, &caught); 264 collect_sigign_sigcatch(p, &ignored, &caught);
264 num_threads = atomic_read(&p->signal->count); 265 num_threads = atomic_read(&p->signal->count);
265 qsize = atomic_read(&p->cred->user->sigpending); 266 qsize = atomic_read(&__task_cred(p)->user->sigpending);
266 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur; 267 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
267 unlock_task_sighand(p, &flags); 268 unlock_task_sighand(p, &flags);
268 } 269 }
@@ -293,12 +294,21 @@ static void render_cap_t(struct seq_file *m, const char *header,
293 294
294static inline void task_cap(struct seq_file *m, struct task_struct *p) 295static inline void task_cap(struct seq_file *m, struct task_struct *p)
295{ 296{
296 struct cred *cred = p->cred; 297 const struct cred *cred;
298 kernel_cap_t cap_inheritable, cap_permitted, cap_effective, cap_bset;
297 299
298 render_cap_t(m, "CapInh:\t", &cred->cap_inheritable); 300 rcu_read_lock();
299 render_cap_t(m, "CapPrm:\t", &cred->cap_permitted); 301 cred = __task_cred(p);
300 render_cap_t(m, "CapEff:\t", &cred->cap_effective); 302 cap_inheritable = cred->cap_inheritable;
301 render_cap_t(m, "CapBnd:\t", &cred->cap_bset); 303 cap_permitted = cred->cap_permitted;
304 cap_effective = cred->cap_effective;
305 cap_bset = cred->cap_bset;
306 rcu_read_unlock();
307
308 render_cap_t(m, "CapInh:\t", &cap_inheritable);
309 render_cap_t(m, "CapPrm:\t", &cap_permitted);
310 render_cap_t(m, "CapEff:\t", &cap_effective);
311 render_cap_t(m, "CapBnd:\t", &cap_bset);
302} 312}
303 313
304static inline void task_context_switch_counts(struct seq_file *m, 314static inline void task_context_switch_counts(struct seq_file *m,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6862b360c36c..cf42c42cbfbb 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1406,6 +1406,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
1406{ 1406{
1407 struct inode * inode; 1407 struct inode * inode;
1408 struct proc_inode *ei; 1408 struct proc_inode *ei;
1409 const struct cred *cred;
1409 1410
1410 /* We need a new inode */ 1411 /* We need a new inode */
1411 1412
@@ -1428,8 +1429,11 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
1428 inode->i_uid = 0; 1429 inode->i_uid = 0;
1429 inode->i_gid = 0; 1430 inode->i_gid = 0;
1430 if (task_dumpable(task)) { 1431 if (task_dumpable(task)) {
1431 inode->i_uid = task->cred->euid; 1432 rcu_read_lock();
1432 inode->i_gid = task->cred->egid; 1433 cred = __task_cred(task);
1434 inode->i_uid = cred->euid;
1435 inode->i_gid = cred->egid;
1436 rcu_read_unlock();
1433 } 1437 }
1434 security_task_to_inode(task, inode); 1438 security_task_to_inode(task, inode);
1435 1439
@@ -1445,6 +1449,8 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
1445{ 1449{
1446 struct inode *inode = dentry->d_inode; 1450 struct inode *inode = dentry->d_inode;
1447 struct task_struct *task; 1451 struct task_struct *task;
1452 const struct cred *cred;
1453
1448 generic_fillattr(inode, stat); 1454 generic_fillattr(inode, stat);
1449 1455
1450 rcu_read_lock(); 1456 rcu_read_lock();
@@ -1454,8 +1460,9 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
1454 if (task) { 1460 if (task) {
1455 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || 1461 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
1456 task_dumpable(task)) { 1462 task_dumpable(task)) {
1457 stat->uid = task->cred->euid; 1463 cred = __task_cred(task);
1458 stat->gid = task->cred->egid; 1464 stat->uid = cred->euid;
1465 stat->gid = cred->egid;
1459 } 1466 }
1460 } 1467 }
1461 rcu_read_unlock(); 1468 rcu_read_unlock();
@@ -1483,11 +1490,16 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
1483{ 1490{
1484 struct inode *inode = dentry->d_inode; 1491 struct inode *inode = dentry->d_inode;
1485 struct task_struct *task = get_proc_task(inode); 1492 struct task_struct *task = get_proc_task(inode);
1493 const struct cred *cred;
1494
1486 if (task) { 1495 if (task) {
1487 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || 1496 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
1488 task_dumpable(task)) { 1497 task_dumpable(task)) {
1489 inode->i_uid = task->cred->euid; 1498 rcu_read_lock();
1490 inode->i_gid = task->cred->egid; 1499 cred = __task_cred(task);
1500 inode->i_uid = cred->euid;
1501 inode->i_gid = cred->egid;
1502 rcu_read_unlock();
1491 } else { 1503 } else {
1492 inode->i_uid = 0; 1504 inode->i_uid = 0;
1493 inode->i_gid = 0; 1505 inode->i_gid = 0;
@@ -1649,6 +1661,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1649 struct task_struct *task = get_proc_task(inode); 1661 struct task_struct *task = get_proc_task(inode);
1650 int fd = proc_fd(inode); 1662 int fd = proc_fd(inode);
1651 struct files_struct *files; 1663 struct files_struct *files;
1664 const struct cred *cred;
1652 1665
1653 if (task) { 1666 if (task) {
1654 files = get_files_struct(task); 1667 files = get_files_struct(task);
@@ -1658,8 +1671,11 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1658 rcu_read_unlock(); 1671 rcu_read_unlock();
1659 put_files_struct(files); 1672 put_files_struct(files);
1660 if (task_dumpable(task)) { 1673 if (task_dumpable(task)) {
1661 inode->i_uid = task->cred->euid; 1674 rcu_read_lock();
1662 inode->i_gid = task->cred->egid; 1675 cred = __task_cred(task);
1676 inode->i_uid = cred->euid;
1677 inode->i_gid = cred->egid;
1678 rcu_read_unlock();
1663 } else { 1679 } else {
1664 inode->i_uid = 0; 1680 inode->i_uid = 0;
1665 inode->i_gid = 0; 1681 inode->i_gid = 0;
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 4221ec6000c1..166ce4ddba64 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -147,8 +147,9 @@ static inline struct cred *get_cred(struct cred *cred)
147 * Release a reference to a set of credentials, deleting them when the last ref 147 * Release a reference to a set of credentials, deleting them when the last ref
148 * is released. 148 * is released.
149 */ 149 */
150static inline void put_cred(struct cred *cred) 150static inline void put_cred(const struct cred *_cred)
151{ 151{
152 struct cred *cred = (struct cred *) _cred;
152 if (atomic_dec_and_test(&(cred)->usage)) 153 if (atomic_dec_and_test(&(cred)->usage))
153 __put_cred(cred); 154 __put_cred(cred);
154} 155}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2febf5165fad..ae8ef88ade3f 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -447,7 +447,7 @@ static int audit_filter_rules(struct task_struct *tsk,
447 struct audit_names *name, 447 struct audit_names *name,
448 enum audit_state *state) 448 enum audit_state *state)
449{ 449{
450 struct cred *cred = tsk->cred; 450 const struct cred *cred = get_task_cred(tsk);
451 int i, j, need_sid = 1; 451 int i, j, need_sid = 1;
452 u32 sid; 452 u32 sid;
453 453
@@ -642,8 +642,10 @@ static int audit_filter_rules(struct task_struct *tsk,
642 break; 642 break;
643 } 643 }
644 644
645 if (!result) 645 if (!result) {
646 put_cred(cred);
646 return 0; 647 return 0;
648 }
647 } 649 }
648 if (rule->filterkey && ctx) 650 if (rule->filterkey && ctx)
649 ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); 651 ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
@@ -651,6 +653,7 @@ static int audit_filter_rules(struct task_struct *tsk,
651 case AUDIT_NEVER: *state = AUDIT_DISABLED; break; 653 case AUDIT_NEVER: *state = AUDIT_DISABLED; break;
652 case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; 654 case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break;
653 } 655 }
656 put_cred(cred);
654 return 1; 657 return 1;
655} 658}
656 659
@@ -1229,7 +1232,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
1229 1232
1230static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) 1233static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
1231{ 1234{
1232 struct cred *cred = tsk->cred; 1235 const struct cred *cred;
1233 int i, call_panic = 0; 1236 int i, call_panic = 0;
1234 struct audit_buffer *ab; 1237 struct audit_buffer *ab;
1235 struct audit_aux_data *aux; 1238 struct audit_aux_data *aux;
@@ -1239,13 +1242,14 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
1239 context->pid = tsk->pid; 1242 context->pid = tsk->pid;
1240 if (!context->ppid) 1243 if (!context->ppid)
1241 context->ppid = sys_getppid(); 1244 context->ppid = sys_getppid();
1242 context->uid = cred->uid; 1245 cred = current_cred();
1243 context->gid = cred->gid; 1246 context->uid = cred->uid;
1244 context->euid = cred->euid; 1247 context->gid = cred->gid;
1245 context->suid = cred->suid; 1248 context->euid = cred->euid;
1249 context->suid = cred->suid;
1246 context->fsuid = cred->fsuid; 1250 context->fsuid = cred->fsuid;
1247 context->egid = cred->egid; 1251 context->egid = cred->egid;
1248 context->sgid = cred->sgid; 1252 context->sgid = cred->sgid;
1249 context->fsgid = cred->fsgid; 1253 context->fsgid = cred->fsgid;
1250 context->personality = tsk->personality; 1254 context->personality = tsk->personality;
1251 1255
@@ -2088,7 +2092,7 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
2088 audit_log_format(ab, "login pid=%d uid=%u " 2092 audit_log_format(ab, "login pid=%d uid=%u "
2089 "old auid=%u new auid=%u" 2093 "old auid=%u new auid=%u"
2090 " old ses=%u new ses=%u", 2094 " old ses=%u new ses=%u",
2091 task->pid, task->cred->uid, 2095 task->pid, task_uid(task),
2092 task->loginuid, loginuid, 2096 task->loginuid, loginuid,
2093 task->sessionid, sessionid); 2097 task->sessionid, sessionid);
2094 audit_log_end(ab); 2098 audit_log_end(ab);
@@ -2471,7 +2475,7 @@ void __audit_ptrace(struct task_struct *t)
2471 2475
2472 context->target_pid = t->pid; 2476 context->target_pid = t->pid;
2473 context->target_auid = audit_get_loginuid(t); 2477 context->target_auid = audit_get_loginuid(t);
2474 context->target_uid = t->cred->uid; 2478 context->target_uid = task_uid(t);
2475 context->target_sessionid = audit_get_sessionid(t); 2479 context->target_sessionid = audit_get_sessionid(t);
2476 security_task_getsecid(t, &context->target_sid); 2480 security_task_getsecid(t, &context->target_sid);
2477 memcpy(context->target_comm, t->comm, TASK_COMM_LEN); 2481 memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
@@ -2490,6 +2494,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
2490 struct audit_aux_data_pids *axp; 2494 struct audit_aux_data_pids *axp;
2491 struct task_struct *tsk = current; 2495 struct task_struct *tsk = current;
2492 struct audit_context *ctx = tsk->audit_context; 2496 struct audit_context *ctx = tsk->audit_context;
2497 uid_t uid = current_uid(), t_uid = task_uid(t);
2493 2498
2494 if (audit_pid && t->tgid == audit_pid) { 2499 if (audit_pid && t->tgid == audit_pid) {
2495 if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { 2500 if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
@@ -2497,7 +2502,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
2497 if (tsk->loginuid != -1) 2502 if (tsk->loginuid != -1)
2498 audit_sig_uid = tsk->loginuid; 2503 audit_sig_uid = tsk->loginuid;
2499 else 2504 else
2500 audit_sig_uid = tsk->cred->uid; 2505 audit_sig_uid = uid;
2501 security_task_getsecid(tsk, &audit_sig_sid); 2506 security_task_getsecid(tsk, &audit_sig_sid);
2502 } 2507 }
2503 if (!audit_signals || audit_dummy_context()) 2508 if (!audit_signals || audit_dummy_context())
@@ -2509,7 +2514,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
2509 if (!ctx->target_pid) { 2514 if (!ctx->target_pid) {
2510 ctx->target_pid = t->tgid; 2515 ctx->target_pid = t->tgid;
2511 ctx->target_auid = audit_get_loginuid(t); 2516 ctx->target_auid = audit_get_loginuid(t);
2512 ctx->target_uid = t->cred->uid; 2517 ctx->target_uid = t_uid;
2513 ctx->target_sessionid = audit_get_sessionid(t); 2518 ctx->target_sessionid = audit_get_sessionid(t);
2514 security_task_getsecid(t, &ctx->target_sid); 2519 security_task_getsecid(t, &ctx->target_sid);
2515 memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); 2520 memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
@@ -2530,7 +2535,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
2530 2535
2531 axp->target_pid[axp->pid_count] = t->tgid; 2536 axp->target_pid[axp->pid_count] = t->tgid;
2532 axp->target_auid[axp->pid_count] = audit_get_loginuid(t); 2537 axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
2533 axp->target_uid[axp->pid_count] = t->cred->uid; 2538 axp->target_uid[axp->pid_count] = t_uid;
2534 axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); 2539 axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
2535 security_task_getsecid(t, &axp->target_sid[axp->pid_count]); 2540 security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
2536 memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); 2541 memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index e210526e6401..a512a75a5560 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1279,7 +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 const struct cred *cred = current_cred(), *tcred;
1283 int ret; 1283 int ret;
1284 1284
1285 if (pid) { 1285 if (pid) {
@@ -1289,16 +1289,16 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
1289 rcu_read_unlock(); 1289 rcu_read_unlock();
1290 return -ESRCH; 1290 return -ESRCH;
1291 } 1291 }
1292 get_task_struct(tsk);
1293 rcu_read_unlock();
1294 1292
1295 euid = current_euid(); 1293 tcred = __task_cred(tsk);
1296 if (euid && 1294 if (cred->euid &&
1297 euid != tsk->cred->uid && 1295 cred->euid != tcred->uid &&
1298 euid != tsk->cred->suid) { 1296 cred->euid != tcred->suid) {
1299 put_task_struct(tsk); 1297 rcu_read_unlock();
1300 return -EACCES; 1298 return -EACCES;
1301 } 1299 }
1300 get_task_struct(tsk);
1301 rcu_read_unlock();
1302 } else { 1302 } else {
1303 tsk = current; 1303 tsk = current;
1304 get_task_struct(tsk); 1304 get_task_struct(tsk);
diff --git a/kernel/exit.c b/kernel/exit.c
index e0f6e1892fb9..bbc22530f2c1 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -160,7 +160,10 @@ void release_task(struct task_struct * p)
160 int zap_leader; 160 int zap_leader;
161repeat: 161repeat:
162 tracehook_prepare_release_task(p); 162 tracehook_prepare_release_task(p);
163 atomic_dec(&p->cred->user->processes); 163 /* don't need to get the RCU readlock here - the process is dead and
164 * can't be modifying its own credentials */
165 atomic_dec(&__task_cred(p)->user->processes);
166
164 proc_flush_task(p); 167 proc_flush_task(p);
165 write_lock_irq(&tasklist_lock); 168 write_lock_irq(&tasklist_lock);
166 tracehook_finish_release_task(p); 169 tracehook_finish_release_task(p);
@@ -1267,12 +1270,12 @@ static int wait_task_zombie(struct task_struct *p, int options,
1267 unsigned long state; 1270 unsigned long state;
1268 int retval, status, traced; 1271 int retval, status, traced;
1269 pid_t pid = task_pid_vnr(p); 1272 pid_t pid = task_pid_vnr(p);
1273 uid_t uid = __task_cred(p)->uid;
1270 1274
1271 if (!likely(options & WEXITED)) 1275 if (!likely(options & WEXITED))
1272 return 0; 1276 return 0;
1273 1277
1274 if (unlikely(options & WNOWAIT)) { 1278 if (unlikely(options & WNOWAIT)) {
1275 uid_t uid = p->cred->uid;
1276 int exit_code = p->exit_code; 1279 int exit_code = p->exit_code;
1277 int why, status; 1280 int why, status;
1278 1281
@@ -1393,7 +1396,7 @@ static int wait_task_zombie(struct task_struct *p, int options,
1393 if (!retval && infop) 1396 if (!retval && infop)
1394 retval = put_user(pid, &infop->si_pid); 1397 retval = put_user(pid, &infop->si_pid);
1395 if (!retval && infop) 1398 if (!retval && infop)
1396 retval = put_user(p->cred->uid, &infop->si_uid); 1399 retval = put_user(uid, &infop->si_uid);
1397 if (!retval) 1400 if (!retval)
1398 retval = pid; 1401 retval = pid;
1399 1402
@@ -1458,7 +1461,8 @@ static int wait_task_stopped(int ptrace, struct task_struct *p,
1458 if (!unlikely(options & WNOWAIT)) 1461 if (!unlikely(options & WNOWAIT))
1459 p->exit_code = 0; 1462 p->exit_code = 0;
1460 1463
1461 uid = p->cred->uid; 1464 /* don't need the RCU readlock here as we're holding a spinlock */
1465 uid = __task_cred(p)->uid;
1462unlock_sig: 1466unlock_sig:
1463 spin_unlock_irq(&p->sighand->siglock); 1467 spin_unlock_irq(&p->sighand->siglock);
1464 if (!exit_code) 1468 if (!exit_code)
@@ -1532,10 +1536,10 @@ static int wait_task_continued(struct task_struct *p, int options,
1532 } 1536 }
1533 if (!unlikely(options & WNOWAIT)) 1537 if (!unlikely(options & WNOWAIT))
1534 p->signal->flags &= ~SIGNAL_STOP_CONTINUED; 1538 p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
1539 uid = __task_cred(p)->uid;
1535 spin_unlock_irq(&p->sighand->siglock); 1540 spin_unlock_irq(&p->sighand->siglock);
1536 1541
1537 pid = task_pid_vnr(p); 1542 pid = task_pid_vnr(p);
1538 uid = p->cred->uid;
1539 get_task_struct(p); 1543 get_task_struct(p);
1540 read_unlock(&tasklist_lock); 1544 read_unlock(&tasklist_lock);
1541 1545
diff --git a/kernel/futex.c b/kernel/futex.c
index 28421d8210b8..4fe790e89d0f 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -439,15 +439,20 @@ 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 const struct cred *cred = current_cred(), *pcred;
443 443
444 rcu_read_lock(); 444 rcu_read_lock();
445 p = find_task_by_vpid(pid); 445 p = find_task_by_vpid(pid);
446 if (!p || (euid != p->cred->euid && 446 if (!p) {
447 euid != p->cred->uid))
448 p = ERR_PTR(-ESRCH); 447 p = ERR_PTR(-ESRCH);
449 else 448 } else {
450 get_task_struct(p); 449 pcred = __task_cred(p);
450 if (cred->euid != pcred->euid &&
451 cred->euid != pcred->uid)
452 p = ERR_PTR(-ESRCH);
453 else
454 get_task_struct(p);
455 }
451 456
452 rcu_read_unlock(); 457 rcu_read_unlock();
453 458
@@ -1831,7 +1836,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
1831{ 1836{
1832 struct robust_list_head __user *head; 1837 struct robust_list_head __user *head;
1833 unsigned long ret; 1838 unsigned long ret;
1834 uid_t euid = current_euid(); 1839 const struct cred *cred = current_cred(), *pcred;
1835 1840
1836 if (!futex_cmpxchg_enabled) 1841 if (!futex_cmpxchg_enabled)
1837 return -ENOSYS; 1842 return -ENOSYS;
@@ -1847,8 +1852,9 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
1847 if (!p) 1852 if (!p)
1848 goto err_unlock; 1853 goto err_unlock;
1849 ret = -EPERM; 1854 ret = -EPERM;
1850 if (euid != p->cred->euid && 1855 pcred = __task_cred(p);
1851 euid != p->cred->uid && 1856 if (cred->euid != pcred->euid &&
1857 cred->euid != pcred->uid &&
1852 !capable(CAP_SYS_PTRACE)) 1858 !capable(CAP_SYS_PTRACE))
1853 goto err_unlock; 1859 goto err_unlock;
1854 head = p->robust_list; 1860 head = p->robust_list;
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 2c3fd5ed34f5..d607a5b9ee29 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -135,7 +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 const struct cred *cred = current_cred(), *pcred;
139 139
140 if (!futex_cmpxchg_enabled) 140 if (!futex_cmpxchg_enabled)
141 return -ENOSYS; 141 return -ENOSYS;
@@ -151,8 +151,9 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
151 if (!p) 151 if (!p)
152 goto err_unlock; 152 goto err_unlock;
153 ret = -EPERM; 153 ret = -EPERM;
154 if (euid != p->cred->euid && 154 pcred = __task_cred(p);
155 euid != p->cred->uid && 155 if (cred->euid != pcred->euid &&
156 cred->euid != pcred->uid &&
156 !capable(CAP_SYS_PTRACE)) 157 !capable(CAP_SYS_PTRACE))
157 goto err_unlock; 158 goto err_unlock;
158 head = p->compat_robust_list; 159 head = p->compat_robust_list;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 49849d12dd12..b9d5f4e4f6a4 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -115,7 +115,7 @@ int ptrace_check_attach(struct task_struct *child, int kill)
115 115
116int __ptrace_may_access(struct task_struct *task, unsigned int mode) 116int __ptrace_may_access(struct task_struct *task, unsigned int mode)
117{ 117{
118 struct cred *cred = current->cred, *tcred = task->cred; 118 const struct cred *cred = current_cred(), *tcred;
119 119
120 /* May we inspect the given task? 120 /* May we inspect the given task?
121 * This check is used both for attaching with ptrace 121 * This check is used both for attaching with ptrace
@@ -125,19 +125,23 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
125 * because setting up the necessary parent/child relationship 125 * because setting up the necessary parent/child relationship
126 * or halting the specified task is impossible. 126 * or halting the specified task is impossible.
127 */ 127 */
128 uid_t uid = cred->uid;
129 gid_t gid = cred->gid;
130 int dumpable = 0; 128 int dumpable = 0;
131 /* Don't let security modules deny introspection */ 129 /* Don't let security modules deny introspection */
132 if (task == current) 130 if (task == current)
133 return 0; 131 return 0;
134 if ((uid != tcred->euid || 132 rcu_read_lock();
135 uid != tcred->suid || 133 tcred = __task_cred(task);
136 uid != tcred->uid || 134 if ((cred->uid != tcred->euid ||
137 gid != tcred->egid || 135 cred->uid != tcred->suid ||
138 gid != tcred->sgid || 136 cred->uid != tcred->uid ||
139 gid != tcred->gid) && !capable(CAP_SYS_PTRACE)) 137 cred->gid != tcred->egid ||
138 cred->gid != tcred->sgid ||
139 cred->gid != tcred->gid) &&
140 !capable(CAP_SYS_PTRACE)) {
141 rcu_read_unlock();
140 return -EPERM; 142 return -EPERM;
143 }
144 rcu_read_unlock();
141 smp_rmb(); 145 smp_rmb();
142 if (task->mm) 146 if (task->mm)
143 dumpable = get_dumpable(task->mm); 147 dumpable = get_dumpable(task->mm);
diff --git a/kernel/sched.c b/kernel/sched.c
index 733c59e645aa..92992e287b10 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -345,7 +345,9 @@ static inline struct task_group *task_group(struct task_struct *p)
345 struct task_group *tg; 345 struct task_group *tg;
346 346
347#ifdef CONFIG_USER_SCHED 347#ifdef CONFIG_USER_SCHED
348 tg = p->cred->user->tg; 348 rcu_read_lock();
349 tg = __task_cred(p)->user->tg;
350 rcu_read_unlock();
349#elif defined(CONFIG_CGROUP_SCHED) 351#elif defined(CONFIG_CGROUP_SCHED)
350 tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), 352 tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id),
351 struct task_group, css); 353 struct task_group, css);
@@ -5121,6 +5123,22 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
5121 set_load_weight(p); 5123 set_load_weight(p);
5122} 5124}
5123 5125
5126/*
5127 * check the target process has a UID that matches the current process's
5128 */
5129static bool check_same_owner(struct task_struct *p)
5130{
5131 const struct cred *cred = current_cred(), *pcred;
5132 bool match;
5133
5134 rcu_read_lock();
5135 pcred = __task_cred(p);
5136 match = (cred->euid == pcred->euid ||
5137 cred->euid == pcred->uid);
5138 rcu_read_unlock();
5139 return match;
5140}
5141
5124static int __sched_setscheduler(struct task_struct *p, int policy, 5142static int __sched_setscheduler(struct task_struct *p, int policy,
5125 struct sched_param *param, bool user) 5143 struct sched_param *param, bool user)
5126{ 5144{
@@ -5128,7 +5146,6 @@ static int __sched_setscheduler(struct task_struct *p, int policy,
5128 unsigned long flags; 5146 unsigned long flags;
5129 const struct sched_class *prev_class = p->sched_class; 5147 const struct sched_class *prev_class = p->sched_class;
5130 struct rq *rq; 5148 struct rq *rq;
5131 uid_t euid;
5132 5149
5133 /* may grab non-irq protected spin_locks */ 5150 /* may grab non-irq protected spin_locks */
5134 BUG_ON(in_interrupt()); 5151 BUG_ON(in_interrupt());
@@ -5181,9 +5198,7 @@ recheck:
5181 return -EPERM; 5198 return -EPERM;
5182 5199
5183 /* can't change other user's priorities */ 5200 /* can't change other user's priorities */
5184 euid = current_euid(); 5201 if (!check_same_owner(p))
5185 if (euid != p->cred->euid &&
5186 euid != p->cred->uid)
5187 return -EPERM; 5202 return -EPERM;
5188 } 5203 }
5189 5204
@@ -5394,7 +5409,6 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)
5394 cpumask_t cpus_allowed; 5409 cpumask_t cpus_allowed;
5395 cpumask_t new_mask = *in_mask; 5410 cpumask_t new_mask = *in_mask;
5396 struct task_struct *p; 5411 struct task_struct *p;
5397 uid_t euid;
5398 int retval; 5412 int retval;
5399 5413
5400 get_online_cpus(); 5414 get_online_cpus();
@@ -5415,11 +5429,8 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)
5415 get_task_struct(p); 5429 get_task_struct(p);
5416 read_unlock(&tasklist_lock); 5430 read_unlock(&tasklist_lock);
5417 5431
5418 euid = current_euid();
5419 retval = -EPERM; 5432 retval = -EPERM;
5420 if (euid != p->cred->euid && 5433 if (!check_same_owner(p) && !capable(CAP_SYS_NICE))
5421 euid != p->cred->uid &&
5422 !capable(CAP_SYS_NICE))
5423 goto out_unlock; 5434 goto out_unlock;
5424 5435
5425 retval = security_task_setscheduler(p, 0, NULL); 5436 retval = security_task_setscheduler(p, 0, NULL);
diff --git a/kernel/signal.c b/kernel/signal.c
index 80e8a6489f97..84989124bafb 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -177,6 +177,11 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
177 return sig; 177 return sig;
178} 178}
179 179
180/*
181 * allocate a new signal queue record
182 * - this may be called without locks if and only if t == current, otherwise an
183 * appopriate lock must be held to protect t's user_struct
184 */
180static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, 185static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
181 int override_rlimit) 186 int override_rlimit)
182{ 187{
@@ -184,11 +189,12 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
184 struct user_struct *user; 189 struct user_struct *user;
185 190
186 /* 191 /*
187 * In order to avoid problems with "switch_user()", we want to make 192 * We won't get problems with the target's UID changing under us
188 * sure that the compiler doesn't re-load "t->user" 193 * because changing it requires RCU be used, and if t != current, the
194 * caller must be holding the RCU readlock (by way of a spinlock) and
195 * we use RCU protection here
189 */ 196 */
190 user = t->cred->user; 197 user = __task_cred(t)->user;
191 barrier();
192 atomic_inc(&user->sigpending); 198 atomic_inc(&user->sigpending);
193 if (override_rlimit || 199 if (override_rlimit ||
194 atomic_read(&user->sigpending) <= 200 atomic_read(&user->sigpending) <=
@@ -562,12 +568,13 @@ static int rm_from_queue(unsigned long mask, struct sigpending *s)
562 568
563/* 569/*
564 * Bad permissions for sending the signal 570 * Bad permissions for sending the signal
571 * - the caller must hold at least the RCU read lock
565 */ 572 */
566static int check_kill_permission(int sig, struct siginfo *info, 573static int check_kill_permission(int sig, struct siginfo *info,
567 struct task_struct *t) 574 struct task_struct *t)
568{ 575{
576 const struct cred *cred = current_cred(), *tcred;
569 struct pid *sid; 577 struct pid *sid;
570 uid_t uid, euid;
571 int error; 578 int error;
572 579
573 if (!valid_signal(sig)) 580 if (!valid_signal(sig))
@@ -580,10 +587,11 @@ static int check_kill_permission(int sig, struct siginfo *info,
580 if (error) 587 if (error)
581 return error; 588 return error;
582 589
583 uid = current_uid(); 590 tcred = __task_cred(t);
584 euid = current_euid(); 591 if ((cred->euid ^ tcred->suid) &&
585 if ((euid ^ t->cred->suid) && (euid ^ t->cred->uid) && 592 (cred->euid ^ tcred->uid) &&
586 (uid ^ t->cred->suid) && (uid ^ t->cred->uid) && 593 (cred->uid ^ tcred->suid) &&
594 (cred->uid ^ tcred->uid) &&
587 !capable(CAP_KILL)) { 595 !capable(CAP_KILL)) {
588 switch (sig) { 596 switch (sig) {
589 case SIGCONT: 597 case SIGCONT:
@@ -1011,6 +1019,10 @@ struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long
1011 return sighand; 1019 return sighand;
1012} 1020}
1013 1021
1022/*
1023 * send signal info to all the members of a group
1024 * - the caller must hold the RCU read lock at least
1025 */
1014int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) 1026int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1015{ 1027{
1016 unsigned long flags; 1028 unsigned long flags;
@@ -1032,8 +1044,8 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1032/* 1044/*
1033 * __kill_pgrp_info() sends a signal to a process group: this is what the tty 1045 * __kill_pgrp_info() sends a signal to a process group: this is what the tty
1034 * control characters do (^C, ^Z etc) 1046 * control characters do (^C, ^Z etc)
1047 * - the caller must hold at least a readlock on tasklist_lock
1035 */ 1048 */
1036
1037int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) 1049int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
1038{ 1050{
1039 struct task_struct *p = NULL; 1051 struct task_struct *p = NULL;
@@ -1089,6 +1101,7 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1089{ 1101{
1090 int ret = -EINVAL; 1102 int ret = -EINVAL;
1091 struct task_struct *p; 1103 struct task_struct *p;
1104 const struct cred *pcred;
1092 1105
1093 if (!valid_signal(sig)) 1106 if (!valid_signal(sig))
1094 return ret; 1107 return ret;
@@ -1099,9 +1112,11 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1099 ret = -ESRCH; 1112 ret = -ESRCH;
1100 goto out_unlock; 1113 goto out_unlock;
1101 } 1114 }
1102 if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info))) 1115 pcred = __task_cred(p);
1103 && (euid != p->cred->suid) && (euid != p->cred->uid) 1116 if ((info == SEND_SIG_NOINFO ||
1104 && (uid != p->cred->suid) && (uid != p->cred->uid)) { 1117 (!is_si_special(info) && SI_FROMUSER(info))) &&
1118 euid != pcred->suid && euid != pcred->uid &&
1119 uid != pcred->suid && uid != pcred->uid) {
1105 ret = -EPERM; 1120 ret = -EPERM;
1106 goto out_unlock; 1121 goto out_unlock;
1107 } 1122 }
@@ -1372,10 +1387,9 @@ int do_notify_parent(struct task_struct *tsk, int sig)
1372 */ 1387 */
1373 rcu_read_lock(); 1388 rcu_read_lock();
1374 info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); 1389 info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
1390 info.si_uid = __task_cred(tsk)->uid;
1375 rcu_read_unlock(); 1391 rcu_read_unlock();
1376 1392
1377 info.si_uid = tsk->cred->uid;
1378
1379 thread_group_cputime(tsk, &cputime); 1393 thread_group_cputime(tsk, &cputime);
1380 info.si_utime = cputime_to_jiffies(cputime.utime); 1394 info.si_utime = cputime_to_jiffies(cputime.utime);
1381 info.si_stime = cputime_to_jiffies(cputime.stime); 1395 info.si_stime = cputime_to_jiffies(cputime.stime);
@@ -1443,10 +1457,9 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why)
1443 */ 1457 */
1444 rcu_read_lock(); 1458 rcu_read_lock();
1445 info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); 1459 info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
1460 info.si_uid = __task_cred(tsk)->uid;
1446 rcu_read_unlock(); 1461 rcu_read_unlock();
1447 1462
1448 info.si_uid = tsk->cred->uid;
1449
1450 info.si_utime = cputime_to_clock_t(tsk->utime); 1463 info.si_utime = cputime_to_clock_t(tsk->utime);
1451 info.si_stime = cputime_to_clock_t(tsk->stime); 1464 info.si_stime = cputime_to_clock_t(tsk->stime);
1452 1465
@@ -1713,7 +1726,7 @@ static int ptrace_signal(int signr, siginfo_t *info,
1713 info->si_errno = 0; 1726 info->si_errno = 0;
1714 info->si_code = SI_USER; 1727 info->si_code = SI_USER;
1715 info->si_pid = task_pid_vnr(current->parent); 1728 info->si_pid = task_pid_vnr(current->parent);
1716 info->si_uid = current->parent->cred->uid; 1729 info->si_uid = task_uid(current->parent);
1717 } 1730 }
1718 1731
1719 /* If the (new) signal is now blocked, requeue it. */ 1732 /* If the (new) signal is now blocked, requeue it. */
diff --git a/kernel/sys.c b/kernel/sys.c
index c4d6b59553e9..ccc9eb736d35 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -112,14 +112,17 @@ EXPORT_SYMBOL(cad_pid);
112 112
113void (*pm_power_off_prepare)(void); 113void (*pm_power_off_prepare)(void);
114 114
115/*
116 * set the priority of a task
117 * - the caller must hold the RCU read lock
118 */
115static int set_one_prio(struct task_struct *p, int niceval, int error) 119static int set_one_prio(struct task_struct *p, int niceval, int error)
116{ 120{
117 uid_t euid = current_euid(); 121 const struct cred *cred = current_cred(), *pcred = __task_cred(p);
118 int no_nice; 122 int no_nice;
119 123
120 if (p->cred->uid != euid && 124 if (pcred->uid != cred->euid &&
121 p->cred->euid != euid && 125 pcred->euid != cred->euid && !capable(CAP_SYS_NICE)) {
122 !capable(CAP_SYS_NICE)) {
123 error = -EPERM; 126 error = -EPERM;
124 goto out; 127 goto out;
125 } 128 }
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index 6d1ed07bf312..2dc06ab35716 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -27,6 +27,7 @@
27 */ 27 */
28void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) 28void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
29{ 29{
30 const struct cred *tcred;
30 struct timespec uptime, ts; 31 struct timespec uptime, ts;
31 u64 ac_etime; 32 u64 ac_etime;
32 33
@@ -53,10 +54,11 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
53 stats->ac_flag |= AXSIG; 54 stats->ac_flag |= AXSIG;
54 stats->ac_nice = task_nice(tsk); 55 stats->ac_nice = task_nice(tsk);
55 stats->ac_sched = tsk->policy; 56 stats->ac_sched = tsk->policy;
56 stats->ac_uid = tsk->cred->uid;
57 stats->ac_gid = tsk->cred->gid;
58 stats->ac_pid = tsk->pid; 57 stats->ac_pid = tsk->pid;
59 rcu_read_lock(); 58 rcu_read_lock();
59 tcred = __task_cred(tsk);
60 stats->ac_uid = tcred->uid;
61 stats->ac_gid = tcred->gid;
60 stats->ac_ppid = pid_alive(tsk) ? 62 stats->ac_ppid = pid_alive(tsk) ?
61 rcu_dereference(tsk->real_parent)->tgid : 0; 63 rcu_dereference(tsk->real_parent)->tgid : 0;
62 rcu_read_unlock(); 64 rcu_read_unlock();
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index b23492ee3e50..7555219c535b 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1110,7 +1110,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
1110 const unsigned long __user *old_nodes, 1110 const unsigned long __user *old_nodes,
1111 const unsigned long __user *new_nodes) 1111 const unsigned long __user *new_nodes)
1112{ 1112{
1113 struct cred *cred, *tcred; 1113 const struct cred *cred = current_cred(), *tcred;
1114 struct mm_struct *mm; 1114 struct mm_struct *mm;
1115 struct task_struct *task; 1115 struct task_struct *task;
1116 nodemask_t old; 1116 nodemask_t old;
@@ -1145,14 +1145,16 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
1145 * capabilities, superuser privileges or the same 1145 * capabilities, superuser privileges or the same
1146 * userid as the target process. 1146 * userid as the target process.
1147 */ 1147 */
1148 cred = current->cred; 1148 rcu_read_lock();
1149 tcred = task->cred; 1149 tcred = __task_cred(task);
1150 if (cred->euid != tcred->suid && cred->euid != tcred->uid && 1150 if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
1151 cred->uid != tcred->suid && cred->uid != tcred->uid && 1151 cred->uid != tcred->suid && cred->uid != tcred->uid &&
1152 !capable(CAP_SYS_NICE)) { 1152 !capable(CAP_SYS_NICE)) {
1153 rcu_read_unlock();
1153 err = -EPERM; 1154 err = -EPERM;
1154 goto out; 1155 goto out;
1155 } 1156 }
1157 rcu_read_unlock();
1156 1158
1157 task_nodes = cpuset_mems_allowed(task); 1159 task_nodes = cpuset_mems_allowed(task);
1158 /* Is the user allowed to access the target nodes? */ 1160 /* Is the user allowed to access the target nodes? */
diff --git a/mm/migrate.c b/mm/migrate.c
index 794443da1b4f..142284229ce2 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1045,7 +1045,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
1045 const int __user *nodes, 1045 const int __user *nodes,
1046 int __user *status, int flags) 1046 int __user *status, int flags)
1047{ 1047{
1048 struct cred *cred, *tcred; 1048 const struct cred *cred = current_cred(), *tcred;
1049 struct task_struct *task; 1049 struct task_struct *task;
1050 struct mm_struct *mm; 1050 struct mm_struct *mm;
1051 int err; 1051 int err;
@@ -1076,14 +1076,16 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
1076 * capabilities, superuser privileges or the same 1076 * capabilities, superuser privileges or the same
1077 * userid as the target process. 1077 * userid as the target process.
1078 */ 1078 */
1079 cred = current->cred; 1079 rcu_read_lock();
1080 tcred = task->cred; 1080 tcred = __task_cred(task);
1081 if (cred->euid != tcred->suid && cred->euid != tcred->uid && 1081 if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
1082 cred->uid != tcred->suid && cred->uid != tcred->uid && 1082 cred->uid != tcred->suid && cred->uid != tcred->uid &&
1083 !capable(CAP_SYS_NICE)) { 1083 !capable(CAP_SYS_NICE)) {
1084 rcu_read_unlock();
1084 err = -EPERM; 1085 err = -EPERM;
1085 goto out; 1086 goto out;
1086 } 1087 }
1088 rcu_read_unlock();
1087 1089
1088 err = security_task_movememory(task); 1090 err = security_task_movememory(task);
1089 if (err) 1091 if (err)
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 3af787ba2077..0e0b282a2073 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -298,9 +298,9 @@ static void dump_tasks(const struct mem_cgroup *mem)
298 298
299 task_lock(p); 299 task_lock(p);
300 printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n", 300 printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n",
301 p->pid, p->cred->uid, p->tgid, p->mm->total_vm, 301 p->pid, __task_cred(p)->uid, p->tgid,
302 get_mm_rss(p->mm), (int)task_cpu(p), p->oomkilladj, 302 p->mm->total_vm, get_mm_rss(p->mm), (int)task_cpu(p),
303 p->comm); 303 p->oomkilladj, p->comm);
304 task_unlock(p); 304 task_unlock(p);
305 } while_each_thread(g, p); 305 } while_each_thread(g, p);
306} 306}
diff --git a/security/commoncap.c b/security/commoncap.c
index 61307f590003..0384bf95db68 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -51,10 +51,13 @@ EXPORT_SYMBOL(cap_netlink_recv);
51 */ 51 */
52int cap_capable(struct task_struct *tsk, int cap, int audit) 52int cap_capable(struct task_struct *tsk, int cap, int audit)
53{ 53{
54 __u32 cap_raised;
55
54 /* Derived from include/linux/sched.h:capable. */ 56 /* Derived from include/linux/sched.h:capable. */
55 if (cap_raised(tsk->cred->cap_effective, cap)) 57 rcu_read_lock();
56 return 0; 58 cap_raised = cap_raised(__task_cred(tsk)->cap_effective, cap);
57 return -EPERM; 59 rcu_read_unlock();
60 return cap_raised ? 0 : -EPERM;
58} 61}
59 62
60int cap_settime(struct timespec *ts, struct timezone *tz) 63int cap_settime(struct timespec *ts, struct timezone *tz)
@@ -66,34 +69,42 @@ int cap_settime(struct timespec *ts, struct timezone *tz)
66 69
67int cap_ptrace_may_access(struct task_struct *child, unsigned int mode) 70int cap_ptrace_may_access(struct task_struct *child, unsigned int mode)
68{ 71{
69 /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */ 72 int ret = 0;
70 if (cap_issubset(child->cred->cap_permitted, 73
71 current->cred->cap_permitted)) 74 rcu_read_lock();
72 return 0; 75 if (!cap_issubset(child->cred->cap_permitted,
73 if (capable(CAP_SYS_PTRACE)) 76 current->cred->cap_permitted) &&
74 return 0; 77 !capable(CAP_SYS_PTRACE))
75 return -EPERM; 78 ret = -EPERM;
79 rcu_read_unlock();
80 return ret;
76} 81}
77 82
78int cap_ptrace_traceme(struct task_struct *parent) 83int cap_ptrace_traceme(struct task_struct *parent)
79{ 84{
80 if (cap_issubset(current->cred->cap_permitted, 85 int ret = 0;
81 parent->cred->cap_permitted)) 86
82 return 0; 87 rcu_read_lock();
83 if (has_capability(parent, CAP_SYS_PTRACE)) 88 if (!cap_issubset(current->cred->cap_permitted,
84 return 0; 89 parent->cred->cap_permitted) &&
85 return -EPERM; 90 !has_capability(parent, CAP_SYS_PTRACE))
91 ret = -EPERM;
92 rcu_read_unlock();
93 return ret;
86} 94}
87 95
88int cap_capget (struct task_struct *target, kernel_cap_t *effective, 96int cap_capget (struct task_struct *target, kernel_cap_t *effective,
89 kernel_cap_t *inheritable, kernel_cap_t *permitted) 97 kernel_cap_t *inheritable, kernel_cap_t *permitted)
90{ 98{
91 struct cred *cred = target->cred; 99 const struct cred *cred;
92 100
93 /* Derived from kernel/capability.c:sys_capget. */ 101 /* Derived from kernel/capability.c:sys_capget. */
102 rcu_read_lock();
103 cred = __task_cred(target);
94 *effective = cred->cap_effective; 104 *effective = cred->cap_effective;
95 *inheritable = cred->cap_inheritable; 105 *inheritable = cred->cap_inheritable;
96 *permitted = cred->cap_permitted; 106 *permitted = cred->cap_permitted;
107 rcu_read_unlock();
97 return 0; 108 return 0;
98} 109}
99 110
@@ -433,7 +444,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
433 444
434int cap_bprm_secureexec (struct linux_binprm *bprm) 445int cap_bprm_secureexec (struct linux_binprm *bprm)
435{ 446{
436 const struct cred *cred = current->cred; 447 const struct cred *cred = current_cred();
437 448
438 if (cred->uid != 0) { 449 if (cred->uid != 0) {
439 if (bprm->cap_effective) 450 if (bprm->cap_effective)
@@ -511,11 +522,11 @@ static inline void cap_emulate_setxuid (int old_ruid, int old_euid,
511 if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) && 522 if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
512 (cred->uid != 0 && cred->euid != 0 && cred->suid != 0) && 523 (cred->uid != 0 && cred->euid != 0 && cred->suid != 0) &&
513 !issecure(SECURE_KEEP_CAPS)) { 524 !issecure(SECURE_KEEP_CAPS)) {
514 cap_clear (cred->cap_permitted); 525 cap_clear(cred->cap_permitted);
515 cap_clear (cred->cap_effective); 526 cap_clear(cred->cap_effective);
516 } 527 }
517 if (old_euid == 0 && cred->euid != 0) { 528 if (old_euid == 0 && cred->euid != 0) {
518 cap_clear (cred->cap_effective); 529 cap_clear(cred->cap_effective);
519 } 530 }
520 if (old_euid != 0 && cred->euid == 0) { 531 if (old_euid != 0 && cred->euid == 0) {
521 cred->cap_effective = cred->cap_permitted; 532 cred->cap_effective = cred->cap_permitted;
@@ -582,9 +593,14 @@ int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
582 */ 593 */
583static int cap_safe_nice(struct task_struct *p) 594static int cap_safe_nice(struct task_struct *p)
584{ 595{
585 if (!cap_issubset(p->cred->cap_permitted, 596 int is_subset;
586 current->cred->cap_permitted) && 597
587 !capable(CAP_SYS_NICE)) 598 rcu_read_lock();
599 is_subset = cap_issubset(__task_cred(p)->cap_permitted,
600 current_cred()->cap_permitted);
601 rcu_read_unlock();
602
603 if (!is_subset && !capable(CAP_SYS_NICE))
588 return -EPERM; 604 return -EPERM;
589 return 0; 605 return 0;
590} 606}
diff --git a/security/keys/permission.c b/security/keys/permission.c
index baf3d5f31e71..13c36164f284 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -22,13 +22,16 @@ int key_task_permission(const key_ref_t key_ref,
22 struct task_struct *context, 22 struct task_struct *context,
23 key_perm_t perm) 23 key_perm_t perm)
24{ 24{
25 struct cred *cred = context->cred; 25 const struct cred *cred;
26 struct key *key; 26 struct key *key;
27 key_perm_t kperm; 27 key_perm_t kperm;
28 int ret; 28 int ret;
29 29
30 key = key_ref_to_ptr(key_ref); 30 key = key_ref_to_ptr(key_ref);
31 31
32 rcu_read_lock();
33 cred = __task_cred(context);
34
32 /* use the second 8-bits of permissions for keys the caller owns */ 35 /* use the second 8-bits of permissions for keys the caller owns */
33 if (key->uid == cred->fsuid) { 36 if (key->uid == cred->fsuid) {
34 kperm = key->perm >> 16; 37 kperm = key->perm >> 16;
@@ -43,10 +46,7 @@ int key_task_permission(const key_ref_t key_ref,
43 goto use_these_perms; 46 goto use_these_perms;
44 } 47 }
45 48
46 spin_lock(&cred->lock);
47 ret = groups_search(cred->group_info, key->gid); 49 ret = groups_search(cred->group_info, key->gid);
48 spin_unlock(&cred->lock);
49
50 if (ret) { 50 if (ret) {
51 kperm = key->perm >> 8; 51 kperm = key->perm >> 8;
52 goto use_these_perms; 52 goto use_these_perms;
@@ -57,6 +57,8 @@ int key_task_permission(const key_ref_t key_ref,
57 kperm = key->perm; 57 kperm = key->perm;
58 58
59use_these_perms: 59use_these_perms:
60 rcu_read_lock();
61
60 /* use the top 8-bits of permissions for keys the caller possesses 62 /* use the top 8-bits of permissions for keys the caller possesses
61 * - possessor permissions are additive with other permissions 63 * - possessor permissions are additive with other permissions
62 */ 64 */
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index ce8ac6073d57..212601ebaa46 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -412,10 +412,13 @@ key_ref_t search_process_keyrings(struct key_type *type,
412 struct task_struct *context) 412 struct task_struct *context)
413{ 413{
414 struct request_key_auth *rka; 414 struct request_key_auth *rka;
415 struct cred *cred;
415 key_ref_t key_ref, ret, err; 416 key_ref_t key_ref, ret, err;
416 417
417 might_sleep(); 418 might_sleep();
418 419
420 cred = get_task_cred(context);
421
419 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 422 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
420 * searchable, but we failed to find a key or we found a negative key; 423 * searchable, but we failed to find a key or we found a negative key;
421 * otherwise we want to return a sample error (probably -EACCES) if 424 * otherwise we want to return a sample error (probably -EACCES) if
@@ -428,9 +431,9 @@ key_ref_t search_process_keyrings(struct key_type *type,
428 err = ERR_PTR(-EAGAIN); 431 err = ERR_PTR(-EAGAIN);
429 432
430 /* search the thread keyring first */ 433 /* search the thread keyring first */
431 if (context->cred->thread_keyring) { 434 if (cred->thread_keyring) {
432 key_ref = keyring_search_aux( 435 key_ref = keyring_search_aux(
433 make_key_ref(context->cred->thread_keyring, 1), 436 make_key_ref(cred->thread_keyring, 1),
434 context, type, description, match); 437 context, type, description, match);
435 if (!IS_ERR(key_ref)) 438 if (!IS_ERR(key_ref))
436 goto found; 439 goto found;
@@ -495,9 +498,9 @@ key_ref_t search_process_keyrings(struct key_type *type,
495 } 498 }
496 } 499 }
497 /* or search the user-session keyring */ 500 /* or search the user-session keyring */
498 else if (context->cred->user->session_keyring) { 501 else if (cred->user->session_keyring) {
499 key_ref = keyring_search_aux( 502 key_ref = keyring_search_aux(
500 make_key_ref(context->cred->user->session_keyring, 1), 503 make_key_ref(cred->user->session_keyring, 1),
501 context, type, description, match); 504 context, type, description, match);
502 if (!IS_ERR(key_ref)) 505 if (!IS_ERR(key_ref))
503 goto found; 506 goto found;
@@ -519,20 +522,20 @@ key_ref_t search_process_keyrings(struct key_type *type,
519 * search the keyrings of the process mentioned there 522 * search the keyrings of the process mentioned there
520 * - we don't permit access to request_key auth keys via this method 523 * - we don't permit access to request_key auth keys via this method
521 */ 524 */
522 if (context->cred->request_key_auth && 525 if (cred->request_key_auth &&
523 context == current && 526 context == current &&
524 type != &key_type_request_key_auth 527 type != &key_type_request_key_auth
525 ) { 528 ) {
526 /* defend against the auth key being revoked */ 529 /* defend against the auth key being revoked */
527 down_read(&context->cred->request_key_auth->sem); 530 down_read(&cred->request_key_auth->sem);
528 531
529 if (key_validate(context->cred->request_key_auth) == 0) { 532 if (key_validate(cred->request_key_auth) == 0) {
530 rka = context->cred->request_key_auth->payload.data; 533 rka = cred->request_key_auth->payload.data;
531 534
532 key_ref = search_process_keyrings(type, description, 535 key_ref = search_process_keyrings(type, description,
533 match, rka->context); 536 match, rka->context);
534 537
535 up_read(&context->cred->request_key_auth->sem); 538 up_read(&cred->request_key_auth->sem);
536 539
537 if (!IS_ERR(key_ref)) 540 if (!IS_ERR(key_ref))
538 goto found; 541 goto found;
@@ -549,7 +552,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
549 break; 552 break;
550 } 553 }
551 } else { 554 } else {
552 up_read(&context->cred->request_key_auth->sem); 555 up_read(&cred->request_key_auth->sem);
553 } 556 }
554 } 557 }
555 558
@@ -557,6 +560,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
557 key_ref = ret ? ret : err; 560 key_ref = ret ? ret : err;
558 561
559found: 562found:
563 put_cred(cred);
560 return key_ref; 564 return key_ref;
561 565
562} /* end search_process_keyrings() */ 566} /* end search_process_keyrings() */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 10715d1330b9..c86303638235 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -95,13 +95,18 @@ extern void selnl_notify_setenforce(int val);
95static int task_has_security(struct task_struct *tsk, 95static int task_has_security(struct task_struct *tsk,
96 u32 perms) 96 u32 perms)
97{ 97{
98 struct task_security_struct *tsec; 98 const struct task_security_struct *tsec;
99 99 u32 sid = 0;
100 tsec = tsk->cred->security; 100
101 rcu_read_lock();
102 tsec = __task_cred(tsk)->security;
103 if (tsec)
104 sid = tsec->sid;
105 rcu_read_unlock();
101 if (!tsec) 106 if (!tsec)
102 return -EACCES; 107 return -EACCES;
103 108
104 return avc_has_perm(tsec->sid, SECINITSID_SECURITY, 109 return avc_has_perm(sid, SECINITSID_SECURITY,
105 SECCLASS_SECURITY, perms, NULL); 110 SECCLASS_SECURITY, perms, NULL);
106} 111}
107 112
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index e8a4fcb1ad04..11167fd567b9 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -30,6 +30,8 @@
30 30
31#include "smack.h" 31#include "smack.h"
32 32
33#define task_security(task) (task_cred_xxx((task), security))
34
33/* 35/*
34 * I hope these are the hokeyist lines of code in the module. Casey. 36 * I hope these are the hokeyist lines of code in the module. Casey.
35 */ 37 */
@@ -1012,7 +1014,7 @@ static void smack_cred_free(struct cred *cred)
1012 */ 1014 */
1013static int smack_task_setpgid(struct task_struct *p, pid_t pgid) 1015static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1014{ 1016{
1015 return smk_curacc(p->cred->security, MAY_WRITE); 1017 return smk_curacc(task_security(p), MAY_WRITE);
1016} 1018}
1017 1019
1018/** 1020/**
@@ -1023,7 +1025,7 @@ static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1023 */ 1025 */
1024static int smack_task_getpgid(struct task_struct *p) 1026static int smack_task_getpgid(struct task_struct *p)
1025{ 1027{
1026 return smk_curacc(p->cred->security, MAY_READ); 1028 return smk_curacc(task_security(p), MAY_READ);
1027} 1029}
1028 1030
1029/** 1031/**
@@ -1034,7 +1036,7 @@ static int smack_task_getpgid(struct task_struct *p)
1034 */ 1036 */
1035static int smack_task_getsid(struct task_struct *p) 1037static int smack_task_getsid(struct task_struct *p)
1036{ 1038{
1037 return smk_curacc(p->cred->security, MAY_READ); 1039 return smk_curacc(task_security(p), MAY_READ);
1038} 1040}
1039 1041
1040/** 1042/**
@@ -1046,7 +1048,7 @@ static int smack_task_getsid(struct task_struct *p)
1046 */ 1048 */
1047static void smack_task_getsecid(struct task_struct *p, u32 *secid) 1049static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1048{ 1050{
1049 *secid = smack_to_secid(p->cred->security); 1051 *secid = smack_to_secid(task_security(p));
1050} 1052}
1051 1053
1052/** 1054/**
@@ -1062,7 +1064,7 @@ static int smack_task_setnice(struct task_struct *p, int nice)
1062 1064
1063 rc = cap_task_setnice(p, nice); 1065 rc = cap_task_setnice(p, nice);
1064 if (rc == 0) 1066 if (rc == 0)
1065 rc = smk_curacc(p->cred->security, MAY_WRITE); 1067 rc = smk_curacc(task_security(p), MAY_WRITE);
1066 return rc; 1068 return rc;
1067} 1069}
1068 1070
@@ -1079,7 +1081,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
1079 1081
1080 rc = cap_task_setioprio(p, ioprio); 1082 rc = cap_task_setioprio(p, ioprio);
1081 if (rc == 0) 1083 if (rc == 0)
1082 rc = smk_curacc(p->cred->security, MAY_WRITE); 1084 rc = smk_curacc(task_security(p), MAY_WRITE);
1083 return rc; 1085 return rc;
1084} 1086}
1085 1087
@@ -1091,7 +1093,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
1091 */ 1093 */
1092static int smack_task_getioprio(struct task_struct *p) 1094static int smack_task_getioprio(struct task_struct *p)
1093{ 1095{
1094 return smk_curacc(p->cred->security, MAY_READ); 1096 return smk_curacc(task_security(p), MAY_READ);
1095} 1097}
1096 1098
1097/** 1099/**
@@ -1109,7 +1111,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy,
1109 1111
1110 rc = cap_task_setscheduler(p, policy, lp); 1112 rc = cap_task_setscheduler(p, policy, lp);
1111 if (rc == 0) 1113 if (rc == 0)
1112 rc = smk_curacc(p->cred->security, MAY_WRITE); 1114 rc = smk_curacc(task_security(p), MAY_WRITE);
1113 return rc; 1115 return rc;
1114} 1116}
1115 1117
@@ -1121,7 +1123,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy,
1121 */ 1123 */
1122static int smack_task_getscheduler(struct task_struct *p) 1124static int smack_task_getscheduler(struct task_struct *p)
1123{ 1125{
1124 return smk_curacc(p->cred->security, MAY_READ); 1126 return smk_curacc(task_security(p), MAY_READ);
1125} 1127}
1126 1128
1127/** 1129/**
@@ -1132,7 +1134,7 @@ static int smack_task_getscheduler(struct task_struct *p)
1132 */ 1134 */
1133static int smack_task_movememory(struct task_struct *p) 1135static int smack_task_movememory(struct task_struct *p)
1134{ 1136{
1135 return smk_curacc(p->cred->security, MAY_WRITE); 1137 return smk_curacc(task_security(p), MAY_WRITE);
1136} 1138}
1137 1139
1138/** 1140/**
@@ -1155,13 +1157,13 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1155 * can write the receiver. 1157 * can write the receiver.
1156 */ 1158 */
1157 if (secid == 0) 1159 if (secid == 0)
1158 return smk_curacc(p->cred->security, MAY_WRITE); 1160 return smk_curacc(task_security(p), MAY_WRITE);
1159 /* 1161 /*
1160 * If the secid isn't 0 we're dealing with some USB IO 1162 * If the secid isn't 0 we're dealing with some USB IO
1161 * specific behavior. This is not clean. For one thing 1163 * specific behavior. This is not clean. For one thing
1162 * we can't take privilege into account. 1164 * we can't take privilege into account.
1163 */ 1165 */
1164 return smk_access(smack_from_secid(secid), p->cred->security, MAY_WRITE); 1166 return smk_access(smack_from_secid(secid), task_security(p), MAY_WRITE);
1165} 1167}
1166 1168
1167/** 1169/**
@@ -1174,7 +1176,7 @@ static int smack_task_wait(struct task_struct *p)
1174{ 1176{
1175 int rc; 1177 int rc;
1176 1178
1177 rc = smk_access(current->cred->security, p->cred->security, MAY_WRITE); 1179 rc = smk_access(current_security(), task_security(p), MAY_WRITE);
1178 if (rc == 0) 1180 if (rc == 0)
1179 return 0; 1181 return 0;
1180 1182
@@ -1205,7 +1207,7 @@ static int smack_task_wait(struct task_struct *p)
1205static void smack_task_to_inode(struct task_struct *p, struct inode *inode) 1207static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1206{ 1208{
1207 struct inode_smack *isp = inode->i_security; 1209 struct inode_smack *isp = inode->i_security;
1208 isp->smk_inode = p->cred->security; 1210 isp->smk_inode = task_security(p);
1209} 1211}
1210 1212
1211/* 1213/*
@@ -2010,7 +2012,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2010 if (strcmp(name, "current") != 0) 2012 if (strcmp(name, "current") != 0)
2011 return -EINVAL; 2013 return -EINVAL;
2012 2014
2013 cp = kstrdup(p->cred->security, GFP_KERNEL); 2015 cp = kstrdup(task_security(p), GFP_KERNEL);
2014 if (cp == NULL) 2016 if (cp == NULL)
2015 return -ENOMEM; 2017 return -ENOMEM;
2016 2018