public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] install_special_mapping skips security_file_mmap check.
@ 2010-12-09 14:29 Tavis Ormandy
  2010-12-09 18:38 ` Randy Dunlap
  0 siblings, 1 reply; 5+ messages in thread
From: Tavis Ormandy @ 2010-12-09 14:29 UTC (permalink / raw)
  To: Linus Torvalds, Greg KH; +Cc: linux-kernel, security, stable, kees, eugene

The install_special_mapping routine (used, for example, to setup the vdso)
skips the security check before insert_vm_struct, allowing a local attacker to
bypass the mmap_min_addr security restriction by limiting the available pages
for special mappings. bprm_mm_init() also skips the check, although I don't
think this can be used to bypass any restrictions, I don't see any reason not
to have the security check.

$ uname -m
x86_64
$ cat /proc/sys/vm/mmap_min_addr
65536
$ cat install_special_mapping.s
section .bss
    resb BSS_SIZE
section .text
    global _start
    _start:
        mov     eax, __NR_pause
        int     0x80
$ nasm -D__NR_pause=29 -DBSS_SIZE=0xfffed000 -f elf -o install_special_mapping.o install_special_mapping.s
$ ld -m elf_i386 -Ttext=0x10000 -Tbss=0x11000 -o install_special_mapping install_special_mapping.o
$ ./install_special_mapping &
[1] 14303
$ cat /proc/14303/maps 
0000f000-00010000 r-xp 00000000 00:00 0                                  [vdso]
00010000-00011000 r-xp 00001000 00:19 2453665                            /home/taviso/install_special_mapping
00011000-ffffe000 rwxp 00000000 00:00 0                                  [stack]

It's worth noting that Red Hat are shipping with mmap_min_addr set to 4096.

Signed-off-by: Tavis Ormandy <taviso@google.com>
Acked-by: Kees Cook <kees@ubuntu.com>
Acked-by: Robert Swiecki <swiecki@google.com>
---

 fs/exec.c |    7 +++++++
 mm/mmap.c |    5 +++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index d68c378..7e8c4b6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -275,7 +275,14 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
    vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
    vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
    INIT_LIST_HEAD(&vma->anon_vma_chain);
+
+   err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+
+   if (err)
+       goto err;
+
    err = insert_vm_struct(mm, vma);
+
    if (err)
        goto err;
 
diff --git a/mm/mmap.c b/mm/mmap.c
index b179abb..1de3f4b 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2479,6 +2479,11 @@ int install_special_mapping(struct mm_struct *mm,
    vma->vm_ops = &special_mapping_vmops;
    vma->vm_private_data = pages;
 
+   if (security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1)) {
+       kmem_cache_free(vm_area_cachep, vma);
+       return -EPERM;
+   }
+
    if (unlikely(insert_vm_struct(mm, vma))) {
        kmem_cache_free(vm_area_cachep, vma);
        return -ENOMEM;


-- 
-------------------------------------
taviso@cmpxchg8b.com | pgp encrypted mail preferred
-------------------------------------------------------

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] install_special_mapping skips security_file_mmap check.
  2010-12-09 14:29 [PATCH] install_special_mapping skips security_file_mmap check Tavis Ormandy
@ 2010-12-09 18:38 ` Randy Dunlap
  2010-12-09 19:16   ` Tavis Ormandy
  0 siblings, 1 reply; 5+ messages in thread
From: Randy Dunlap @ 2010-12-09 18:38 UTC (permalink / raw)
  To: Tavis Ormandy
  Cc: Linus Torvalds, Greg KH, linux-kernel, security, stable, kees,
	eugene

On Thu, 9 Dec 2010 15:29:42 +0100 Tavis Ormandy wrote:

> Signed-off-by: Tavis Ormandy <taviso@google.com>
> Acked-by: Kees Cook <kees@ubuntu.com>
> Acked-by: Robert Swiecki <swiecki@google.com>
> ---
> 
>  fs/exec.c |    7 +++++++
>  mm/mmap.c |    5 +++++
>  2 files changed, 12 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/exec.c b/fs/exec.c
> index d68c378..7e8c4b6 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -275,7 +275,14 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
>     vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
>     vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
>     INIT_LIST_HEAD(&vma->anon_vma_chain);
> +
> +   err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
> +
> +   if (err)
> +       goto err;
> +
>     err = insert_vm_struct(mm, vma);
> +
>     if (err)
>         goto err;
>  

Uh, something happened to the tabs at the beginning of each line...
I.e., the original file content has been mucked up.


> diff --git a/mm/mmap.c b/mm/mmap.c
> index b179abb..1de3f4b 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -2479,6 +2479,11 @@ int install_special_mapping(struct mm_struct *mm,
>     vma->vm_ops = &special_mapping_vmops;
>     vma->vm_private_data = pages;
>  
> +   if (security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1)) {
> +       kmem_cache_free(vm_area_cachep, vma);
> +       return -EPERM;
> +   }
> +
>     if (unlikely(insert_vm_struct(mm, vma))) {
>         kmem_cache_free(vm_area_cachep, vma);
>         return -ENOMEM;
> 
> 
> -- 
> -------------------------------------


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] install_special_mapping skips security_file_mmap check.
  2010-12-09 18:38 ` Randy Dunlap
@ 2010-12-09 19:16   ` Tavis Ormandy
  2010-12-09 20:28     ` [Security] " Andrew Morton
  0 siblings, 1 reply; 5+ messages in thread
From: Tavis Ormandy @ 2010-12-09 19:16 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Linus Torvalds, Greg KH, linux-kernel, security, stable, kees,
	eugene

On Thu, Dec 09, 2010 at 10:38:53AM -0800, Randy Dunlap wrote:
> 
> Uh, something happened to the tabs at the beginning of each line...
> I.e., the original file content has been mucked up.
> 

Gah. Apologies, second attempt...

The install_special_mapping routine (used, for example, to setup the vdso)
skips the security check before insert_vm_struct, allowing a local attacker to
bypass the mmap_min_addr security restriction by limiting the available pages
for special mappings. bprm_mm_init() also skips the check, although I don't
think this can be used to bypass any restrictions, I don't see any reason not
to have the security check.

$ uname -m
x86_64
$ cat /proc/sys/vm/mmap_min_addr
65536
$ cat install_special_mapping.s
section .bss
    resb BSS_SIZE
section .text
    global _start
    _start:
        mov     eax, __NR_pause
        int     0x80
$ nasm -D__NR_pause=29 -DBSS_SIZE=0xfffed000 -f elf -o install_special_mapping.o install_special_mapping.s
$ ld -m elf_i386 -Ttext=0x10000 -Tbss=0x11000 -o install_special_mapping install_special_mapping.o
$ ./install_special_mapping &
[1] 14303
$ cat /proc/14303/maps 
0000f000-00010000 r-xp 00000000 00:00 0                                  [vdso]
00010000-00011000 r-xp 00001000 00:19 2453665                            /home/taviso/install_special_mapping
00011000-ffffe000 rwxp 00000000 00:00 0                                  [stack]

It's worth noting that Red Hat are shipping with mmap_min_addr set to 4096.

Signed-off-by: Tavis Ormandy <taviso@google.com>
Acked-by: Kees Cook <kees.cook@canonical.com>
Acked-by: Robert Swiecki <swiecki@google.com>
Cc: stable@kernel.org
---
 fs/exec.c |    7 +++++++
 mm/mmap.c |    5 +++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index d68c378..7e8c4b6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -275,7 +275,14 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
 	vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
 	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 	INIT_LIST_HEAD(&vma->anon_vma_chain);
+
+	err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+
+	if (err)
+		goto err;
+
 	err = insert_vm_struct(mm, vma);
+
 	if (err)
 		goto err;
 
diff --git a/mm/mmap.c b/mm/mmap.c
index b179abb..1de3f4b 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2479,6 +2479,11 @@ int install_special_mapping(struct mm_struct *mm,
 	vma->vm_ops = &special_mapping_vmops;
 	vma->vm_private_data = pages;
 
+	if (security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1)) {
+		kmem_cache_free(vm_area_cachep, vma);
+		return -EPERM;
+	}
+
 	if (unlikely(insert_vm_struct(mm, vma))) {
 		kmem_cache_free(vm_area_cachep, vma);
 		return -ENOMEM;


-- 
-------------------------------------
taviso@cmpxchg8b.com | pgp encrypted mail preferred
-------------------------------------------------------

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Security] [PATCH] install_special_mapping skips security_file_mmap check.
  2010-12-09 19:16   ` Tavis Ormandy
@ 2010-12-09 20:28     ` Andrew Morton
  2010-12-09 21:43       ` James Morris
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Morton @ 2010-12-09 20:28 UTC (permalink / raw)
  To: Tavis Ormandy
  Cc: Randy Dunlap, security, kees, Greg KH, linux-kernel, eugene,
	Linus Torvalds, stable

On Thu, 9 Dec 2010 20:16:37 +0100
Tavis Ormandy <taviso@cmpxchg8b.com> wrote:

> On Thu, Dec 09, 2010 at 10:38:53AM -0800, Randy Dunlap wrote:
> > 
> > Uh, something happened to the tabs at the beginning of each line...
> > I.e., the original file content has been mucked up.
> > 
> 
> Gah. Apologies, second attempt...
> 
> The install_special_mapping routine (used, for example, to setup the vdso)
> skips the security check before insert_vm_struct, allowing a local attacker to
> bypass the mmap_min_addr security restriction by limiting the available pages
> for special mappings. bprm_mm_init() also skips the check, although I don't
> think this can be used to bypass any restrictions, I don't see any reason not
> to have the security check.
> 
> $ uname -m
> x86_64
> $ cat /proc/sys/vm/mmap_min_addr
> 65536
> $ cat install_special_mapping.s
> section .bss
>     resb BSS_SIZE
> section .text
>     global _start
>     _start:
>         mov     eax, __NR_pause
>         int     0x80
> $ nasm -D__NR_pause=29 -DBSS_SIZE=0xfffed000 -f elf -o install_special_mapping.o install_special_mapping.s
> $ ld -m elf_i386 -Ttext=0x10000 -Tbss=0x11000 -o install_special_mapping install_special_mapping.o
> $ ./install_special_mapping &
> [1] 14303
> $ cat /proc/14303/maps 
> 0000f000-00010000 r-xp 00000000 00:00 0                                  [vdso]
> 00010000-00011000 r-xp 00001000 00:19 2453665                            /home/taviso/install_special_mapping
> 00011000-ffffe000 rwxp 00000000 00:00 0                                  [stack]
> 
> It's worth noting that Red Hat are shipping with mmap_min_addr set to 4096.
> 
> ...
>
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -2479,6 +2479,11 @@ int install_special_mapping(struct mm_struct *mm,
>  	vma->vm_ops = &special_mapping_vmops;
>  	vma->vm_private_data = pages;
>  
> +	if (security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1)) {
> +		kmem_cache_free(vm_area_cachep, vma);
> +		return -EPERM;
> +	}

This should return the security_file_mmap() errno rather than assuming
EPERM.  Although it happens to be the case that EPERM is the only errno
which security_file_mmap() presently returns, afacit.

Ditto insert_vm_struct(), with s/EPERM/ENOMEM/

Please review and test?


--- a/mm/mmap.c~mm-install_special_mapping-skips-security_file_mmap-check-fix
+++ a/mm/mmap.c
@@ -2463,6 +2463,7 @@ int install_special_mapping(struct mm_st
 			    unsigned long vm_flags, struct page **pages)
 {
 	struct vm_area_struct *vma;
+	int ret;
 
 	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
 	if (unlikely(vma == NULL))
@@ -2479,21 +2480,21 @@ int install_special_mapping(struct mm_st
 	vma->vm_ops = &special_mapping_vmops;
 	vma->vm_private_data = pages;
 
-	if (security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1)) {
-		kmem_cache_free(vm_area_cachep, vma);
-		return -EPERM;
-	}
-
-	if (unlikely(insert_vm_struct(mm, vma))) {
-		kmem_cache_free(vm_area_cachep, vma);
-		return -ENOMEM;
-	}
+	ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+	if (ret < 0)
+		goto out;
+
+	ret = insert_vm_struct(mm, vma);
+	if (ret < 0)
+		goto out;
 
 	mm->total_vm += len >> PAGE_SHIFT;
 
 	perf_event_mmap(vma);
-
 	return 0;
+out:
+	kmem_cache_free(vm_area_cachep, vma);
+	return ret;
 }
 
 static DEFINE_MUTEX(mm_all_locks_mutex);
_


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Security] [PATCH] install_special_mapping skips security_file_mmap check.
  2010-12-09 20:28     ` [Security] " Andrew Morton
@ 2010-12-09 21:43       ` James Morris
  0 siblings, 0 replies; 5+ messages in thread
From: James Morris @ 2010-12-09 21:43 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Tavis Ormandy, Randy Dunlap, security, kees, Greg KH,
	linux-kernel, eugene, Linus Torvalds, stable

On Thu, 9 Dec 2010, Andrew Morton wrote:

> This should return the security_file_mmap() errno rather than assuming
> EPERM.  Although it happens to be the case that EPERM is the only errno
> which security_file_mmap() presently returns, afacit.
> 
> Ditto insert_vm_struct(), with s/EPERM/ENOMEM/
> 
> Please review and test?

Reviewed-by: James Morris <jmorris@namei.org>


> 
> 
> --- a/mm/mmap.c~mm-install_special_mapping-skips-security_file_mmap-check-fix
> +++ a/mm/mmap.c
> @@ -2463,6 +2463,7 @@ int install_special_mapping(struct mm_st
>  			    unsigned long vm_flags, struct page **pages)
>  {
>  	struct vm_area_struct *vma;
> +	int ret;
>  
>  	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
>  	if (unlikely(vma == NULL))
> @@ -2479,21 +2480,21 @@ int install_special_mapping(struct mm_st
>  	vma->vm_ops = &special_mapping_vmops;
>  	vma->vm_private_data = pages;
>  
> -	if (security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1)) {
> -		kmem_cache_free(vm_area_cachep, vma);
> -		return -EPERM;
> -	}
> -
> -	if (unlikely(insert_vm_struct(mm, vma))) {
> -		kmem_cache_free(vm_area_cachep, vma);
> -		return -ENOMEM;
> -	}
> +	ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = insert_vm_struct(mm, vma);
> +	if (ret < 0)
> +		goto out;
>  
>  	mm->total_vm += len >> PAGE_SHIFT;
>  
>  	perf_event_mmap(vma);
> -
>  	return 0;
> +out:
> +	kmem_cache_free(vm_area_cachep, vma);
> +	return ret;
>  }
>  
>  static DEFINE_MUTEX(mm_all_locks_mutex);
> _
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-12-09 21:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-09 14:29 [PATCH] install_special_mapping skips security_file_mmap check Tavis Ormandy
2010-12-09 18:38 ` Randy Dunlap
2010-12-09 19:16   ` Tavis Ormandy
2010-12-09 20:28     ` [Security] " Andrew Morton
2010-12-09 21:43       ` James Morris

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox