Merge branches 'delete-gts-bfs', 'misc', 'novell-bugzilla-757888-numa' and 'osc-pcie...
[firefly-linux-kernel-4.4.55.git] / fs / proc / base.c
index 437195f204e14e908bdda87ace0e8b0ce81efb21..1b6c84cbdb732e5684ccaa823548b8780cf1c16d 100644 (file)
@@ -695,8 +695,6 @@ static int __mem_open(struct inode *inode, struct file *file, unsigned int mode)
                mmput(mm);
        }
 
-       /* OK to pass negative loff_t, we can catch out-of-range */
-       file->f_mode |= FMODE_UNSIGNED_OFFSET;
        file->private_data = mm;
 
        return 0;
@@ -704,7 +702,12 @@ static int __mem_open(struct inode *inode, struct file *file, unsigned int mode)
 
 static int mem_open(struct inode *inode, struct file *file)
 {
-       return __mem_open(inode, file, PTRACE_MODE_ATTACH);
+       int ret = __mem_open(inode, file, PTRACE_MODE_ATTACH);
+
+       /* OK to pass negative loff_t, we can catch out-of-range */
+       file->f_mode |= FMODE_UNSIGNED_OFFSET;
+
+       return ret;
 }
 
 static ssize_t mem_rw(struct file *file, char __user *buf,
@@ -827,15 +830,16 @@ static ssize_t environ_read(struct file *file, char __user *buf,
        if (!atomic_inc_not_zero(&mm->mm_users))
                goto free;
        while (count > 0) {
-               int this_len, retval, max_len;
+               size_t this_len, max_len;
+               int retval;
 
-               this_len = mm->env_end - (mm->env_start + src);
-
-               if (this_len <= 0)
+               if (src >= (mm->env_end - mm->env_start))
                        break;
 
-               max_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
-               this_len = (this_len > max_len) ? max_len : this_len;
+               this_len = mm->env_end - (mm->env_start + src);
+
+               max_len = min_t(size_t, PAGE_SIZE, count);
+               this_len = min(max_len, this_len);
 
                retval = access_remote_vm(mm, (mm->env_start + src),
                        page, this_len, 0);
@@ -1427,16 +1431,19 @@ static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
 static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *inode = dentry->d_inode;
+       struct path path;
        int error = -EACCES;
 
-       /* We don't need a base pointer in the /proc filesystem */
-       path_put(&nd->path);
-
        /* Are we allowed to snoop on the tasks file descriptors? */
        if (!proc_fd_access_allowed(inode))
                goto out;
 
-       error = PROC_I(inode)->op.proc_get_link(dentry, &nd->path);
+       error = PROC_I(inode)->op.proc_get_link(dentry, &path);
+       if (error)
+               goto out;
+
+       nd_jump_link(nd, &path);
+       return NULL;
 out:
        return ERR_PTR(error);
 }
@@ -1601,13 +1608,13 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
  * made this apply to all per process world readable and executable
  * directories.
  */
-int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
+int pid_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct inode *inode;
        struct task_struct *task;
        const struct cred *cred;
 
-       if (nd && nd->flags & LOOKUP_RCU)
+       if (flags & LOOKUP_RCU)
                return -ECHILD;
 
        inode = dentry->d_inode;
@@ -1781,7 +1788,7 @@ static int proc_fd_link(struct dentry *dentry, struct path *path)
        return proc_fd_info(dentry->d_inode, path, NULL);
 }
 
-static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct inode *inode;
        struct task_struct *task;
@@ -1789,7 +1796,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
        struct files_struct *files;
        const struct cred *cred;
 
-       if (nd && nd->flags & LOOKUP_RCU)
+       if (flags & LOOKUP_RCU)
                return -ECHILD;
 
        inode = dentry->d_inode;
@@ -1868,7 +1875,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
        d_set_d_op(dentry, &tid_fd_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
-       if (tid_fd_revalidate(dentry, NULL))
+       if (tid_fd_revalidate(dentry, 0))
                error = NULL;
 
  out:
@@ -1956,7 +1963,7 @@ out_no_task:
 }
 
 static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
-                                   struct nameidata *nd)
+                                   unsigned int flags)
 {
        return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
 }
@@ -2003,7 +2010,7 @@ static int dname_to_vma_addr(struct dentry *dentry,
        return 0;
 }
 
-static int map_files_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
 {
        unsigned long vm_start, vm_end;
        bool exact_vma_exists = false;
@@ -2013,7 +2020,7 @@ static int map_files_d_revalidate(struct dentry *dentry, struct nameidata *nd)
        struct inode *inode;
        int status = 0;
 
-       if (nd && nd->flags & LOOKUP_RCU)
+       if (flags & LOOKUP_RCU)
                return -ECHILD;
 
        if (!capable(CAP_SYS_ADMIN)) {
@@ -2145,7 +2152,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,
 }
 
 static struct dentry *proc_map_files_lookup(struct inode *dir,
-               struct dentry *dentry, struct nameidata *nd)
+               struct dentry *dentry, unsigned int flags)
 {
        unsigned long vm_start, vm_end;
        struct vm_area_struct *vma;
@@ -2371,7 +2378,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
        d_set_d_op(dentry, &tid_fd_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
-       if (tid_fd_revalidate(dentry, NULL))
+       if (tid_fd_revalidate(dentry, 0))
                error = NULL;
 
  out:
@@ -2380,7 +2387,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
 
 static struct dentry *proc_lookupfdinfo(struct inode *dir,
                                        struct dentry *dentry,
-                                       struct nameidata *nd)
+                                       unsigned int flags)
 {
        return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
 }
@@ -2430,7 +2437,7 @@ static struct dentry *proc_pident_instantiate(struct inode *dir,
        d_set_d_op(dentry, &pid_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
-       if (pid_revalidate(dentry, NULL))
+       if (pid_revalidate(dentry, 0))
                error = NULL;
 out:
        return error;
@@ -2630,7 +2637,7 @@ static const struct file_operations proc_attr_dir_operations = {
 };
 
 static struct dentry *proc_attr_dir_lookup(struct inode *dir,
-                               struct dentry *dentry, struct nameidata *nd)
+                               struct dentry *dentry, unsigned int flags)
 {
        return proc_pident_lookup(dir, dentry,
                                  attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
@@ -3114,7 +3121,8 @@ static const struct file_operations proc_tgid_base_operations = {
        .llseek         = default_llseek,
 };
 
-static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
+{
        return proc_pident_lookup(dir, dentry,
                                  tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
 }
@@ -3237,13 +3245,13 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
 
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
-       if (pid_revalidate(dentry, NULL))
+       if (pid_revalidate(dentry, 0))
                error = NULL;
 out:
        return error;
 }
 
-struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
 {
        struct dentry *result;
        struct task_struct *task;
@@ -3470,7 +3478,8 @@ static int proc_tid_base_readdir(struct file * filp,
                                   tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
 }
 
-static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
+{
        return proc_pident_lookup(dir, dentry,
                                  tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
 }
@@ -3508,13 +3517,13 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
 
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
-       if (pid_revalidate(dentry, NULL))
+       if (pid_revalidate(dentry, 0))
                error = NULL;
 out:
        return error;
 }
 
-static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
 {
        struct dentry *result = ERR_PTR(-ENOENT);
        struct task_struct *task;