Bug 712774 (CVE-2011-2203) - CVE-2011-2203 kernel: hfs_find_init() sb->ext_tree NULL pointer dereference
Summary: CVE-2011-2203 kernel: hfs_find_init() sb->ext_tree NULL pointer dereference
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2011-2203
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
low
low
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 712775 712776 782695
Blocks: 738951
TreeView+ depends on / blocked
 
Reported: 2011-06-13 05:25 UTC by Eugene Teo (Security Response)
Modified: 2019-09-29 12:45 UTC (History)
11 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2012-05-04 06:50:06 UTC


Attachments (Terms of Use)


Links
System ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2011:1479 normal SHIPPED_LIVE Important: kernel security, bug fix, and enhancement update 2011-11-29 19:25:05 UTC

Description Eugene Teo (Security Response) 2011-06-13 05:25:24 UTC
hfs_find_init() is wrongly assuming that sb->ext_tree has already been opened and is not NULL but this function can be called when sb->ext_tree is currently being opened (NULL deref).

Indeed when we have the following call path, the NULL deref. occurs:

In hfs_mdb_get() we have (at this stage ext_tree == NULL):

 HFS_SB(sb)->ext_tree = hfs_btree_open(sb, HFS_EXT_CNID, hfs_ext_keycmp);

hfs_btree_open() is calling read_mapping_page() which is indirectly a call to hfs_readpage(). Then hfs_readpage() can make the following calls:

 hfs_readpage() -> hfs_get_block() -> alloc_buffer_head() -> hfs_ext_read_extent()

Then hfs_ext_read_extent() calls hfs_find_init() with an ext_tree == NULL. Then we have a NULL dereference in hfs_find_init().

 ptr = kmalloc(tree->max_key_len (...));

Due to the huge call stack from hfs_btree_open() to hfs_find_init() there are many ways to fix this dereference but I can't find the proper way to fix it.

Moreover if we look at the code in hfs_find_init().

 20        ptr = kmalloc(tree->max_key_len * 2 + 4, GFP_KERNEL);
 21        if (!ptr)
 22                return -ENOMEM;
 23        fd->search_key = ptr;
 24        fd->key = ptr + tree->max_key_len + 2;

We can make "max_key_len * 2 + 4" wrap and have an fd->key pointing outside of the kmalloc()'ed space. Moreover we can make space in fd->search_key lower than max_key_len and bad things can occur.

Reference:
https://lkml.org/lkml/2011/6/8/154

Acknowledgements:

Red Hat would like to thank Clement Lecigne for reporting this issue.

Comment 1 Eugene Teo (Security Response) 2011-06-13 05:26:54 UTC
Unable to handle kernel NULL pointer dereference at 0000000000000040 RIP: 
 [<ffffffff8845d64c>] :hfs:hfs_find_init+0x18/0x61
PGD 1b58a067 PUD 1cf5c067 PMD 0 
Oops: 0000 [1] SMP 
last sysfs file: /block/dm-1/range
CPU 0 
Modules linked in: hfs ip_conntrack_netbios_ns ipt_REJECT xt_state ip_conntrack nfnetlink iptable_filter ip_tables ip6t_REJECT xt_tcpudp ip6table_filter ip6_tables x_tables ipv6 xfrm_nalgo crypto_api loop dm_multipath scsi_dh video backlight sbs power_meter hwmon i2c_ec dell_wmi wmi button battery asus_acpi acpi_memhotplug ac parport_pc lp parport floppy virtio_balloon pcspkr 8139too 8139cp mii virtio_pci virtio_ring virtio i2c_piix4 i2c_core serio_raw tpm_tis tpm tpm_bios dm_raid45 dm_message dm_region_hash dm_mem_cache dm_snapshot dm_zero dm_mirror dm_log dm_mod ata_piix libata sd_mod scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd
Pid: 1621, comm: mount Not tainted 2.6.18-238.9.1.el5 #1
RIP: 0010:[<ffffffff8845d64c>]  [<ffffffff8845d64c>] :hfs:hfs_find_init+0x18/0x61
RSP: 0018:ffff81001b211808  EFLAGS: 00010292
RAX: ffff81001c6fca80 RBX: ffff81001b211828 RCX: 0000000000000000
RDX: 0000000000000006 RSI: ffff81001b211828 RDI: 0000000000000000
RBP: 0000000000000000 R08: 0000000000000000 R09: ffff81001fc9d000
R10: ffff8100178d8f70 R11: 00000050000000d0 R12: ffff8100178d9c80
R13: 0000000000000006 R14: 0000000000000006 R15: ffff8100178d9d28
FS:  00002ad3cb7397b0(0000) GS:ffffffff80426000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000040 CR3: 000000001b6c1000 CR4: 00000000000006e0
Process mount (pid: 1621, threadinfo ffff81001b210000, task ffff81001f2b4820)
Stack:  ffff81001fc98800 ffff8100178d9d28 0000000000000000 ffffffff88460c3a
 0000000000000050 ffff81001fc9c440 0000000000000000 0000000000000000
 0000000000000050 0000000000000246 ffff8100178d8e50 ffff8100178d8e50
Call Trace:
 [<ffffffff88460c3a>] :hfs:hfs_ext_read_extent+0x52/0x155
 [<ffffffff88461287>] :hfs:hfs_get_block+0xb9/0x199
 [<ffffffff800e4a75>] block_read_full_page+0x10a/0x26e
 [<ffffffff884611ce>] :hfs:hfs_get_block+0x0/0x199
 [<ffffffff8846172a>] :hfs:hfs_readpage+0x0/0xf
 [<ffffffff800c8a5b>] read_cache_page+0x7a/0x110
 [<ffffffff88460fe5>] :hfs:hfs_ext_keycmp+0x0/0x44
 [<ffffffff8845fa69>] :hfs:hfs_btree_open+0x16c/0x2eb
 [<ffffffff88462f93>] :hfs:hfs_mdb_get+0x4c4/0x641
 [<ffffffff8001a870>] vsnprintf+0x3f8/0x627
 [<ffffffff8846362a>] :hfs:hfs_fill_super+0x0/0x52a
 [<ffffffff88463b35>] :hfs:hfs_fill_super+0x50b/0x52a
 [<ffffffff8846362a>] :hfs:hfs_fill_super+0x0/0x52a
 [<ffffffff801562e9>] snprintf+0x44/0x4c
 [<ffffffff8006456b>] __down_write_nested+0x12/0x92
 [<ffffffff8012f26f>] selinux_sb_alloc_security+0x3e/0x83
 [<ffffffff800ef599>] get_filesystem+0x12/0x3b
 [<ffffffff800e629f>] sget+0x365/0x377
 [<ffffffff800e5beb>] set_bdev_super+0x0/0xf
 [<ffffffff800e6bb9>] get_sb_bdev+0x10a/0x16c
 [<ffffffff8012fe73>] selinux_sb_copy_data+0x1a1/0x1c5
 [<ffffffff800e6556>] vfs_kern_mount+0x93/0x11a
 [<ffffffff800e661f>] do_kern_mount+0x36/0x4d
 [<ffffffff800f0ec8>] do_mount+0x6a9/0x719
 [<ffffffff8000c7d8>] _atomic_dec_and_lock+0x39/0x57
 [<ffffffff8002cbec>] mntput_no_expire+0x19/0x89
 [<ffffffff8000a81a>] __link_path_walk+0xf79/0xfb9
 [<ffffffff8002cbec>] mntput_no_expire+0x19/0x89
 [<ffffffff8000eb94>] link_path_walk+0xa6/0xb2
 [<ffffffff800ce6b2>] zone_statistics+0x3e/0x6d
 [<ffffffff8000f41e>] __alloc_pages+0x78/0x308
 [<ffffffff8004c742>] sys_mount+0x8a/0xcd
 [<ffffffff8005d116>] system_call+0x7e/0x83


Code: 8b 7f 40 be d0 00 00 00 8d 7c 3f 04 e8 17 08 c8 f7 48 89 c2 
RIP  [<ffffffff8845d64c>] :hfs:hfs_find_init+0x18/0x61
 RSP <ffff81001b211808>
CR2: 0000000000000040
 <0>Kernel panic - not syncing: Fatal exception

Comment 7 Eugene Teo (Security Response) 2011-07-19 08:13:18 UTC
Statement:

This issue did not affect the versions of Linux kernel as shipped in Red Hat Enterprise Linux 6 and Red Hat Enterprise MRG as they did not provide support for the Hierarchical File System (HFS). This has been addressed in Red Hat Enterprise Linux 5 via https://rhn.redhat.com/errata/RHSA-2011-1479.html. Red Hat Enterprise Linux 4 is now in Production 3 of the maintenance life-cycle, https://access.redhat.com/support/policy/updates/errata/, therefore the fix for this issue is not currently planned to be included in the future updates.

Comment 16 Eric Sandeen 2011-07-29 16:48:46 UTC
Ok that works.

Comment 23 Eugene Teo (Security Response) 2011-09-16 06:12:02 UTC
Proposed patch:
http://groups.google.com/group/linux.kernel/browse_thread/thread/031d20158467229f?pli=1

Comment 25 errata-xmlrpc 2011-11-29 14:35:29 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5

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

Comment 26 Eugene Teo (Security Response) 2012-01-18 07:22:37 UTC
Created kernel tracking bugs for this issue

Affects: fedora-all [bug 782695]


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