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.c121
1 files changed, 101 insertions, 20 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index af643b5aefe8..8418fcc0a6ab 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -81,6 +81,7 @@
81#include <linux/elf.h> 81#include <linux/elf.h>
82#include <linux/pid_namespace.h> 82#include <linux/pid_namespace.h>
83#include <linux/fs_struct.h> 83#include <linux/fs_struct.h>
84#include <linux/slab.h>
84#include "internal.h" 85#include "internal.h"
85 86
86/* NOTE: 87/* NOTE:
@@ -442,12 +443,13 @@ static const struct file_operations proc_lstats_operations = {
442unsigned long badness(struct task_struct *p, unsigned long uptime); 443unsigned long badness(struct task_struct *p, unsigned long uptime);
443static int proc_oom_score(struct task_struct *task, char *buffer) 444static int proc_oom_score(struct task_struct *task, char *buffer)
444{ 445{
445 unsigned long points; 446 unsigned long points = 0;
446 struct timespec uptime; 447 struct timespec uptime;
447 448
448 do_posix_clock_monotonic_gettime(&uptime); 449 do_posix_clock_monotonic_gettime(&uptime);
449 read_lock(&tasklist_lock); 450 read_lock(&tasklist_lock);
450 points = badness(task->group_leader, uptime.tv_sec); 451 if (pid_alive(task))
452 points = badness(task, uptime.tv_sec);
451 read_unlock(&tasklist_lock); 453 read_unlock(&tasklist_lock);
452 return sprintf(buffer, "%lu\n", points); 454 return sprintf(buffer, "%lu\n", points);
453} 455}
@@ -647,17 +649,11 @@ static int mounts_release(struct inode *inode, struct file *file)
647static unsigned mounts_poll(struct file *file, poll_table *wait) 649static unsigned mounts_poll(struct file *file, poll_table *wait)
648{ 650{
649 struct proc_mounts *p = file->private_data; 651 struct proc_mounts *p = file->private_data;
650 struct mnt_namespace *ns = p->ns;
651 unsigned res = POLLIN | POLLRDNORM; 652 unsigned res = POLLIN | POLLRDNORM;
652 653
653 poll_wait(file, &ns->poll, wait); 654 poll_wait(file, &p->ns->poll, wait);
654 655 if (mnt_had_events(p))
655 spin_lock(&vfsmount_lock);
656 if (p->event != ns->event) {
657 p->event = ns->event;
658 res |= POLLERR | POLLPRI; 656 res |= POLLERR | POLLPRI;
659 }
660 spin_unlock(&vfsmount_lock);
661 657
662 return res; 658 return res;
663} 659}
@@ -1095,8 +1091,12 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
1095 if (!capable(CAP_AUDIT_CONTROL)) 1091 if (!capable(CAP_AUDIT_CONTROL))
1096 return -EPERM; 1092 return -EPERM;
1097 1093
1098 if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) 1094 rcu_read_lock();
1095 if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) {
1096 rcu_read_unlock();
1099 return -EPERM; 1097 return -EPERM;
1098 }
1099 rcu_read_unlock();
1100 1100
1101 if (count >= PAGE_SIZE) 1101 if (count >= PAGE_SIZE)
1102 count = PAGE_SIZE - 1; 1102 count = PAGE_SIZE - 1;
@@ -1265,6 +1265,72 @@ static const struct file_operations proc_pid_sched_operations = {
1265 1265
1266#endif 1266#endif
1267 1267
1268static ssize_t comm_write(struct file *file, const char __user *buf,
1269 size_t count, loff_t *offset)
1270{
1271 struct inode *inode = file->f_path.dentry->d_inode;
1272 struct task_struct *p;
1273 char buffer[TASK_COMM_LEN];
1274
1275 memset(buffer, 0, sizeof(buffer));
1276 if (count > sizeof(buffer) - 1)
1277 count = sizeof(buffer) - 1;
1278 if (copy_from_user(buffer, buf, count))
1279 return -EFAULT;
1280
1281 p = get_proc_task(inode);
1282 if (!p)
1283 return -ESRCH;
1284
1285 if (same_thread_group(current, p))
1286 set_task_comm(p, buffer);
1287 else
1288 count = -EINVAL;
1289
1290 put_task_struct(p);
1291
1292 return count;
1293}
1294
1295static int comm_show(struct seq_file *m, void *v)
1296{
1297 struct inode *inode = m->private;
1298 struct task_struct *p;
1299
1300 p = get_proc_task(inode);
1301 if (!p)
1302 return -ESRCH;
1303
1304 task_lock(p);
1305 seq_printf(m, "%s\n", p->comm);
1306 task_unlock(p);
1307
1308 put_task_struct(p);
1309
1310 return 0;
1311}
1312
1313static int comm_open(struct inode *inode, struct file *filp)
1314{
1315 int ret;
1316
1317 ret = single_open(filp, comm_show, NULL);
1318 if (!ret) {
1319 struct seq_file *m = filp->private_data;
1320
1321 m->private = inode;
1322 }
1323 return ret;
1324}
1325
1326static const struct file_operations proc_pid_set_comm_operations = {
1327 .open = comm_open,
1328 .read = seq_read,
1329 .write = comm_write,
1330 .llseek = seq_lseek,
1331 .release = single_release,
1332};
1333
1268/* 1334/*
1269 * We added or removed a vma mapping the executable. The vmas are only mapped 1335 * We added or removed a vma mapping the executable. The vmas are only mapped
1270 * during exec and are not mapped with the mmap system call. 1336 * during exec and are not mapped with the mmap system call.
@@ -1353,7 +1419,6 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
1353 goto out; 1419 goto out;
1354 1420
1355 error = PROC_I(inode)->op.proc_get_link(inode, &nd->path); 1421 error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
1356 nd->last_type = LAST_BIND;
1357out: 1422out:
1358 return ERR_PTR(error); 1423 return ERR_PTR(error);
1359} 1424}
@@ -2200,7 +2265,7 @@ static const struct inode_operations proc_attr_dir_inode_operations = {
2200 2265
2201#endif 2266#endif
2202 2267
2203#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 2268#ifdef CONFIG_ELF_CORE
2204static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf, 2269static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf,
2205 size_t count, loff_t *ppos) 2270 size_t count, loff_t *ppos)
2206{ 2271{
@@ -2304,16 +2369,30 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
2304{ 2369{
2305 struct pid_namespace *ns = dentry->d_sb->s_fs_info; 2370 struct pid_namespace *ns = dentry->d_sb->s_fs_info;
2306 pid_t tgid = task_tgid_nr_ns(current, ns); 2371 pid_t tgid = task_tgid_nr_ns(current, ns);
2307 char tmp[PROC_NUMBUF]; 2372 char *name = ERR_PTR(-ENOENT);
2308 if (!tgid) 2373 if (tgid) {
2309 return ERR_PTR(-ENOENT); 2374 name = __getname();
2310 sprintf(tmp, "%d", task_tgid_nr_ns(current, ns)); 2375 if (!name)
2311 return ERR_PTR(vfs_follow_link(nd,tmp)); 2376 name = ERR_PTR(-ENOMEM);
2377 else
2378 sprintf(name, "%d", tgid);
2379 }
2380 nd_set_link(nd, name);
2381 return NULL;
2382}
2383
2384static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
2385 void *cookie)
2386{
2387 char *s = nd_get_link(nd);
2388 if (!IS_ERR(s))
2389 __putname(s);
2312} 2390}
2313 2391
2314static const struct inode_operations proc_self_inode_operations = { 2392static const struct inode_operations proc_self_inode_operations = {
2315 .readlink = proc_self_readlink, 2393 .readlink = proc_self_readlink,
2316 .follow_link = proc_self_follow_link, 2394 .follow_link = proc_self_follow_link,
2395 .put_link = proc_self_put_link,
2317}; 2396};
2318 2397
2319/* 2398/*
@@ -2504,6 +2583,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2504#ifdef CONFIG_SCHED_DEBUG 2583#ifdef CONFIG_SCHED_DEBUG
2505 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), 2584 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2506#endif 2585#endif
2586 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2507#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2587#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2508 INF("syscall", S_IRUSR, proc_pid_syscall), 2588 INF("syscall", S_IRUSR, proc_pid_syscall),
2509#endif 2589#endif
@@ -2556,7 +2636,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2556#ifdef CONFIG_FAULT_INJECTION 2636#ifdef CONFIG_FAULT_INJECTION
2557 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), 2637 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
2558#endif 2638#endif
2559#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 2639#ifdef CONFIG_ELF_CORE
2560 REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations), 2640 REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
2561#endif 2641#endif
2562#ifdef CONFIG_TASK_IO_ACCOUNTING 2642#ifdef CONFIG_TASK_IO_ACCOUNTING
@@ -2829,7 +2909,7 @@ out_no_task:
2829 */ 2909 */
2830static const struct pid_entry tid_base_stuff[] = { 2910static const struct pid_entry tid_base_stuff[] = {
2831 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations), 2911 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
2832 DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations), 2912 DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
2833 REG("environ", S_IRUSR, proc_environ_operations), 2913 REG("environ", S_IRUSR, proc_environ_operations),
2834 INF("auxv", S_IRUSR, proc_pid_auxv), 2914 INF("auxv", S_IRUSR, proc_pid_auxv),
2835 ONE("status", S_IRUGO, proc_pid_status), 2915 ONE("status", S_IRUGO, proc_pid_status),
@@ -2838,6 +2918,7 @@ static const struct pid_entry tid_base_stuff[] = {
2838#ifdef CONFIG_SCHED_DEBUG 2918#ifdef CONFIG_SCHED_DEBUG
2839 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), 2919 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2840#endif 2920#endif
2921 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2841#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2922#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2842 INF("syscall", S_IRUSR, proc_pid_syscall), 2923 INF("syscall", S_IRUSR, proc_pid_syscall),
2843#endif 2924#endif