* [PATCH v2 1/2] proc: environ_read() make sure offset points to environment address range
2012-07-24 15:29 [PATCH v2 0/2] proc: /proc/<pid>/environ offset fixes Djalal Harouni
@ 2012-07-24 15:29 ` Djalal Harouni
2012-07-24 15:29 ` [PATCH v2 2/2] proc: do not allow negative offsets on /proc/<pid>/environ Djalal Harouni
2012-07-24 17:41 ` [PATCH v2 0/2] proc: /proc/<pid>/environ offset fixes Kees Cook
2 siblings, 0 replies; 5+ messages in thread
From: Djalal Harouni @ 2012-07-24 15:29 UTC (permalink / raw)
To: linux-kernel, kernel-hardening, Al Viro, Andrew Morton,
Vasiliy Kulikov, WANG Cong, Oleg Nesterov, Solar Designer,
Kees Cook, David Rientjes, Brad Spengler
Cc: Djalal Harouni, Oleg Nesterov, Brad Spengler
Currently the following offset and environment address range check in
environ_read() of /proc/<pid>/environ is buggy:
int this_len = mm->env_end - (mm->env_start + src);
if (this_len <= 0)
break;
Large or negative offsets on /proc/<pid>/environ converted to 'unsigned
long' may pass this check since '(mm->env_start + src)' can overflow and
'this_len' will be positive.
This can turn /proc/<pid>/environ to act like /proc/<pid>/mem since
(mm->env_start + src) will point and read from another VMA.
There are two fixes here plus some code cleaning:
1) Fix the overflow by checking if the offset that was converted to
unsigned long will always point to the [mm->env_start, mm->env_end] address
range.
2) Remove the truncation that was made to the result of the check, storing
the result in 'int this_len' will alter its value and we can not depend on
it.
For kernels that have commit b409e578d9a4ec95913e06d8f which adds the
appropriate ptrace check and saves the 'mm' at ->open() time, this is not
a security issue.
This patch is taken from the grsecurity patch since it was just made
available.
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Brad Spengler <spender@grsecurity.net>
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
---
fs/proc/base.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2772208..39ee093 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -827,15 +827,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);
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 2/2] proc: do not allow negative offsets on /proc/<pid>/environ
2012-07-24 15:29 [PATCH v2 0/2] proc: /proc/<pid>/environ offset fixes Djalal Harouni
2012-07-24 15:29 ` [PATCH v2 1/2] proc: environ_read() make sure offset points to environment address range Djalal Harouni
@ 2012-07-24 15:29 ` Djalal Harouni
2012-07-25 12:16 ` Oleg Nesterov
2012-07-24 17:41 ` [PATCH v2 0/2] proc: /proc/<pid>/environ offset fixes Kees Cook
2 siblings, 1 reply; 5+ messages in thread
From: Djalal Harouni @ 2012-07-24 15:29 UTC (permalink / raw)
To: linux-kernel, kernel-hardening, Al Viro, Andrew Morton,
Vasiliy Kulikov, WANG Cong, Oleg Nesterov, Solar Designer,
Kees Cook, David Rientjes, Brad Spengler
Cc: Djalal Harouni, Oleg Nesterov
__mem_open() which is called by both /proc/<pid>/environ and
/proc/<pid>/mem ->open() handlers will allow the use of negative offsets.
/proc/<pid>/mem has negative offsets but not /proc/<pid>/environ.
Clean this by moving the 'force FMODE_UNSIGNED_OFFSET flag' to mem_open()
to allow negative offsets only on /proc/<pid>/mem.
Cc: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
---
fs/proc/base.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 39ee093..1b6c84c 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -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,
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v2 2/2] proc: do not allow negative offsets on /proc/<pid>/environ
2012-07-24 15:29 ` [PATCH v2 2/2] proc: do not allow negative offsets on /proc/<pid>/environ Djalal Harouni
@ 2012-07-25 12:16 ` Oleg Nesterov
0 siblings, 0 replies; 5+ messages in thread
From: Oleg Nesterov @ 2012-07-25 12:16 UTC (permalink / raw)
To: Djalal Harouni
Cc: linux-kernel, kernel-hardening, Al Viro, Andrew Morton,
Vasiliy Kulikov, WANG Cong, Solar Designer, Kees Cook,
David Rientjes, Brad Spengler
On 07/24, Djalal Harouni wrote:
>
> 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;
> }
It could be even simpler, I meant
file->f_mode |= FMODE_UNSIGNED_OFFSET;
return __mem_open(inode, file, PTRACE_MODE_ATTACH);
Never mind, this is very minor and the patch is already in -mm.
Oleg.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 0/2] proc: /proc/<pid>/environ offset fixes
2012-07-24 15:29 [PATCH v2 0/2] proc: /proc/<pid>/environ offset fixes Djalal Harouni
2012-07-24 15:29 ` [PATCH v2 1/2] proc: environ_read() make sure offset points to environment address range Djalal Harouni
2012-07-24 15:29 ` [PATCH v2 2/2] proc: do not allow negative offsets on /proc/<pid>/environ Djalal Harouni
@ 2012-07-24 17:41 ` Kees Cook
2 siblings, 0 replies; 5+ messages in thread
From: Kees Cook @ 2012-07-24 17:41 UTC (permalink / raw)
To: Djalal Harouni
Cc: linux-kernel, kernel-hardening, Al Viro, Andrew Morton,
Vasiliy Kulikov, WANG Cong, Oleg Nesterov, Solar Designer,
David Rientjes, Brad Spengler
Hi,
On Tue, Jul 24, 2012 at 8:29 AM, Djalal Harouni <tixxdz@opendz.org> wrote:
> This is the V2 to correctly check offsets on /proc/<pid>/environ before
> reading. This was previously discussed here:
> http://lkml.org/lkml/2012/7/22/79
>
> Due to incorrect offset checks, currently one can read from aribtrary
> addresses on /proc/<pid>/environ, not only the environment address range
> as shown here (the same thread):
> http://lkml.org/lkml/2012/7/22/163
>
> The bug is in environ_read().
> [...]
> Djalal Harouni (2):
> proc: environ_read() make sure offset points to environment address range
> proc: do not allow negative offsets on /proc/<pid>/environ
>
> fs/proc/base.c | 22 +++++++++++++---------
> 1 files changed, 13 insertions(+), 9 deletions(-)
This looks good, thanks!
Acked-by: Kees Cook <keescook@chromium.org>
-Kees
--
Kees Cook
Chrome OS Security
^ permalink raw reply [flat|nested] 5+ messages in thread