vfs: show O_CLOEXE bit properly in /proc/<pid>/fdinfo/<fd> files
[pandora-kernel.git] / fs / proc / base.c
index fc5bc27..5eb0206 100644 (file)
@@ -216,7 +216,7 @@ static struct mm_struct *__check_mem_permission(struct task_struct *task)
        if (task_is_stopped_or_traced(task)) {
                int match;
                rcu_read_lock();
-               match = (tracehook_tracer_task(task) == current);
+               match = (ptrace_parent(task) == current);
                rcu_read_unlock();
                if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
                        return mm;
@@ -673,7 +673,7 @@ static int mounts_open_common(struct inode *inode, struct file *file,
        p->m.private = p;
        p->ns = ns;
        p->root = root;
-       p->event = ns->event;
+       p->m.poll_event = ns->event;
 
        return 0;
 
@@ -1118,10 +1118,9 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
         * Warn that /proc/pid/oom_adj is deprecated, see
         * Documentation/feature-removal-schedule.txt.
         */
-       printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, "
-                       "please use /proc/%d/oom_score_adj instead.\n",
-                       current->comm, task_pid_nr(current),
-                       task_pid_nr(task), task_pid_nr(task));
+       printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
+                 current->comm, task_pid_nr(current), task_pid_nr(task),
+                 task_pid_nr(task));
        task->signal->oom_adj = oom_adjust;
        /*
         * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
@@ -1920,6 +1919,14 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
                spin_lock(&files->file_lock);
                file = fcheck_files(files, fd);
                if (file) {
+                       unsigned int f_flags;
+                       struct fdtable *fdt;
+
+                       fdt = files_fdtable(files);
+                       f_flags = file->f_flags & ~O_CLOEXEC;
+                       if (FD_ISSET(fd, fdt->close_on_exec))
+                               f_flags |= O_CLOEXEC;
+
                        if (path) {
                                *path = file->f_path;
                                path_get(&file->f_path);
@@ -1929,7 +1936,7 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
                                         "pos:\t%lli\n"
                                         "flags:\t0%o\n",
                                         (long long) file->f_pos,
-                                        file->f_flags);
+                                        f_flags);
                        spin_unlock(&files->file_lock);
                        put_files_struct(files);
                        return 0;
@@ -2167,9 +2174,9 @@ static const struct file_operations proc_fd_operations = {
  * /proc/pid/fd needs a special permission handler so that a process can still
  * access /proc/self/fd after it has executed a setuid().
  */
-static int proc_fd_permission(struct inode *inode, int mask, unsigned int flags)
+static int proc_fd_permission(struct inode *inode, int mask)
 {
-       int rv = generic_permission(inode, mask, flags, NULL);
+       int rv = generic_permission(inode, mask);
        if (rv == 0)
                return 0;
        if (task_pid(current) == proc_pid(inode))
@@ -2707,9 +2714,16 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
 {
        struct task_io_accounting acct = task->ioac;
        unsigned long flags;
+       int result;
 
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
-               return -EACCES;
+       result = mutex_lock_killable(&task->signal->cred_guard_mutex);
+       if (result)
+               return result;
+
+       if (!ptrace_may_access(task, PTRACE_MODE_READ)) {
+               result = -EACCES;
+               goto out_unlock;
+       }
 
        if (whole && lock_task_sighand(task, &flags)) {
                struct task_struct *t = task;
@@ -2720,7 +2734,7 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
 
                unlock_task_sighand(task, &flags);
        }
-       return sprintf(buffer,
+       result = sprintf(buffer,
                        "rchar: %llu\n"
                        "wchar: %llu\n"
                        "syscr: %llu\n"
@@ -2735,6 +2749,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
                        (unsigned long long)acct.read_bytes,
                        (unsigned long long)acct.write_bytes,
                        (unsigned long long)acct.cancelled_write_bytes);
+out_unlock:
+       mutex_unlock(&task->signal->cred_guard_mutex);
+       return result;
 }
 
 static int proc_tid_io_accounting(struct task_struct *task, char *buffer)