netns xfrm: fix "ip xfrm state|policy count" misreport
[safe/jmp/linux-2.6] / fs / proc / base.c
index 5bc5870..e42bbd8 100644 (file)
@@ -1187,17 +1187,16 @@ static ssize_t proc_fault_inject_write(struct file * file,
                count = sizeof(buffer) - 1;
        if (copy_from_user(buffer, buf, count))
                return -EFAULT;
-       make_it_fail = simple_strtol(buffer, &end, 0);
-       if (*end == '\n')
-               end++;
+       make_it_fail = simple_strtol(strstrip(buffer), &end, 0);
+       if (*end)
+               return -EINVAL;
        task = get_proc_task(file->f_dentry->d_inode);
        if (!task)
                return -ESRCH;
        task->make_it_fail = make_it_fail;
        put_task_struct(task);
-       if (end - buffer == 0)
-               return -EIO;
-       return end - buffer;
+
+       return count;
 }
 
 static const struct file_operations proc_fault_inject_operations = {
@@ -1266,6 +1265,72 @@ static const struct file_operations proc_pid_sched_operations = {
 
 #endif
 
+static ssize_t comm_write(struct file *file, const char __user *buf,
+                               size_t count, loff_t *offset)
+{
+       struct inode *inode = file->f_path.dentry->d_inode;
+       struct task_struct *p;
+       char buffer[TASK_COMM_LEN];
+
+       memset(buffer, 0, sizeof(buffer));
+       if (count > sizeof(buffer) - 1)
+               count = sizeof(buffer) - 1;
+       if (copy_from_user(buffer, buf, count))
+               return -EFAULT;
+
+       p = get_proc_task(inode);
+       if (!p)
+               return -ESRCH;
+
+       if (same_thread_group(current, p))
+               set_task_comm(p, buffer);
+       else
+               count = -EINVAL;
+
+       put_task_struct(p);
+
+       return count;
+}
+
+static int comm_show(struct seq_file *m, void *v)
+{
+       struct inode *inode = m->private;
+       struct task_struct *p;
+
+       p = get_proc_task(inode);
+       if (!p)
+               return -ESRCH;
+
+       task_lock(p);
+       seq_printf(m, "%s\n", p->comm);
+       task_unlock(p);
+
+       put_task_struct(p);
+
+       return 0;
+}
+
+static int comm_open(struct inode *inode, struct file *filp)
+{
+       int ret;
+
+       ret = single_open(filp, comm_show, NULL);
+       if (!ret) {
+               struct seq_file *m = filp->private_data;
+
+               m->private = inode;
+       }
+       return ret;
+}
+
+static const struct file_operations proc_pid_set_comm_operations = {
+       .open           = comm_open,
+       .read           = seq_read,
+       .write          = comm_write,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 /*
  * We added or removed a vma mapping the executable. The vmas are only mapped
  * during exec and are not mapped with the mmap system call.
@@ -1354,7 +1419,6 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
                goto out;
 
        error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
-       nd->last_type = LAST_BIND;
 out:
        return ERR_PTR(error);
 }
@@ -2201,7 +2265,7 @@ static const struct inode_operations proc_attr_dir_inode_operations = {
 
 #endif
 
-#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
+#ifdef CONFIG_ELF_CORE
 static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf,
                                         size_t count, loff_t *ppos)
 {
@@ -2505,6 +2569,7 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_SCHED_DEBUG
        REG("sched",      S_IRUGO|S_IWUSR, proc_pid_sched_operations),
 #endif
+       REG("comm",      S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
 #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
        INF("syscall",    S_IRUSR, proc_pid_syscall),
 #endif
@@ -2557,7 +2622,7 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_FAULT_INJECTION
        REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
 #endif
-#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
+#ifdef CONFIG_ELF_CORE
        REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
 #endif
 #ifdef CONFIG_TASK_IO_ACCOUNTING
@@ -2598,8 +2663,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
        name.len = snprintf(buf, sizeof(buf), "%d", pid);
        dentry = d_hash_and_lookup(mnt->mnt_root, &name);
        if (dentry) {
-               if (!(current->flags & PF_EXITING))
-                       shrink_dcache_parent(dentry);
+               shrink_dcache_parent(dentry);
                d_drop(dentry);
                dput(dentry);
        }
@@ -2840,6 +2904,7 @@ static const struct pid_entry tid_base_stuff[] = {
 #ifdef CONFIG_SCHED_DEBUG
        REG("sched",     S_IRUGO|S_IWUSR, proc_pid_sched_operations),
 #endif
+       REG("comm",      S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
 #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
        INF("syscall",   S_IRUSR, proc_pid_syscall),
 #endif