Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 299811 Details for
Bug 399243
Kernel: proc: clean up and fix /proc/<pid>/mem handling (CVE-2012-0056)
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
proc-mem-handling patch for 2.6.39-gentoo-r3 kernel
backport-proc-mem-handling-fix-2.6.39.patch (text/plain), 4.76 KB, created by
werner maier
on 2012-01-25 09:49:59 UTC
(
hide
)
Description:
proc-mem-handling patch for 2.6.39-gentoo-r3 kernel
Filename:
MIME Type:
Creator:
werner maier
Created:
2012-01-25 09:49:59 UTC
Size:
4.76 KB
patch
obsolete
>--- linux-2.6.39-gentoo-r3/fs/proc/base.c 2011-05-19 06:06:34.000000000 +0200 >+++ linux-2.6.39-gentoo-r103/fs/proc/base.c 2012-01-24 17:03:14.033342499 +0100 >@@ -191,65 +191,8 @@ > return result; > } > >-static struct mm_struct *__check_mem_permission(struct task_struct *task) >-{ >- struct mm_struct *mm; >- >- mm = get_task_mm(task); >- if (!mm) >- return ERR_PTR(-EINVAL); > >- /* >- * A task can always look at itself, in case it chooses >- * to use system calls instead of load instructions. >- */ >- if (task == current) >- return mm; >- >- /* >- * If current is actively ptrace'ing, and would also be >- * permitted to freshly attach with ptrace now, permit it. >- */ >- if (task_is_stopped_or_traced(task)) { >- int match; >- rcu_read_lock(); >- match = (tracehook_tracer_task(task) == current); >- rcu_read_unlock(); >- if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH)) >- return mm; >- } >- >- /* >- * No one else is allowed. >- */ >- mmput(mm); >- return ERR_PTR(-EPERM); >-} >- >-/* >- * If current may access user memory in @task return a reference to the >- * corresponding mm, otherwise ERR_PTR. >- */ >-static struct mm_struct *check_mem_permission(struct task_struct *task) >-{ >- struct mm_struct *mm; >- int err; >- >- /* >- * Avoid racing if task exec's as we might get a new mm but validate >- * against old credentials. >- */ >- err = mutex_lock_killable(&task->signal->cred_guard_mutex); >- if (err) >- return ERR_PTR(err); >- >- mm = __check_mem_permission(task); >- mutex_unlock(&task->signal->cred_guard_mutex); >- >- return mm; >-} >- >-struct mm_struct *mm_for_maps(struct task_struct *task) >+static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) > { > struct mm_struct *mm; > int err; >@@ -260,7 +203,7 @@ > > mm = get_task_mm(task); > if (mm && mm != current->mm && >- !ptrace_may_access(task, PTRACE_MODE_READ)) { >+ !ptrace_may_access(task, mode)) { > mmput(mm); > mm = ERR_PTR(-EACCES); > } >@@ -269,6 +212,11 @@ > return mm; > } > >+struct mm_struct *mm_for_maps(struct task_struct *task) >+{ >+ return mm_access(task, PTRACE_MODE_READ); >+} >+ > static int proc_pid_cmdline(struct task_struct *task, char * buffer) > { > int res = 0; >@@ -813,38 +761,40 @@ > > static int mem_open(struct inode* inode, struct file* file) > { >- file->private_data = (void*)((long)current->self_exec_id); >+ struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); >+ struct mm_struct *mm; >+ >+ if (!task) >+ return -ESRCH; >+ >+ mm = mm_access(task, PTRACE_MODE_ATTACH); >+ put_task_struct(task); >+ >+ if (IS_ERR(mm)) >+ return PTR_ERR(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; > } > > static ssize_t mem_read(struct file * file, char __user * buf, > size_t count, loff_t *ppos) > { >- struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); >+ int ret; > char *page; > unsigned long src = *ppos; >- int ret = -ESRCH; >- struct mm_struct *mm; >+ struct mm_struct *mm = file->private_data; > >- if (!task) >- goto out_no_task; > >- ret = -ENOMEM; >+ if (!mm) >+ return 0; >+ > page = (char *)__get_free_page(GFP_TEMPORARY); > if (!page) >- goto out; >- >- mm = check_mem_permission(task); >- ret = PTR_ERR(mm); >- if (IS_ERR(mm)) >- goto out_free; >- >- ret = -EIO; >- >- if (file->private_data != (void*)((long)current->self_exec_id)) >- goto out_put; >+ return -ENOMEM; > > ret = 0; > >@@ -871,13 +821,7 @@ > } > *ppos = src; > >-out_put: >- mmput(mm); >-out_free: > free_page((unsigned long) page); >-out: >- put_task_struct(task); >-out_no_task: > return ret; > } > >@@ -886,27 +830,15 @@ > { > int copied; > char *page; >- struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); > unsigned long dst = *ppos; >- struct mm_struct *mm; >- >- copied = -ESRCH; >- if (!task) >- goto out_no_task; >+ struct mm_struct *mm = file->private_data; > >- mm = check_mem_permission(task); >- copied = PTR_ERR(mm); >- if (IS_ERR(mm)) >- goto out_task; >- >- copied = -EIO; >- if (file->private_data != (void *)((long)current->self_exec_id)) >- goto out_mm; >+ if (!mm) >+ return 0; > >- copied = -ENOMEM; > page = (char *)__get_free_page(GFP_TEMPORARY); > if (!page) >- goto out_mm; >+ return -ENOMEM; > > copied = 0; > while (count > 0) { >@@ -930,11 +862,6 @@ > } > *ppos = dst; > free_page((unsigned long) page); >-out_mm: >- mmput(mm); >-out_task: >- put_task_struct(task); >-out_no_task: > return copied; > } > >@@ -954,11 +881,20 @@ > return file->f_pos; > } > >+static int mem_release(struct inode *inode, struct file *file) >+{ >+ struct mm_struct *mm = file->private_data; >+ >+ mmput(mm); >+ return 0; >+} >+ > static const struct file_operations proc_mem_operations = { > .llseek = mem_lseek, > .read = mem_read, > .write = mem_write, > .open = mem_open, >+ .release = mem_release, > }; > > static ssize_t environ_read(struct file *file, char __user *buf,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 399243
: 299811