]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/proc/base.c
proc read mm's {arg,env}_{start,end} with mmap semaphore taken.
[mirror_ubuntu-bionic-kernel.git] / fs / proc / base.c
index 2cf5d7e373757d631de6f9d8a174287d46058219..4f764c2ac1a53db75c7c116cdb3bd4b45074c647 100644 (file)
@@ -403,7 +403,7 @@ static const struct file_operations proc_pid_cmdline_ops = {
 static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns,
                         struct pid *pid, struct task_struct *task)
 {
-       struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ);
+       struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
        if (mm && !IS_ERR(mm)) {
                unsigned int nwords = 0;
                do {
@@ -430,7 +430,8 @@ static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
 
        wchan = get_wchan(task);
 
-       if (wchan && ptrace_may_access(task, PTRACE_MODE_READ) && !lookup_symbol_name(wchan, symname))
+       if (wchan && ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)
+                       && !lookup_symbol_name(wchan, symname))
                seq_printf(m, "%s", symname);
        else
                seq_putc(m, '0');
@@ -444,7 +445,7 @@ static int lock_trace(struct task_struct *task)
        int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
        if (err)
                return err;
-       if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
                mutex_unlock(&task->signal->cred_guard_mutex);
                return -EPERM;
        }
@@ -697,7 +698,7 @@ static int proc_fd_access_allowed(struct inode *inode)
         */
        task = get_proc_task(inode);
        if (task) {
-               allowed = ptrace_may_access(task, PTRACE_MODE_READ);
+               allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
                put_task_struct(task);
        }
        return allowed;
@@ -732,7 +733,7 @@ static bool has_pid_permissions(struct pid_namespace *pid,
                return true;
        if (in_group_p(pid->pid_gid))
                return true;
-       return ptrace_may_access(task, PTRACE_MODE_READ);
+       return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
 }
 
 
@@ -809,7 +810,7 @@ struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
        struct mm_struct *mm = ERR_PTR(-ESRCH);
 
        if (task) {
-               mm = mm_access(task, mode);
+               mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
                put_task_struct(task);
 
                if (!IS_ERR_OR_NULL(mm)) {
@@ -952,6 +953,7 @@ static ssize_t environ_read(struct file *file, char __user *buf,
        unsigned long src = *ppos;
        int ret = 0;
        struct mm_struct *mm = file->private_data;
+       unsigned long env_start, env_end;
 
        if (!mm)
                return 0;
@@ -963,19 +965,25 @@ static ssize_t environ_read(struct file *file, char __user *buf,
        ret = 0;
        if (!atomic_inc_not_zero(&mm->mm_users))
                goto free;
+
+       down_read(&mm->mmap_sem);
+       env_start = mm->env_start;
+       env_end = mm->env_end;
+       up_read(&mm->mmap_sem);
+
        while (count > 0) {
                size_t this_len, max_len;
                int retval;
 
-               if (src >= (mm->env_end - mm->env_start))
+               if (src >= (env_end - env_start))
                        break;
 
-               this_len = mm->env_end - (mm->env_start + src);
+               this_len = env_end - (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),
+               retval = access_remote_vm(mm, (env_start + src),
                        page, this_len, 0);
 
                if (retval <= 0) {
@@ -1860,7 +1868,7 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
        if (!task)
                goto out_notask;
 
-       mm = mm_access(task, PTRACE_MODE_READ);
+       mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
        if (IS_ERR_OR_NULL(mm))
                goto out;
 
@@ -2013,7 +2021,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
                goto out;
 
        result = -EACCES;
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
                goto out_put_task;
 
        result = -ENOENT;
@@ -2066,7 +2074,7 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
                goto out;
 
        ret = -EACCES;
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
                goto out_put_task;
 
        ret = 0;
@@ -2533,7 +2541,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh
        if (result)
                return result;
 
-       if (!ptrace_may_access(task, PTRACE_MODE_READ)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
                result = -EACCES;
                goto out_unlock;
        }