Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 46836 Details for
Bug 72452
Linux Kernel Local DoS and Memory Content Disclosure Vulnerabilities (CAN-2004-1074)
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
2.6.9 VMA Patch
linux-2.6.9-vma.patch (text/plain), 8.74 KB, created by
Tim Yamin (RETIRED)
on 2004-12-24 16:42:33 UTC
(
hide
)
Description:
2.6.9 VMA Patch
Filename:
MIME Type:
Creator:
Tim Yamin (RETIRED)
Created:
2004-12-24 16:42:33 UTC
Size:
8.74 KB
patch
obsolete
># This is a BitKeeper generated diff -Nru style patch. ># ># ChangeSet ># 2004/11/25 16:00:28-08:00 nanhai.zou@intel.com ># [PATCH] ia64/x86_64/s390 overlapping vma fix ># ># IA64 is also vulnerable to the huge-vma-in-executable bug in 64 bit elf ># support, it just insert a vma of zero page without checking overlap, so user ># can construct a elf with section begin from 0x0 to trigger this BUGON(). ># ># However, I think it's safe to check overlap before we actually insert a vma ># into vma list. And I also feel check vma overlap everywhere is unnecessary, ># because invert_vm_struct will check it again, so the check is duplicated. ># It's better to have invert_vm_struct return a value then let caller check if ># it successes. Here is a patch against 2.6.10.rc2-mm3 I have tested it on ># i386, x86_64 and ia64 machines. ># ># Signed-off-by: Tony Luck <tony.luck@intel.com> ># Signed-off-by: Zou Nan hai <Nanhai.zou@intel.com> ># Signed-off-by: Andrew Morton <akpm@osdl.org> ># Signed-off-by: Linus Torvalds <torvalds@osdl.org> ># ># arch/ia64/ia32/binfmt_elf32.c ># 2004/11/24 22:42:43-08:00 nanhai.zou@intel.com +21 -5 ># ia64/x86_64/s390 overlapping vma fix ># ># arch/ia64/mm/init.c ># 2004/11/24 22:42:43-08:00 nanhai.zou@intel.com +14 -2 ># ia64/x86_64/s390 overlapping vma fix ># ># arch/s390/kernel/compat_exec.c ># 2004/11/24 22:42:43-08:00 nanhai.zou@intel.com +6 -2 ># ia64/x86_64/s390 overlapping vma fix ># ># arch/x86_64/ia32/ia32_binfmt.c ># 2004/11/24 22:42:43-08:00 nanhai.zou@intel.com +6 -2 ># ia64/x86_64/s390 overlapping vma fix ># ># fs/exec.c ># 2004/11/24 22:42:43-08:00 nanhai.zou@intel.com +3 -6 ># ia64/x86_64/s390 overlapping vma fix ># ># include/linux/mm.h ># 2004/11/24 22:42:43-08:00 nanhai.zou@intel.com +1 -1 ># ia64/x86_64/s390 overlapping vma fix ># ># mm/mmap.c ># 2004/11/24 22:42:43-08:00 nanhai.zou@intel.com +3 -2 ># ia64/x86_64/s390 overlapping vma fix ># >diff -Nru a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c >--- a/arch/ia64/ia32/binfmt_elf32.c 2004-12-03 12:01:20 -08:00 >+++ b/arch/ia64/ia32/binfmt_elf32.c 2004-12-03 12:01:20 -08:00 >@@ -100,7 +100,11 @@ > vma->vm_ops = &ia32_shared_page_vm_ops; > down_write(¤t->mm->mmap_sem); > { >- insert_vm_struct(current->mm, vma); >+ if (insert_vm_struct(current->mm, vma)) { >+ kmem_cache_free(vm_area_cachep, vma); >+ up_write(¤t->mm->mmap_sem); >+ return; >+ } > } > up_write(¤t->mm->mmap_sem); > } >@@ -123,7 +127,11 @@ > vma->vm_ops = &ia32_gate_page_vm_ops; > down_write(¤t->mm->mmap_sem); > { >- insert_vm_struct(current->mm, vma); >+ if (insert_vm_struct(current->mm, vma)) { >+ kmem_cache_free(vm_area_cachep, vma); >+ up_write(¤t->mm->mmap_sem); >+ return; >+ } > } > up_write(¤t->mm->mmap_sem); > } >@@ -142,7 +150,11 @@ > vma->vm_flags = VM_READ|VM_WRITE|VM_MAYREAD|VM_MAYWRITE; > down_write(¤t->mm->mmap_sem); > { >- insert_vm_struct(current->mm, vma); >+ if (insert_vm_struct(current->mm, vma)) { >+ kmem_cache_free(vm_area_cachep, vma); >+ up_write(¤t->mm->mmap_sem); >+ return; >+ } > } > up_write(¤t->mm->mmap_sem); > } >@@ -190,7 +202,7 @@ > unsigned long stack_base; > struct vm_area_struct *mpnt; > struct mm_struct *mm = current->mm; >- int i; >+ int i, ret; > > stack_base = IA32_STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE; > mm->arg_start = bprm->p + stack_base; >@@ -225,7 +237,11 @@ > mpnt->vm_flags = VM_STACK_FLAGS; > mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC)? > PAGE_COPY_EXEC: PAGE_COPY; >- insert_vm_struct(current->mm, mpnt); >+ if ((ret = insert_vm_struct(current->mm, mpnt))) { >+ up_write(¤t->mm->mmap_sem); >+ kmem_cache_free(vm_area_cachep, mpnt); >+ return ret; >+ } > current->mm->stack_vm = current->mm->total_vm = vma_pages(mpnt); > } > >diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c >--- a/arch/ia64/mm/init.c 2004-12-03 12:01:20 -08:00 >+++ b/arch/ia64/mm/init.c 2004-12-03 12:01:20 -08:00 >@@ -131,7 +131,13 @@ > vma->vm_end = vma->vm_start + PAGE_SIZE; > vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7]; > vma->vm_flags = VM_DATA_DEFAULT_FLAGS | VM_GROWSUP; >- insert_vm_struct(current->mm, vma); >+ down_write(¤t->mm->mmap_sem); >+ if (insert_vm_struct(current->mm, vma)) { >+ up_write(¤t->mm->mmap_sem); >+ kmem_cache_free(vm_area_cachep, vma); >+ return; >+ } >+ up_write(¤t->mm->mmap_sem); > } > > /* map NaT-page at address zero to speed up speculative dereferencing of NULL: */ >@@ -143,7 +149,13 @@ > vma->vm_end = PAGE_SIZE; > vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT); > vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO | VM_RESERVED; >- insert_vm_struct(current->mm, vma); >+ down_write(¤t->mm->mmap_sem); >+ if (insert_vm_struct(current->mm, vma)) { >+ up_write(¤t->mm->mmap_sem); >+ kmem_cache_free(vm_area_cachep, vma); >+ return; >+ } >+ up_write(¤t->mm->mmap_sem); > } > } > } >diff -Nru a/arch/s390/kernel/compat_exec.c b/arch/s390/kernel/compat_exec.c >--- a/arch/s390/kernel/compat_exec.c 2004-12-03 12:01:20 -08:00 >+++ b/arch/s390/kernel/compat_exec.c 2004-12-03 12:01:20 -08:00 >@@ -39,7 +39,7 @@ > unsigned long stack_base; > struct vm_area_struct *mpnt; > struct mm_struct *mm = current->mm; >- int i; >+ int i, ret; > > stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE; > mm->arg_start = bprm->p + stack_base; >@@ -68,7 +68,11 @@ > /* executable stack setting would be applied here */ > mpnt->vm_page_prot = PAGE_COPY; > mpnt->vm_flags = VM_STACK_FLAGS; >- insert_vm_struct(mm, mpnt); >+ if ((ret = insert_vm_struct(mm, mpnt))) { >+ up_write(&mm->mmap_sem); >+ kmem_cache_free(vm_area_cachep, mpnt); >+ return ret; >+ } > mm->stack_vm = mm->total_vm = vma_pages(mpnt); > } > >diff -Nru a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c >--- a/arch/x86_64/ia32/ia32_binfmt.c 2004-12-03 12:01:20 -08:00 >+++ b/arch/x86_64/ia32/ia32_binfmt.c 2004-12-03 12:01:20 -08:00 >@@ -334,7 +334,7 @@ > unsigned long stack_base; > struct vm_area_struct *mpnt; > struct mm_struct *mm = current->mm; >- int i; >+ int i, ret; > > stack_base = IA32_STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE; > mm->arg_start = bprm->p + stack_base; >@@ -368,7 +368,11 @@ > mpnt->vm_flags = VM_STACK_FLAGS; > mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? > PAGE_COPY_EXEC : PAGE_COPY; >- insert_vm_struct(mm, mpnt); >+ if ((ret = insert_vm_struct(mm, mpnt))) { >+ up_write(&mm->mmap_sem); >+ kmem_cache_free(vm_area_cachep, mpnt); >+ return ret; >+ } > mm->stack_vm = mm->total_vm = vma_pages(mpnt); > } > >diff -Nru a/fs/exec.c b/fs/exec.c >--- a/fs/exec.c 2004-12-03 12:01:20 -08:00 >+++ b/fs/exec.c 2004-12-03 12:01:20 -08:00 >@@ -342,7 +342,7 @@ > unsigned long stack_base; > struct vm_area_struct *mpnt; > struct mm_struct *mm = current->mm; >- int i; >+ int i, ret; > long arg_size; > > #ifdef CONFIG_STACK_GROWSUP >@@ -413,7 +413,6 @@ > > down_write(&mm->mmap_sem); > { >- struct vm_area_struct *vma; > mpnt->vm_mm = mm; > #ifdef CONFIG_STACK_GROWSUP > mpnt->vm_start = stack_base; >@@ -434,13 +433,11 @@ > mpnt->vm_flags = VM_STACK_FLAGS; > mpnt->vm_flags |= mm->def_flags; > mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7]; >- vma = find_vma(mm, mpnt->vm_start); >- if (vma) { >+ if ((ret = insert_vm_struct(mm, mpnt))) { > up_write(&mm->mmap_sem); > kmem_cache_free(vm_area_cachep, mpnt); >- return -ENOMEM; >+ return ret; > } >- insert_vm_struct(mm, mpnt); > mm->stack_vm = mm->total_vm = vma_pages(mpnt); > } > >diff -Nru a/include/linux/mm.h b/include/linux/mm.h >--- a/include/linux/mm.h 2004-12-03 12:01:20 -08:00 >+++ b/include/linux/mm.h 2004-12-03 12:01:20 -08:00 >@@ -675,7 +675,7 @@ > extern struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *); > extern int split_vma(struct mm_struct *, > struct vm_area_struct *, unsigned long addr, int new_below); >-extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *); >+extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *); > extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *, > struct rb_node **, struct rb_node *); > extern struct vm_area_struct *copy_vma(struct vm_area_struct **, >diff -Nru a/mm/mmap.c b/mm/mmap.c >--- a/mm/mmap.c 2004-12-03 12:01:20 -08:00 >+++ b/mm/mmap.c 2004-12-03 12:01:20 -08:00 >@@ -1871,7 +1871,7 @@ > * and into the inode's i_mmap tree. If vm_file is non-NULL > * then i_mmap_lock is taken here. > */ >-void insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) >+int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) > { > struct vm_area_struct * __vma, * prev; > struct rb_node ** rb_link, * rb_parent; >@@ -1894,8 +1894,9 @@ > } > __vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent); > if (__vma && __vma->vm_start < vma->vm_end) >- BUG(); >+ return -ENOMEM; > vma_link(mm, vma, prev, rb_link, rb_parent); >+ return 0; > } > > /*
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 72452
:
45056
|
45071
|
45171
|
45193
|
46349
|
46830
|
46831
| 46836