From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1RpR1r-000491-AR for garchives@archives.gentoo.org; Mon, 23 Jan 2012 21:02:15 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 389C6E0E1F; Mon, 23 Jan 2012 21:02:08 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id EF728E0E1A for ; Mon, 23 Jan 2012 21:02:07 +0000 (UTC) Received: from flycatcher.gentoo.org (flycatcher.gentoo.org [81.93.255.6]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 329631B4008 for ; Mon, 23 Jan 2012 21:02:07 +0000 (UTC) Received: by flycatcher.gentoo.org (Postfix, from userid 2238) id E524F2004C; Mon, 23 Jan 2012 21:02:05 +0000 (UTC) From: "Markos Chandras (hwoarang)" To: gentoo-commits@lists.gentoo.org Reply-To: gentoo-dev@lists.gentoo.org, hwoarang@gentoo.org Subject: [gentoo-commits] gentoo-x86 commit in sys-kernel/pf-sources/files: 2100_proc-mem-handling-fix.patch X-VCS-Repository: gentoo-x86 X-VCS-Files: 2100_proc-mem-handling-fix.patch X-VCS-Directories: sys-kernel/pf-sources/files X-VCS-Committer: hwoarang X-VCS-Committer-Name: Markos Chandras Content-Type: text/plain; charset=utf8 Message-Id: <20120123210205.E524F2004C@flycatcher.gentoo.org> Date: Mon, 23 Jan 2012 21:02:05 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: b1aae65d-0424-492b-90bf-f200494fb060 X-Archives-Hash: 67b30156d729bffd728f7d61b781dfbe hwoarang 12/01/23 21:02:05 Added: 2100_proc-mem-handling-fix.patch Log: Apply fix from gentoo-sources for CVE-2012-0056 in 3.1 and 3.2 kernel s= eries =20 (Portage version: 2.2.0_alpha84/cvs/Linux x86_64) Revision Changes Path 1.1 sys-kernel/pf-sources/files/2100_proc-mem-handling-f= ix.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-kernel/pf-sour= ces/files/2100_proc-mem-handling-fix.patch?rev=3D1.1&view=3Dmarkup plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-kernel/pf-sour= ces/files/2100_proc-mem-handling-fix.patch?rev=3D1.1&content-type=3Dtext/= plain Index: 2100_proc-mem-handling-fix.patch =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >From bd3d50227ece7d8234cdc5b3d3486ff90e92d545 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Jan 2012 11:25:40 -0500 Subject: [PATCH] 3.2-stable patches added patches: proc-clean-up-and-fix-proc-pid-mem-handling.patch --- ...oc-clean-up-and-fix-proc-pid-mem-handling.patch | 269 ++++++++++++++= ++++++ queue-3.2/series | 1 + 2 files changed, 270 insertions(+), 0 deletions(-) create mode 100644 queue-3.2/proc-clean-up-and-fix-proc-pid-mem-handling= .patch diff --git a/queue-3.2/proc-clean-up-and-fix-proc-pid-mem-handling.patch = b/queue-3.2/proc-clean-up-and-fix-proc-pid-mem-handling.patch new file mode 100644 index 0000000..2acee07 --- /dev/null +++ b/queue-3.2/proc-clean-up-and-fix-proc-pid-mem-handling.patch @@ -0,0 +1,269 @@ +From e268337dfe26dfc7efd422a804dbb27977a3cccc Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Tue, 17 Jan 2012 15:21:19 -0800 +Subject: proc: clean up and fix /proc//mem handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=3DUTF-8 +Content-Transfer-Encoding: 8bit + +From: Linus Torvalds + +commit e268337dfe26dfc7efd422a804dbb27977a3cccc upstream. + +J=C3=83=C2=BCri Aedla reported that the /proc//mem handling really = isn't very +robust, and it also doesn't match the permission checking of any of the +other related files. + +This changes it to do the permission checks at open time, and instead of +tracking the process, it tracks the VM at the time of the open. That +simplifies the code a lot, but does mean that if you hold the file +descriptor open over an execve(), you'll continue to read from the _old_ +VM. + +That is different from our previous behavior, but much simpler. If +somebody actually finds a load where this matters, we'll need to revert +this commit. + +I suspect that nobody will ever notice - because the process mapping +addresses will also have changed as part of the execve. So you cannot +actually usefully access the fd across a VM change simply because all +the offsets for IO would have changed too. + +Reported-by: J=C3=83=C2=BCri Aedla +Cc: Al Viro +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/proc/base.c | 145 +++++++++++++++----------------------------------= -------- + 1 file changed, 39 insertions(+), 106 deletions(-) + +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -194,65 +194,7 @@ static int proc_root_link(struct inode * + return result; + } +=20 +-static struct mm_struct *__check_mem_permission(struct task_struct *tas= k) +-{ +- struct mm_struct *mm; +- +- mm =3D 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 =3D=3D 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 =3D (ptrace_parent(task) =3D=3D 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 =3D mutex_lock_killable(&task->signal->cred_guard_mutex); +- if (err) +- return ERR_PTR(err); +- +- mm =3D __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 i= nt mode) + { + struct mm_struct *mm; + int err; +@@ -263,7 +205,7 @@ struct mm_struct *mm_for_maps(struct tas +=20 + mm =3D get_task_mm(task); + if (mm && mm !=3D current->mm && +- !ptrace_may_access(task, PTRACE_MODE_READ)) { ++ !ptrace_may_access(task, mode)) { + mmput(mm); + mm =3D ERR_PTR(-EACCES); + } +@@ -272,6 +214,11 @@ struct mm_struct *mm_for_maps(struct tas + return mm; + } +=20 ++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 =3D 0; +@@ -816,38 +763,39 @@ static const struct file_operations proc +=20 + static int mem_open(struct inode* inode, struct file* file) + { +- file->private_data =3D (void*)((long)current->self_exec_id); ++ struct task_struct *task =3D get_proc_task(file->f_path.dentry->d_ino= de); ++ struct mm_struct *mm; ++ ++ if (!task) ++ return -ESRCH; ++ ++ mm =3D 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 |=3D FMODE_UNSIGNED_OFFSET; ++ file->private_data =3D mm; ++ + return 0; + } +=20 + static ssize_t mem_read(struct file * file, char __user * buf, + size_t count, loff_t *ppos) + { +- struct task_struct *task =3D get_proc_task(file->f_path.dentry->d_ino= de); ++ int ret; + char *page; + unsigned long src =3D *ppos; +- int ret =3D -ESRCH; +- struct mm_struct *mm; ++ struct mm_struct *mm =3D file->private_data; +=20 +- if (!task) +- goto out_no_task; ++ if (!mm) ++ return 0; +=20 +- ret =3D -ENOMEM; + page =3D (char *)__get_free_page(GFP_TEMPORARY); + if (!page) +- goto out; +- +- mm =3D check_mem_permission(task); +- ret =3D PTR_ERR(mm); +- if (IS_ERR(mm)) +- goto out_free; +- +- ret =3D -EIO; +-=20 +- if (file->private_data !=3D (void*)((long)current->self_exec_id)) +- goto out_put; ++ return -ENOMEM; +=20 + ret =3D 0; + =20 +@@ -874,13 +822,7 @@ static ssize_t mem_read(struct file * fi + } + *ppos =3D src; +=20 +-out_put: +- mmput(mm); +-out_free: + free_page((unsigned long) page); +-out: +- put_task_struct(task); +-out_no_task: + return ret; + } +=20 +@@ -889,27 +831,15 @@ static ssize_t mem_write(struct file * f + { + int copied; + char *page; +- struct task_struct *task =3D get_proc_task(file->f_path.dentry->d_ino= de); + unsigned long dst =3D *ppos; +- struct mm_struct *mm; ++ struct mm_struct *mm =3D file->private_data; +=20 +- copied =3D -ESRCH; +- if (!task) +- goto out_no_task; ++ if (!mm) ++ return 0; +=20 +- copied =3D -ENOMEM; + page =3D (char *)__get_free_page(GFP_TEMPORARY); + if (!page) +- goto out_task; +- +- mm =3D check_mem_permission(task); +- copied =3D PTR_ERR(mm); +- if (IS_ERR(mm)) +- goto out_free; +- +- copied =3D -EIO; +- if (file->private_data !=3D (void *)((long)current->self_exec_id)) +- goto out_mm; ++ return -ENOMEM; +=20 + copied =3D 0; + while (count > 0) { +@@ -933,13 +863,7 @@ static ssize_t mem_write(struct file * f + } + *ppos =3D dst; +=20 +-out_mm: +- mmput(mm); +-out_free: + free_page((unsigned long) page); +-out_task: +- put_task_struct(task); +-out_no_task: + return copied; + } +=20 +@@ -959,11 +883,20 @@ loff_t mem_lseek(struct file *file, loff + return file->f_pos; + } +=20 ++static int mem_release(struct inode *inode, struct file *file) ++{ ++ struct mm_struct *mm =3D file->private_data; ++ ++ mmput(mm); ++ return 0; ++} ++ + static const struct file_operations proc_mem_operations =3D { + .llseek =3D mem_lseek, + .read =3D mem_read, + .write =3D mem_write, + .open =3D mem_open, ++ .release =3D mem_release, + }; +=20 + static ssize_t environ_read(struct file *file, char __user *buf,