Bug 556703 - (CVE-2010-0291) CVE-2010-0291 kernel: untangle the do_mremap()
CVE-2010-0291 kernel: untangle the do_mremap()
Status: CLOSED ERRATA
Product: Security Response
Classification: Other
Component: vulnerability (Show other bugs)
unspecified
All Linux
high Severity high
: ---
: ---
Assigned To: Red Hat Product Security
impact=important,source=lkml,public=2...
: Security
Depends On: 556705 556706 556707 556708 556709 556710
Blocks:
  Show dependency treegraph
 
Reported: 2010-01-19 01:22 EST by Eugene Teo (Security Response)
Modified: 2015-02-16 10:45 EST (History)
12 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2013-04-12 11:49:15 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Eugene Teo (Security Response) 2010-01-19 01:22:03 EST
Description of problem:
There's a pile of upstream commits that fixed issues that can lead to user-triggerable panics on supported boxes: http://groups.google.com/group/linux.kernel/msg/895f20870532241e.

       54f5de709984bae0d31d823ff03de755f9dcac54 
       ecc1a8993751de4e82eb18640d631dae1f626bd6 
       1a0ef85f84feb13f07b604fcf5b90ef7c2b5c82f 
       f106af4e90eadd76cfc0b5325f659619e08fb762 
       097eed103862f9c6a97f2e415e21d1134017b135 
       935874141df839c706cd6cdc438e85eb69d1525e 
       0ec62d290912bb4b989be7563851bc364ec73b56 
       c4caa778157dbbf04116f0ac2111e389b5cd7a29 
       2ea1d13f64efdf49319e86c87d9ba38c30902782 
       570dcf2c15463842e384eb597a87c1e39bead99b 
       564b3bffc619dcbdd160de597b0547a7017ea010 
       0067bd8a55862ac9dd212bd1c4f6f5bff1ca1301 
       f8b7256096a20436f6d0926747e3ac3d64c81d24 
       8c7b49b3ecd48923eb64ff57e07a1cdb74782970 
       9206de95b1ea68357996ec02be5db0638a0de2c1 
       2c6a10161d0b5fc047b5bd81b03693b9af99fab5 
       05d72faa6d13c9d857478a5d35c85db9adada685 
       bb52d6694002b9d632bb355f64daa045c6293a4e 
       e77414e0aad6a1b063ba5e5750c582c75327ea6a 
       aa65607373a4daf2010e8c3867b6317619f3c1a3 

http://groups.google.co.jp/group/fa.linux.kernel/browse_thread/thread/8bf22336b1082090
Comment 3 Eugene Teo (Security Response) 2010-01-19 22:43:28 EST
http://marc.info/?l=linux-arch&m=126004438008670&w=2

From Al Viro:
We have a bunch of interesting problems with mmap/mremap.

1) MREMAP_FIXED allows remap to any location, regardless of what the architecture has to say about it.  The only check is TASK_SIZE. That's not enough - e.g. there are architectures where some ranges are simply absent (itanic, sparc), there are some that have cache coherency requirements on alignments of shared mapping (a lot - anything with VIPT cache, itanic where it's not a coherency but a performance issue).  There are architectures where specific ranges are reserved for hugetlb and they either simply do not allow normal mappings in there or need to do something to make them possible (as
ppc64 does).  sparc tried to deal with that problem, but it hadn't been complete (alignment issues) and it had been actually wrong for non-MREMAP_FIXED calls of mremap().

2) without MREMAP_FIXED we happily allowed extension into a hole in address space - the only check for being able to extend without move had been for TASK_SIZE (and for non-overlap with other vmas). Victims: sparc, itanic due to extending into holes, powerpc due to extending into hugetlb range.

3) in case of relocation without MREMAP_FIXED we ended up doing get_unmapped_area() with wrong pgoff if the starting address had been in the middle of a mapping.  New vma gets the right pgoff, the checks are done for the wrong one.  Cache coherency issues on all VIPT architectures.

4) mmap() with MAP_HUGETLB leaks struct file if it bails out anywhere past the allocation of struct file (by do_mmap_pgoff())

5) brk() into a hugetlb range failed without trying to do anything; known thing, ppc folks had been unhappy about that.

Series below should deal with those, mostly by switching to consistent use of get_unmapped_area() and sanitizing mmap/mremap code in general.

There is one case where we still have a serious PITA and I'm not sure how to deal with that; it's expand_stack().  We can trigger that by creating a VM_GROWS{UP,DOWN} mapping and either hitting a pagefault on address {below,above} it or doing PTRACE_POKEDATA on such address. As it is, we only check that range we are expanding into is not a hugetlb-only one.  The thing is, we *can't* just do the normal checks as-is there. For cases when we do expand_stack() for our own mm that would work just fine and do the right thing.  Unfortunately, we have places that hit it from get_user_pages() for another process.  And checks (starting with "what's the maximal address we allow") are process-dependent on biarch architectures.  Worse yet, execve() does that when we have no other process - it creates new mm, puts an anonymous mapping as high as possible in it and copies argv/envp in there.  And that's done with
get_user_pages() on new mm.  If we have a 32bit task on e.g. amd64, we'll have that mapping at addresses far above the TASK_SIZE of caller. Later, when  ->load_binary() figures out what personality we'll get, it turns that mapping into a valid vma for stack, possibly relocating the entire thing to address suitable for resulting process.

Breaking execve() from 32bit processes on biarch architectures would be a bad thing, so we can't just add the normal set of checks to expand_stack() (acct_stack_growth(), actually).  The problem is quite real, though, since e.g. on itanic PTRACE_POKEDATA can be used to get a vma hanging down into a gap in address space quite easily.  Results are not pretty...

One way to deal with that would be to put enough information into mm_struct so that all these checks wouldn't have to look at the caller's personality. I'm not sure how much PITA would that be, though; I've been digging through the arch/* VM code for several weeks by now, but I certainly don't pretend to be able to spot e.g. performance implications of such change.
Comment 4 Eugene Teo (Security Response) 2010-01-19 22:44:06 EST
Here are the related links and patch descriptions:
1) untangling do_mremap(), part 1
54f5de709984bae0d31d823ff03de755f9dcac54
http://marc.info/?l=linux-arch&m=126015794920298&w=2
2) do_mremap() untangling, part 2
ecc1a8993751de4e82eb18640d631dae1f626bd6
http://marc.info/?l=linux-arch&m=126015795020304&w=2
3) do_mremap() untangling, part 3
1a0ef85f84feb13f07b604fcf5b90ef7c2b5c82f
http://marc.info/?l=linux-arch&m=126015799020341&w=2
4) fix checks for expand-in-place mremap
f106af4e90eadd76cfc0b5325f659619e08fb762
http://marc.info/?l=linux-kernel&m=126015827720681&w=2
5) fix the arch checks in MREMAP_FIXED case
097eed103862f9c6a97f2e415e21d1134017b135
http://marc.info/?l=linux-kernel&m=126015827720686&w=2
6) fix pgoff in "have to relocate" case of mremap()
935874141df839c706cd6cdc438e85eb69d1525e
http://marc.info/?l=linux-kernel&m=126015825720659&w=2
7) kill useless checks in sparc mremap variants
0ec62d290912bb4b989be7563851bc364ec73b56
http://marc.info/?l=linux-kernel&m=126015822220608&w=2
8) file ->get_unmapped_area() shouldn't duplicate work of get_unmapped_area()
c4caa778157dbbf04116f0ac2111e389b5cd7a29
http://marc.info/?l=linux-arch&m=126015804620397&w=2
9) arm: add arch_mmap_check(), get rid of sys_arm_mremap()
2ea1d13f64efdf49319e86c87d9ba38c30902782
http://marc.info/?l=linux-arch&m=126015819820566&w=2
10) Kill ancient crap in s390 compat mmap
570dcf2c15463842e384eb597a87c1e39bead99b
http://marc.info/?l=linux-kernel&m=126015810620436&w=2
11) arch_mmap_check() on mn10300
564b3bffc619dcbdd160de597b0547a7017ea010
http://marc.info/?l=linux-kernel&m=126015810620439&w=2
12) Cut hugetlb case early for 32bit on ia64
0067bd8a55862ac9dd212bd1c4f6f5bff1ca1301
http://marc.info/?l=linux-kernel&m=126015810620442&w=2
13) Unify sys_mmap*
f8b7256096a20436f6d0926747e3ac3d64c81d24
http://marc.info/?l=linux-kernel&m=126015815920506&w=2
14) fix a struct file leak in do_mmap_pgoff()
8c7b49b3ecd48923eb64ff57e07a1cdb74782970
http://marc.info/?l=linux-kernel&m=126015815920509&w=2
15) Take arch_mmap_check() into get_unmapped_area()
9206de95b1ea68357996ec02be5db0638a0de2c1
http://marc.info/?l=linux-kernel&m=126015815920512&w=2
16) switch do_brk() to get_unmapped_area()
2c6a10161d0b5fc047b5bd81b03693b9af99fab5
http://marc.info/?l=linux-arch&m=126015810820457&w=2
17) sparc_brk() is not needed anymore
05d72faa6d13c9d857478a5d35c85db9adada685
http://marc.info/?l=linux-arch&m=126015810920463&w=2
18) Get rid of open-coding in ia64_brk()
bb52d6694002b9d632bb355f64daa045c6293a4e
http://marc.info/?l=linux-arch&m=126015811020469&w=2
19) fix broken aliasing checks for MAP_FIXED on sparc32,mips,arm and sh
e77414e0aad6a1b063ba5e5750c582c75327ea6a
http://marc.info/?l=linux-arch&m=126015816020518&w=2
20) Add missing alignment check in arch/score sys_mmap()
aa65607373a4daf2010e8c3867b6317619f3c1a3

There are some architecture-specific patches that we can ignore when backporting them to our kernels.
Comment 7 errata-xmlrpc 2010-03-23 11:42:32 EDT
This issue has been addressed in following products:

  MRG for RHEL-5

Via RHSA-2010:0161 https://rhn.redhat.com/errata/RHSA-2010-0161.html
Comment 8 errata-xmlrpc 2010-07-01 14:27:43 EDT
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5

Via RHSA-2010:0504 https://rhn.redhat.com/errata/RHSA-2010-0504.html
Comment 9 Eugene Teo (Security Response) 2011-01-17 22:51:23 EST
Statement:

The risks associated with fixing this bug are greater than the important severity security risk. We therefore currently have no plans to fix this flaw in Red Hat Enterprise Linux 3 and 4. This issue was addressed in Red Hat Enterprise Linux 5 and Red Hat Enterprise MRG via https://rhn.redhat.com/errata/RHSA-2010-0504.html and https://rhn.redhat.com/errata/RHSA-2010-0161.html.

Note You need to log in before you can comment on or make changes to this bug.