diff options
-rw-r--r-- | arch/ia64/kernel/perfmon.c | 32 | ||||
-rw-r--r-- | drivers/connector/cn_proc.c | 16 | ||||
-rw-r--r-- | fs/binfmt_elf.c | 8 | ||||
-rw-r--r-- | fs/binfmt_elf_fdpic.c | 8 | ||||
-rw-r--r-- | fs/fcntl.c | 15 | ||||
-rw-r--r-- | fs/fuse/dir.c | 23 | ||||
-rw-r--r-- | fs/ioprio.c | 14 | ||||
-rw-r--r-- | fs/proc/array.c | 32 | ||||
-rw-r--r-- | fs/proc/base.c | 32 | ||||
-rw-r--r-- | include/linux/cred.h | 3 | ||||
-rw-r--r-- | kernel/auditsc.c | 33 | ||||
-rw-r--r-- | kernel/cgroup.c | 16 | ||||
-rw-r--r-- | kernel/exit.c | 14 | ||||
-rw-r--r-- | kernel/futex.c | 22 | ||||
-rw-r--r-- | kernel/futex_compat.c | 7 | ||||
-rw-r--r-- | kernel/ptrace.c | 22 | ||||
-rw-r--r-- | kernel/sched.c | 31 | ||||
-rw-r--r-- | kernel/signal.c | 49 | ||||
-rw-r--r-- | kernel/sys.c | 11 | ||||
-rw-r--r-- | kernel/tsacct.c | 6 | ||||
-rw-r--r-- | mm/mempolicy.c | 8 | ||||
-rw-r--r-- | mm/migrate.c | 8 | ||||
-rw-r--r-- | mm/oom_kill.c | 6 | ||||
-rw-r--r-- | security/commoncap.c | 64 | ||||
-rw-r--r-- | security/keys/permission.c | 10 | ||||
-rw-r--r-- | security/keys/process_keys.c | 24 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 13 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 32 |
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: | |||
2399 | static int | 2399 | static int |
2400 | pfm_bad_permissions(struct task_struct *task) | 2400 | pfm_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 | ||
2423 | static int | 2431 | static 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, | |||
1361 | static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | 1361 | static 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, | |||
1414 | static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | 1414 | static 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] = { | |||
401 | static inline int sigio_perm(struct task_struct *p, | 401 | static 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 | ||
410 | static void send_sigio_to_task(struct task_struct *p, | 417 | static 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 | */ |
870 | int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) | 870 | int 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 | ||
886 | static int fuse_access(struct inode *inode, int mask) | 893 | static 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 | ||
294 | static inline void task_cap(struct seq_file *m, struct task_struct *p) | 295 | static 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 | ||
304 | static inline void task_context_switch_counts(struct seq_file *m, | 314 | static 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 | */ |
150 | static inline void put_cred(struct cred *cred) | 150 | static 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 | ||
1230 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 1233 | static 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) | |||
1279 | static int attach_task_by_pid(struct cgroup *cgrp, u64 pid) | 1279 | static 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; |
161 | repeat: | 161 | repeat: |
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; | ||
1462 | unlock_sig: | 1466 | unlock_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) | |||
439 | static struct task_struct * futex_find_get_task(pid_t pid) | 439 | static 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 | ||
116 | int __ptrace_may_access(struct task_struct *task, unsigned int mode) | 116 | int __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 | */ | ||
5129 | static 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 | |||
5124 | static int __sched_setscheduler(struct task_struct *p, int policy, | 5142 | static 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 | */ | ||
180 | static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, | 185 | static 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 | */ |
566 | static int check_kill_permission(int sig, struct siginfo *info, | 573 | static 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 | */ | ||
1014 | int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) | 1026 | int 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 | |||
1037 | int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) | 1049 | int __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 | ||
113 | void (*pm_power_off_prepare)(void); | 113 | void (*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 | */ | ||
115 | static int set_one_prio(struct task_struct *p, int niceval, int error) | 119 | static 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 | */ |
28 | void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | 28 | void 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 | */ |
52 | int cap_capable(struct task_struct *tsk, int cap, int audit) | 52 | int 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 | ||
60 | int cap_settime(struct timespec *ts, struct timezone *tz) | 63 | int cap_settime(struct timespec *ts, struct timezone *tz) |
@@ -66,34 +69,42 @@ int cap_settime(struct timespec *ts, struct timezone *tz) | |||
66 | 69 | ||
67 | int cap_ptrace_may_access(struct task_struct *child, unsigned int mode) | 70 | int 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 | ||
78 | int cap_ptrace_traceme(struct task_struct *parent) | 83 | int 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 | ||
88 | int cap_capget (struct task_struct *target, kernel_cap_t *effective, | 96 | int 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 | ||
434 | int cap_bprm_secureexec (struct linux_binprm *bprm) | 445 | int 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 | */ |
583 | static int cap_safe_nice(struct task_struct *p) | 594 | static 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 | ||
59 | use_these_perms: | 59 | use_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 | ||
559 | found: | 562 | found: |
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); | |||
95 | static int task_has_security(struct task_struct *tsk, | 95 | static 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 | */ |
1013 | static int smack_task_setpgid(struct task_struct *p, pid_t pgid) | 1015 | static 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 | */ |
1024 | static int smack_task_getpgid(struct task_struct *p) | 1026 | static 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 | */ |
1035 | static int smack_task_getsid(struct task_struct *p) | 1037 | static 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 | */ |
1047 | static void smack_task_getsecid(struct task_struct *p, u32 *secid) | 1049 | static 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 | */ |
1092 | static int smack_task_getioprio(struct task_struct *p) | 1094 | static 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 | */ |
1122 | static int smack_task_getscheduler(struct task_struct *p) | 1124 | static 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 | */ |
1133 | static int smack_task_movememory(struct task_struct *p) | 1135 | static 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) | |||
1205 | static void smack_task_to_inode(struct task_struct *p, struct inode *inode) | 1207 | static 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 | ||