* [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