aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c183
1 files changed, 95 insertions, 88 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 33537487f5ab..88f8edf18258 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -88,10 +88,6 @@
88 * in /proc for a task before it execs a suid executable. 88 * in /proc for a task before it execs a suid executable.
89 */ 89 */
90 90
91
92/* Worst case buffer size needed for holding an integer. */
93#define PROC_NUMBUF 13
94
95struct pid_entry { 91struct pid_entry {
96 char *name; 92 char *name;
97 int len; 93 int len;
@@ -125,6 +121,10 @@ struct pid_entry {
125 NOD(NAME, (S_IFREG|(MODE)), \ 121 NOD(NAME, (S_IFREG|(MODE)), \
126 NULL, &proc_info_file_operations, \ 122 NULL, &proc_info_file_operations, \
127 { .proc_read = &proc_##OTYPE } ) 123 { .proc_read = &proc_##OTYPE } )
124#define ONE(NAME, MODE, OTYPE) \
125 NOD(NAME, (S_IFREG|(MODE)), \
126 NULL, &proc_single_file_operations, \
127 { .proc_show = &proc_##OTYPE } )
128 128
129int maps_protect; 129int maps_protect;
130EXPORT_SYMBOL(maps_protect); 130EXPORT_SYMBOL(maps_protect);
@@ -153,7 +153,7 @@ static int get_nr_threads(struct task_struct *tsk)
153 return count; 153 return count;
154} 154}
155 155
156static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) 156static int proc_cwd_link(struct inode *inode, struct path *path)
157{ 157{
158 struct task_struct *task = get_proc_task(inode); 158 struct task_struct *task = get_proc_task(inode);
159 struct fs_struct *fs = NULL; 159 struct fs_struct *fs = NULL;
@@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
165 } 165 }
166 if (fs) { 166 if (fs) {
167 read_lock(&fs->lock); 167 read_lock(&fs->lock);
168 *mnt = mntget(fs->pwdmnt); 168 *path = fs->pwd;
169 *dentry = dget(fs->pwd); 169 path_get(&fs->pwd);
170 read_unlock(&fs->lock); 170 read_unlock(&fs->lock);
171 result = 0; 171 result = 0;
172 put_fs_struct(fs); 172 put_fs_struct(fs);
@@ -174,7 +174,7 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
174 return result; 174 return result;
175} 175}
176 176
177static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) 177static int proc_root_link(struct inode *inode, struct path *path)
178{ 178{
179 struct task_struct *task = get_proc_task(inode); 179 struct task_struct *task = get_proc_task(inode);
180 struct fs_struct *fs = NULL; 180 struct fs_struct *fs = NULL;
@@ -186,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
186 } 186 }
187 if (fs) { 187 if (fs) {
188 read_lock(&fs->lock); 188 read_lock(&fs->lock);
189 *mnt = mntget(fs->rootmnt); 189 *path = fs->root;
190 *dentry = dget(fs->root); 190 path_get(&fs->root);
191 read_unlock(&fs->lock); 191 read_unlock(&fs->lock);
192 result = 0; 192 result = 0;
193 put_fs_struct(fs); 193 put_fs_struct(fs);
@@ -506,7 +506,7 @@ static const struct inode_operations proc_def_inode_operations = {
506 .setattr = proc_setattr, 506 .setattr = proc_setattr,
507}; 507};
508 508
509extern struct seq_operations mounts_op; 509extern const struct seq_operations mounts_op;
510struct proc_mounts { 510struct proc_mounts {
511 struct seq_file m; 511 struct seq_file m;
512 int event; 512 int event;
@@ -585,7 +585,7 @@ static const struct file_operations proc_mounts_operations = {
585 .poll = mounts_poll, 585 .poll = mounts_poll,
586}; 586};
587 587
588extern struct seq_operations mountstats_op; 588extern const struct seq_operations mountstats_op;
589static int mountstats_open(struct inode *inode, struct file *file) 589static int mountstats_open(struct inode *inode, struct file *file)
590{ 590{
591 int ret = seq_open(file, &mountstats_op); 591 int ret = seq_open(file, &mountstats_op);
@@ -662,6 +662,45 @@ static const struct file_operations proc_info_file_operations = {
662 .read = proc_info_read, 662 .read = proc_info_read,
663}; 663};
664 664
665static int proc_single_show(struct seq_file *m, void *v)
666{
667 struct inode *inode = m->private;
668 struct pid_namespace *ns;
669 struct pid *pid;
670 struct task_struct *task;
671 int ret;
672
673 ns = inode->i_sb->s_fs_info;
674 pid = proc_pid(inode);
675 task = get_pid_task(pid, PIDTYPE_PID);
676 if (!task)
677 return -ESRCH;
678
679 ret = PROC_I(inode)->op.proc_show(m, ns, pid, task);
680
681 put_task_struct(task);
682 return ret;
683}
684
685static int proc_single_open(struct inode *inode, struct file *filp)
686{
687 int ret;
688 ret = single_open(filp, proc_single_show, NULL);
689 if (!ret) {
690 struct seq_file *m = filp->private_data;
691
692 m->private = inode;
693 }
694 return ret;
695}
696
697static const struct file_operations proc_single_file_operations = {
698 .open = proc_single_open,
699 .read = seq_read,
700 .llseek = seq_lseek,
701 .release = single_release,
702};
703
665static int mem_open(struct inode* inode, struct file* file) 704static int mem_open(struct inode* inode, struct file* file)
666{ 705{
667 file->private_data = (void*)((long)current->self_exec_id); 706 file->private_data = (void*)((long)current->self_exec_id);
@@ -787,7 +826,7 @@ out_no_task:
787} 826}
788#endif 827#endif
789 828
790static loff_t mem_lseek(struct file * file, loff_t offset, int orig) 829loff_t mem_lseek(struct file *file, loff_t offset, int orig)
791{ 830{
792 switch (orig) { 831 switch (orig) {
793 case 0: 832 case 0:
@@ -935,42 +974,6 @@ static const struct file_operations proc_oom_adjust_operations = {
935 .write = oom_adjust_write, 974 .write = oom_adjust_write,
936}; 975};
937 976
938#ifdef CONFIG_MMU
939static ssize_t clear_refs_write(struct file *file, const char __user *buf,
940 size_t count, loff_t *ppos)
941{
942 struct task_struct *task;
943 char buffer[PROC_NUMBUF], *end;
944 struct mm_struct *mm;
945
946 memset(buffer, 0, sizeof(buffer));
947 if (count > sizeof(buffer) - 1)
948 count = sizeof(buffer) - 1;
949 if (copy_from_user(buffer, buf, count))
950 return -EFAULT;
951 if (!simple_strtol(buffer, &end, 0))
952 return -EINVAL;
953 if (*end == '\n')
954 end++;
955 task = get_proc_task(file->f_path.dentry->d_inode);
956 if (!task)
957 return -ESRCH;
958 mm = get_task_mm(task);
959 if (mm) {
960 clear_refs_smap(mm);
961 mmput(mm);
962 }
963 put_task_struct(task);
964 if (end - buffer == 0)
965 return -EIO;
966 return end - buffer;
967}
968
969static struct file_operations proc_clear_refs_operations = {
970 .write = clear_refs_write,
971};
972#endif
973
974#ifdef CONFIG_AUDITSYSCALL 977#ifdef CONFIG_AUDITSYSCALL
975#define TMPBUFLEN 21 978#define TMPBUFLEN 21
976static ssize_t proc_loginuid_read(struct file * file, char __user * buf, 979static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
@@ -1161,39 +1164,36 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
1161 int error = -EACCES; 1164 int error = -EACCES;
1162 1165
1163 /* We don't need a base pointer in the /proc filesystem */ 1166 /* We don't need a base pointer in the /proc filesystem */
1164 path_release(nd); 1167 path_put(&nd->path);
1165 1168
1166 /* Are we allowed to snoop on the tasks file descriptors? */ 1169 /* Are we allowed to snoop on the tasks file descriptors? */
1167 if (!proc_fd_access_allowed(inode)) 1170 if (!proc_fd_access_allowed(inode))
1168 goto out; 1171 goto out;
1169 1172
1170 error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); 1173 error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
1171 nd->last_type = LAST_BIND; 1174 nd->last_type = LAST_BIND;
1172out: 1175out:
1173 return ERR_PTR(error); 1176 return ERR_PTR(error);
1174} 1177}
1175 1178
1176static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, 1179static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
1177 char __user *buffer, int buflen)
1178{ 1180{
1179 struct inode * inode;
1180 char *tmp = (char*)__get_free_page(GFP_TEMPORARY); 1181 char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
1181 char *path; 1182 char *pathname;
1182 int len; 1183 int len;
1183 1184
1184 if (!tmp) 1185 if (!tmp)
1185 return -ENOMEM; 1186 return -ENOMEM;
1186 1187
1187 inode = dentry->d_inode; 1188 pathname = d_path(path, tmp, PAGE_SIZE);
1188 path = d_path(dentry, mnt, tmp, PAGE_SIZE); 1189 len = PTR_ERR(pathname);
1189 len = PTR_ERR(path); 1190 if (IS_ERR(pathname))
1190 if (IS_ERR(path))
1191 goto out; 1191 goto out;
1192 len = tmp + PAGE_SIZE - 1 - path; 1192 len = tmp + PAGE_SIZE - 1 - pathname;
1193 1193
1194 if (len > buflen) 1194 if (len > buflen)
1195 len = buflen; 1195 len = buflen;
1196 if (copy_to_user(buffer, path, len)) 1196 if (copy_to_user(buffer, pathname, len))
1197 len = -EFAULT; 1197 len = -EFAULT;
1198 out: 1198 out:
1199 free_page((unsigned long)tmp); 1199 free_page((unsigned long)tmp);
@@ -1204,20 +1204,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
1204{ 1204{
1205 int error = -EACCES; 1205 int error = -EACCES;
1206 struct inode *inode = dentry->d_inode; 1206 struct inode *inode = dentry->d_inode;
1207 struct dentry *de; 1207 struct path path;
1208 struct vfsmount *mnt = NULL;
1209 1208
1210 /* Are we allowed to snoop on the tasks file descriptors? */ 1209 /* Are we allowed to snoop on the tasks file descriptors? */
1211 if (!proc_fd_access_allowed(inode)) 1210 if (!proc_fd_access_allowed(inode))
1212 goto out; 1211 goto out;
1213 1212
1214 error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); 1213 error = PROC_I(inode)->op.proc_get_link(inode, &path);
1215 if (error) 1214 if (error)
1216 goto out; 1215 goto out;
1217 1216
1218 error = do_proc_readlink(de, mnt, buffer, buflen); 1217 error = do_proc_readlink(&path, buffer, buflen);
1219 dput(de); 1218 path_put(&path);
1220 mntput(mnt);
1221out: 1219out:
1222 return error; 1220 return error;
1223} 1221}
@@ -1444,8 +1442,7 @@ out:
1444 1442
1445#define PROC_FDINFO_MAX 64 1443#define PROC_FDINFO_MAX 64
1446 1444
1447static int proc_fd_info(struct inode *inode, struct dentry **dentry, 1445static int proc_fd_info(struct inode *inode, struct path *path, char *info)
1448 struct vfsmount **mnt, char *info)
1449{ 1446{
1450 struct task_struct *task = get_proc_task(inode); 1447 struct task_struct *task = get_proc_task(inode);
1451 struct files_struct *files = NULL; 1448 struct files_struct *files = NULL;
@@ -1464,10 +1461,10 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry,
1464 spin_lock(&files->file_lock); 1461 spin_lock(&files->file_lock);
1465 file = fcheck_files(files, fd); 1462 file = fcheck_files(files, fd);
1466 if (file) { 1463 if (file) {
1467 if (mnt) 1464 if (path) {
1468 *mnt = mntget(file->f_path.mnt); 1465 *path = file->f_path;
1469 if (dentry) 1466 path_get(&file->f_path);
1470 *dentry = dget(file->f_path.dentry); 1467 }
1471 if (info) 1468 if (info)
1472 snprintf(info, PROC_FDINFO_MAX, 1469 snprintf(info, PROC_FDINFO_MAX,
1473 "pos:\t%lli\n" 1470 "pos:\t%lli\n"
@@ -1484,10 +1481,9 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry,
1484 return -ENOENT; 1481 return -ENOENT;
1485} 1482}
1486 1483
1487static int proc_fd_link(struct inode *inode, struct dentry **dentry, 1484static int proc_fd_link(struct inode *inode, struct path *path)
1488 struct vfsmount **mnt)
1489{ 1485{
1490 return proc_fd_info(inode, dentry, mnt, NULL); 1486 return proc_fd_info(inode, path, NULL);
1491} 1487}
1492 1488
1493static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) 1489static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
@@ -1681,7 +1677,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
1681 size_t len, loff_t *ppos) 1677 size_t len, loff_t *ppos)
1682{ 1678{
1683 char tmp[PROC_FDINFO_MAX]; 1679 char tmp[PROC_FDINFO_MAX];
1684 int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp); 1680 int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp);
1685 if (!err) 1681 if (!err)
1686 err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); 1682 err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
1687 return err; 1683 return err;
@@ -2098,15 +2094,23 @@ static const struct file_operations proc_coredump_filter_operations = {
2098static int proc_self_readlink(struct dentry *dentry, char __user *buffer, 2094static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
2099 int buflen) 2095 int buflen)
2100{ 2096{
2097 struct pid_namespace *ns = dentry->d_sb->s_fs_info;
2098 pid_t tgid = task_tgid_nr_ns(current, ns);
2101 char tmp[PROC_NUMBUF]; 2099 char tmp[PROC_NUMBUF];
2102 sprintf(tmp, "%d", task_tgid_vnr(current)); 2100 if (!tgid)
2101 return -ENOENT;
2102 sprintf(tmp, "%d", tgid);
2103 return vfs_readlink(dentry,buffer,buflen,tmp); 2103 return vfs_readlink(dentry,buffer,buflen,tmp);
2104} 2104}
2105 2105
2106static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) 2106static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
2107{ 2107{
2108 struct pid_namespace *ns = dentry->d_sb->s_fs_info;
2109 pid_t tgid = task_tgid_nr_ns(current, ns);
2108 char tmp[PROC_NUMBUF]; 2110 char tmp[PROC_NUMBUF];
2109 sprintf(tmp, "%d", task_tgid_vnr(current)); 2111 if (!tgid)
2112 return ERR_PTR(-ENOENT);
2113 sprintf(tmp, "%d", task_tgid_nr_ns(current, ns));
2110 return ERR_PTR(vfs_follow_link(nd,tmp)); 2114 return ERR_PTR(vfs_follow_link(nd,tmp));
2111} 2115}
2112 2116
@@ -2271,14 +2275,14 @@ static const struct pid_entry tgid_base_stuff[] = {
2271 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), 2275 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
2272 REG("environ", S_IRUSR, environ), 2276 REG("environ", S_IRUSR, environ),
2273 INF("auxv", S_IRUSR, pid_auxv), 2277 INF("auxv", S_IRUSR, pid_auxv),
2274 INF("status", S_IRUGO, pid_status), 2278 ONE("status", S_IRUGO, pid_status),
2275 INF("limits", S_IRUSR, pid_limits), 2279 INF("limits", S_IRUSR, pid_limits),
2276#ifdef CONFIG_SCHED_DEBUG 2280#ifdef CONFIG_SCHED_DEBUG
2277 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2281 REG("sched", S_IRUGO|S_IWUSR, pid_sched),
2278#endif 2282#endif
2279 INF("cmdline", S_IRUGO, pid_cmdline), 2283 INF("cmdline", S_IRUGO, pid_cmdline),
2280 INF("stat", S_IRUGO, tgid_stat), 2284 ONE("stat", S_IRUGO, tgid_stat),
2281 INF("statm", S_IRUGO, pid_statm), 2285 ONE("statm", S_IRUGO, pid_statm),
2282 REG("maps", S_IRUGO, maps), 2286 REG("maps", S_IRUGO, maps),
2283#ifdef CONFIG_NUMA 2287#ifdef CONFIG_NUMA
2284 REG("numa_maps", S_IRUGO, numa_maps), 2288 REG("numa_maps", S_IRUGO, numa_maps),
@@ -2289,9 +2293,10 @@ static const struct pid_entry tgid_base_stuff[] = {
2289 LNK("exe", exe), 2293 LNK("exe", exe),
2290 REG("mounts", S_IRUGO, mounts), 2294 REG("mounts", S_IRUGO, mounts),
2291 REG("mountstats", S_IRUSR, mountstats), 2295 REG("mountstats", S_IRUSR, mountstats),
2292#ifdef CONFIG_MMU 2296#ifdef CONFIG_PROC_PAGE_MONITOR
2293 REG("clear_refs", S_IWUSR, clear_refs), 2297 REG("clear_refs", S_IWUSR, clear_refs),
2294 REG("smaps", S_IRUGO, smaps), 2298 REG("smaps", S_IRUGO, smaps),
2299 REG("pagemap", S_IRUSR, pagemap),
2295#endif 2300#endif
2296#ifdef CONFIG_SECURITY 2301#ifdef CONFIG_SECURITY
2297 DIR("attr", S_IRUGO|S_IXUGO, attr_dir), 2302 DIR("attr", S_IRUGO|S_IXUGO, attr_dir),
@@ -2360,7 +2365,8 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
2360 name.len = snprintf(buf, sizeof(buf), "%d", pid); 2365 name.len = snprintf(buf, sizeof(buf), "%d", pid);
2361 dentry = d_hash_and_lookup(mnt->mnt_root, &name); 2366 dentry = d_hash_and_lookup(mnt->mnt_root, &name);
2362 if (dentry) { 2367 if (dentry) {
2363 shrink_dcache_parent(dentry); 2368 if (!(current->flags & PF_EXITING))
2369 shrink_dcache_parent(dentry);
2364 d_drop(dentry); 2370 d_drop(dentry);
2365 dput(dentry); 2371 dput(dentry);
2366 } 2372 }
@@ -2600,14 +2606,14 @@ static const struct pid_entry tid_base_stuff[] = {
2600 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), 2606 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
2601 REG("environ", S_IRUSR, environ), 2607 REG("environ", S_IRUSR, environ),
2602 INF("auxv", S_IRUSR, pid_auxv), 2608 INF("auxv", S_IRUSR, pid_auxv),
2603 INF("status", S_IRUGO, pid_status), 2609 ONE("status", S_IRUGO, pid_status),
2604 INF("limits", S_IRUSR, pid_limits), 2610 INF("limits", S_IRUSR, pid_limits),
2605#ifdef CONFIG_SCHED_DEBUG 2611#ifdef CONFIG_SCHED_DEBUG
2606 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2612 REG("sched", S_IRUGO|S_IWUSR, pid_sched),
2607#endif 2613#endif
2608 INF("cmdline", S_IRUGO, pid_cmdline), 2614 INF("cmdline", S_IRUGO, pid_cmdline),
2609 INF("stat", S_IRUGO, tid_stat), 2615 ONE("stat", S_IRUGO, tid_stat),
2610 INF("statm", S_IRUGO, pid_statm), 2616 ONE("statm", S_IRUGO, pid_statm),
2611 REG("maps", S_IRUGO, maps), 2617 REG("maps", S_IRUGO, maps),
2612#ifdef CONFIG_NUMA 2618#ifdef CONFIG_NUMA
2613 REG("numa_maps", S_IRUGO, numa_maps), 2619 REG("numa_maps", S_IRUGO, numa_maps),
@@ -2617,9 +2623,10 @@ static const struct pid_entry tid_base_stuff[] = {
2617 LNK("root", root), 2623 LNK("root", root),
2618 LNK("exe", exe), 2624 LNK("exe", exe),
2619 REG("mounts", S_IRUGO, mounts), 2625 REG("mounts", S_IRUGO, mounts),
2620#ifdef CONFIG_MMU 2626#ifdef CONFIG_PROC_PAGE_MONITOR
2621 REG("clear_refs", S_IWUSR, clear_refs), 2627 REG("clear_refs", S_IWUSR, clear_refs),
2622 REG("smaps", S_IRUGO, smaps), 2628 REG("smaps", S_IRUGO, smaps),
2629 REG("pagemap", S_IRUSR, pagemap),
2623#endif 2630#endif
2624#ifdef CONFIG_SECURITY 2631#ifdef CONFIG_SECURITY
2625 DIR("attr", S_IRUGO|S_IXUGO, attr_dir), 2632 DIR("attr", S_IRUGO|S_IXUGO, attr_dir),