Bug 662189 (CVE-2010-4346) - CVE-2010-4346 kernel: install_special_mapping skips security_file_mmap check
Summary: CVE-2010-4346 kernel: install_special_mapping skips security_file_mmap check
Status: CLOSED ERRATA
Alias: CVE-2010-4346
Product: Security Response
Classification: Other
Component: vulnerability   
(Show other bugs)
Version: unspecified
Hardware: All
OS: Linux
low
low
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard: public=20101209,reported=20101209,sou...
Keywords: Security
Depends On: 662195 662196 662197 662198 662199
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-12-10 20:28 UTC by Petr Matousek
Modified: 2015-08-19 09:01 UTC (History)
23 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2015-07-29 13:31:09 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Patch proposed by Tavis Ormandi (1.22 KB, text/plain)
2010-12-10 20:40 UTC, Petr Matousek
no flags Details
RHEL5'ish patch proposed by Solar Designer (1.35 KB, text/plain)
2010-12-10 20:41 UTC, Petr Matousek
no flags Details


External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2011:0330 normal SHIPPED_LIVE Important: kernel-rt security and bug fix update 2011-03-10 20:04:13 UTC
Red Hat Product Errata RHSA-2011:0421 normal SHIPPED_LIVE Important: kernel security and bug fix update 2011-04-08 02:56:45 UTC
Red Hat Product Errata RHSA-2011:0429 normal SHIPPED_LIVE Important: kernel security and bug fix update 2011-04-12 18:19:57 UTC

Description Petr Matousek 2010-12-10 20:28:43 UTC
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.

Reference:
https://lkml.org/lkml/2010/12/9/222
http://seclists.org/oss-sec/2010/q4/307

Acknowledgements:
Red Hat would like to thank Tavis Ormandy for reporting this issue.

Comment 2 Petr Matousek 2010-12-10 20:31:27 UTC
Statement:

The Linux kernel as shipped with Red Hat Enterprise Linux 4 is not vulnerable because it checks for mmap_min_addr even in special cases.

The Linux kernel as shipped with Red Hat Enterprise Linux 5, 6, and Red Hat Enterprise MRG have mmap_min_addr sysctl tunable set to 4096, and therefore are not affected by this issue. However, as a preventive measure (for example, for administrators who have increased mmap_min_addr), we have addressed this in Red Hat Enterprise Linux 5, 6 and MRG via https://rhn.redhat.com/errata/RHSA-2011-0429.html, https://rhn.redhat.com/errata/RHSA-2011-0421.html, and https://rhn.redhat.com/errata/RHSA-2011-0330.html.

Comment 3 Petr Matousek 2010-12-10 20:40:10 UTC
Created attachment 468055 [details]
Patch proposed by Tavis Ormandi

Comment 4 Petr Matousek 2010-12-10 20:41:34 UTC
Created attachment 468057 [details]
RHEL5'ish patch proposed by Solar Designer

Comment 6 Alexander Peslyak 2010-12-10 21:46:55 UTC
(In reply to comment #2)
> The Linux kernel as shipped with Red Hat Enterprise Linux 5, 6, and Red Hat
> Enterprise MRG have mmap_min_addr sysctl tunable set to 4096, and therefore are
> not affected by this issue.

I think this is a misunderstanding.  Your setting of mmap_min_addr to 4096 is precisely what makes you vulnerable to the fullest extent: the attack demonstrated by Tavis allows to map a page at exactly one page below mmap_min_addr, and you only have exactly one page - so it should get mapped at 0 (NULL).  Isn't this what happens when you try Tavis' PoC program on a clean RHEL 5 or 6 system?  I must admit I have not tried.  There might be something that prevents this from happening, but no one has mentioned such a thing so far (or have I missed it?)

Comment 7 Petr Matousek 2010-12-10 22:17:49 UTC
(In reply to comment #6)
> (In reply to comment #2)
> > The Linux kernel as shipped with Red Hat Enterprise Linux 5, 6, and Red Hat
> > Enterprise MRG have mmap_min_addr sysctl tunable set to 4096, and therefore are
> > not affected by this issue.
> 
> I think this is a misunderstanding.  Your setting of mmap_min_addr to 4096 is
> precisely what makes you vulnerable to the fullest extent: the attack
> demonstrated by Tavis allows to map a page at exactly one page below
> mmap_min_addr, and you only have exactly one page - so it should get mapped at
> 0 (NULL).  Isn't this what happens when you try Tavis' PoC program on a clean
> RHEL 5 or 6 system?  I must admit I have not tried.  There might be something
> that prevents this from happening, but no one has mentioned such a thing so far
> (or have I missed it?)

Update:
The following seems to be true for RHEL6. On both systems vm.overcommit_memory=1 might be needed. On my testing RHEL5 system vdso keeps to be mapped to 0xffffe000 which looks like COMPAT_VDSO. Either way I was not able to use intstall_special_mapping() to map anything to address 0 on RHEL.

--

This is what I was thinking first as well and tried to make the vdso getting mapped to address 0. I tested it on a a 2.6.35 upstream kernel, but on RHEL it's the same (32bit program on x86-64, on 32bit it's similar):

cynique@gentoo64 ~ $ cat /proc/2588/maps
00001000-00002000 r-xp 00001000 03:03 230335   /home/cynique/nada
00002000-ffff2000 rwxp 00000000 00:00 0       [stack]
ffff2000-ffff3000 r-xp 00000000 00:00 0       [vdso]
cynique@gentoo64 ~ $ nasm -D__NR_pause=29 -DBSS_SIZE=0xffffc000 -f elf -o nada.o nada.s
cynique@gentoo64 ~ $ ld -m elf_i386 -Ttext=0x1000 -Tbss=0x2000 -o nada nada.o   cynique@gentoo64 ~ $ ./nada
Killed
cynique@gentoo64 ~ $

breakpoint 4, arch_get_unmapped_area_topdown (filp=0x0, addr0=0x0, len=0x1000, pgoff=0x0, flags=0x0) at arch/x86/kernel/sys_x86_64.c:192
192		} while (len < vma->vm_start);
gdb> p len
$23 = 0x1000
gdb> p vma->vm_start
$24 = 0x1000
gdb> 

The problem AFAIK is in the while condition: the len is 0x1000 because we are looking for one page and the next vma->vm_start is 0x1000 as that is a vma with /home/cynique/nada. The condition (len < vma->vm_start) effectively skips the free page.

After the "} while (len <= vma->vm_start);" patch

cynique@gentoo64 ~ $ nasm -D__NR_pause=29 -DBSS_SIZE=0xffffc000 -f elf -o nada.o nada.s
cynique@gentoo64 ~ $ ld -m elf_i386 -Ttext=0x1000 -Tbss=0x2000 -o nada nada.o
cynique@gentoo64 ~ $ ./nada &
[1] 2555
cynique@gentoo64 ~ $ cat /proc/2555/maps
00000000-00001000 r-xp 00000000 00:00 0          [vdso]
00001000-00002000 r-xp 00001000 03:03 230335     /home/cynique/nada
00002000-ffffe000 rwxp 00000000 00:00 0          [stack]
cynique@gentoo64 ~ $ cat /proc/sys/vm/mmap_min_addr
4096
cynique@gentoo64 ~ $

Comment 8 Frantisek Hrbata 2011-01-10 11:04:57 UTC
Upstream commit 462e635e5b73ba9a4c03913b77138cd57ce4b050
http://git.kernel.org/linus/462e635e5b73ba9a4c03913b77138cd57ce4b050

Comment 10 errata-xmlrpc 2011-03-10 20:04:50 UTC
This issue has been addressed in following products:

  MRG for RHEL-5

Via RHSA-2011:0330 https://rhn.redhat.com/errata/RHSA-2011-0330.html

Comment 11 errata-xmlrpc 2011-04-08 02:57:29 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 6

Via RHSA-2011:0421 https://rhn.redhat.com/errata/RHSA-2011-0421.html

Comment 12 errata-xmlrpc 2011-04-12 18:20:07 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5

Via RHSA-2011:0429 https://rhn.redhat.com/errata/RHSA-2011-0429.html


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