diff options
Diffstat (limited to 'fs/proc')
| -rw-r--r-- | fs/proc/array.c | 32 | ||||
| -rw-r--r-- | fs/proc/base.c | 32 |
2 files changed, 46 insertions, 18 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index 6af7fba7abb1..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->uid, p->euid, p->suid, p->fsuid, | 187 | cred->uid, cred->euid, cred->suid, cred->fsuid, |
| 186 | p->gid, p->egid, p->sgid, p->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->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->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,10 +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 | render_cap_t(m, "CapInh:\t", &p->cap_inheritable); | 297 | const struct cred *cred; |
| 297 | render_cap_t(m, "CapPrm:\t", &p->cap_permitted); | 298 | kernel_cap_t cap_inheritable, cap_permitted, cap_effective, cap_bset; |
| 298 | render_cap_t(m, "CapEff:\t", &p->cap_effective); | 299 | |
| 299 | render_cap_t(m, "CapBnd:\t", &p->cap_bset); | 300 | rcu_read_lock(); |
| 301 | cred = __task_cred(p); | ||
| 302 | cap_inheritable = cred->cap_inheritable; | ||
| 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); | ||
| 300 | } | 312 | } |
| 301 | 313 | ||
| 302 | 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 d4677603c889..0a8a5f880349 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->euid; | 1432 | rcu_read_lock(); |
| 1432 | inode->i_gid = task->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->euid; | 1463 | cred = __task_cred(task); |
| 1458 | stat->gid = task->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->euid; | 1498 | rcu_read_lock(); |
| 1490 | inode->i_gid = task->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->euid; | 1674 | rcu_read_lock(); |
| 1662 | inode->i_gid = task->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; |
