aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/base.c101
1 files changed, 68 insertions, 33 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2e4356f5d5e3..a85b073408e0 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -74,6 +74,16 @@
74#include <linux/poll.h> 74#include <linux/poll.h>
75#include "internal.h" 75#include "internal.h"
76 76
77/* NOTE:
78 * Implementing inode permission operations in /proc is almost
79 * certainly an error. Permission checks need to happen during
80 * each system call not at open time. The reason is that most of
81 * what we wish to check for permissions in /proc varies at runtime.
82 *
83 * The classic example of a problem is opening file descriptors
84 * in /proc for a task before it execs a suid executable.
85 */
86
77/* 87/*
78 * For hysterical raisins we keep the same inumbers as in the old procfs. 88 * For hysterical raisins we keep the same inumbers as in the old procfs.
79 * Feel free to change the macro below - just keep the range distinct from 89 * Feel free to change the macro below - just keep the range distinct from
@@ -494,13 +504,11 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
494 504
495/* If the process being read is separated by chroot from the reading process, 505/* If the process being read is separated by chroot from the reading process,
496 * don't let the reader access the threads. 506 * don't let the reader access the threads.
497 *
498 * note: this does dput(root) and mntput(vfsmnt) on exit.
499 */ 507 */
500static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt) 508static int proc_check_chroot(struct dentry *de, struct vfsmount *mnt)
501{ 509{
502 struct dentry *de, *base; 510 struct dentry *base;
503 struct vfsmount *our_vfsmnt, *mnt; 511 struct vfsmount *our_vfsmnt;
504 int res = 0; 512 int res = 0;
505 513
506 read_lock(&current->fs->lock); 514 read_lock(&current->fs->lock);
@@ -509,8 +517,6 @@ static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
509 read_unlock(&current->fs->lock); 517 read_unlock(&current->fs->lock);
510 518
511 spin_lock(&vfsmount_lock); 519 spin_lock(&vfsmount_lock);
512 de = root;
513 mnt = vfsmnt;
514 520
515 while (mnt != our_vfsmnt) { 521 while (mnt != our_vfsmnt) {
516 if (mnt == mnt->mnt_parent) 522 if (mnt == mnt->mnt_parent)
@@ -526,8 +532,6 @@ static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
526exit: 532exit:
527 dput(base); 533 dput(base);
528 mntput(our_vfsmnt); 534 mntput(our_vfsmnt);
529 dput(root);
530 mntput(vfsmnt);
531 return res; 535 return res;
532out: 536out:
533 spin_unlock(&vfsmount_lock); 537 spin_unlock(&vfsmount_lock);
@@ -535,23 +539,6 @@ out:
535 goto exit; 539 goto exit;
536} 540}
537 541
538static int proc_check_root(struct inode *inode)
539{
540 struct dentry *root;
541 struct vfsmount *vfsmnt;
542
543 if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
544 return -ENOENT;
545 return proc_check_chroot(root, vfsmnt);
546}
547
548static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
549{
550 if (generic_permission(inode, mask, NULL) != 0)
551 return -EACCES;
552 return proc_check_root(inode);
553}
554
555extern struct seq_operations proc_pid_maps_op; 542extern struct seq_operations proc_pid_maps_op;
556static int maps_open(struct inode *inode, struct file *file) 543static int maps_open(struct inode *inode, struct file *file)
557{ 544{
@@ -1048,6 +1035,48 @@ static struct file_operations proc_seccomp_operations = {
1048}; 1035};
1049#endif /* CONFIG_SECCOMP */ 1036#endif /* CONFIG_SECCOMP */
1050 1037
1038static int proc_check_dentry_visible(struct inode *inode,
1039 struct dentry *dentry, struct vfsmount *mnt)
1040{
1041 /* Verify that the current process can already see the
1042 * file pointed at by the file descriptor.
1043 * This prevents /proc from being an accidental information leak.
1044 *
1045 * This prevents access to files that are not visible do to
1046 * being on the otherside of a chroot, in a different
1047 * namespace, or are simply process local (like pipes).
1048 */
1049 struct task_struct *task;
1050 struct files_struct *task_files, *files;
1051 int error = -EACCES;
1052
1053 /* See if the the two tasks share a commone set of
1054 * file descriptors. If so everything is visible.
1055 */
1056 task = proc_task(inode);
1057 if (!task)
1058 goto out;
1059 files = get_files_struct(current);
1060 task_files = get_files_struct(task);
1061 if (files && task_files && (files == task_files))
1062 error = 0;
1063 if (task_files)
1064 put_files_struct(task_files);
1065 if (files)
1066 put_files_struct(files);
1067 if (!error)
1068 goto out;
1069
1070 /* If the two tasks don't share a common set of file
1071 * descriptors see if the destination dentry is already
1072 * visible in the current tasks filesystem namespace.
1073 */
1074 error = proc_check_chroot(dentry, mnt);
1075out:
1076 return error;
1077
1078}
1079
1051static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) 1080static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
1052{ 1081{
1053 struct inode *inode = dentry->d_inode; 1082 struct inode *inode = dentry->d_inode;
@@ -1058,12 +1087,16 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
1058 1087
1059 if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE)) 1088 if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
1060 goto out; 1089 goto out;
1061 error = proc_check_root(inode);
1062 if (error)
1063 goto out;
1064 1090
1065 error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); 1091 error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
1066 nd->last_type = LAST_BIND; 1092 nd->last_type = LAST_BIND;
1093 if (error)
1094 goto out;
1095
1096 /* Only return files this task can already see */
1097 error = proc_check_dentry_visible(inode, nd->dentry, nd->mnt);
1098 if (error)
1099 path_release(nd);
1067out: 1100out:
1068 return ERR_PTR(error); 1101 return ERR_PTR(error);
1069} 1102}
@@ -1104,15 +1137,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
1104 1137
1105 if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE)) 1138 if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
1106 goto out; 1139 goto out;
1107 error = proc_check_root(inode);
1108 if (error)
1109 goto out;
1110 1140
1111 error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); 1141 error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt);
1112 if (error) 1142 if (error)
1113 goto out; 1143 goto out;
1114 1144
1145 /* Only return files this task can already see */
1146 error = proc_check_dentry_visible(inode, de, mnt);
1147 if (error)
1148 goto out_put;
1149
1115 error = do_proc_readlink(de, mnt, buffer, buflen); 1150 error = do_proc_readlink(de, mnt, buffer, buflen);
1151out_put:
1116 dput(de); 1152 dput(de);
1117 mntput(mnt); 1153 mntput(mnt);
1118out: 1154out:
@@ -1512,7 +1548,6 @@ static struct file_operations proc_task_operations = {
1512 */ 1548 */
1513static struct inode_operations proc_fd_inode_operations = { 1549static struct inode_operations proc_fd_inode_operations = {
1514 .lookup = proc_lookupfd, 1550 .lookup = proc_lookupfd,
1515 .permission = proc_permission,
1516}; 1551};
1517 1552
1518static struct inode_operations proc_task_inode_operations = { 1553static struct inode_operations proc_task_inode_operations = {