• S
    acpi: acpica: fix acpi parse and parseext cache leaks · 5ae25d8d
    Seunghun Han 提交于
    hulk inclusion
    category: bugfix
    bugzilla: 13690
    CVE: CVE-2017-13694
    
    -------------------------------------------------
    
    I'm Seunghun Han, and I work for National Security Research Institute of
    South Korea.
    
    I have been doing a research on ACPI and found an ACPI cache leak in ACPI
    early abort cases.
    
    Boot log of ACPI cache leak is as follows:
    [    0.352414] ACPI: Added _OSI(Module Device)
    [    0.353182] ACPI: Added _OSI(Processor Device)
    [    0.353182] ACPI: Added _OSI(3.0 _SCP Extensions)
    [    0.353182] ACPI: Added _OSI(Processor Aggregator Device)
    [    0.356028] ACPI: Unable to start the ACPI Interpreter
    [    0.356799] ACPI Error: Could not remove SCI handler (20170303/evmisc-281)
    [    0.360215] kmem_cache_destroy Acpi-State: Slab cache still has objects
    [    0.360648] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G        W
    4.12.0-rc4-next-20170608+ #10
    [    0.361273] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS
    VirtualBox 12/01/2006
    [    0.361873] Call Trace:
    [    0.362243]  ? dump_stack+0x5c/0x81
    [    0.362591]  ? kmem_cache_destroy+0x1aa/0x1c0
    [    0.362944]  ? acpi_sleep_proc_init+0x27/0x27
    [    0.363296]  ? acpi_os_delete_cache+0xa/0x10
    [    0.363646]  ? acpi_ut_delete_caches+0x6d/0x7b
    [    0.364000]  ? acpi_terminate+0xa/0x14
    [    0.364000]  ? acpi_init+0x2af/0x34f
    [    0.364000]  ? __class_create+0x4c/0x80
    [    0.364000]  ? video_setup+0x7f/0x7f
    [    0.364000]  ? acpi_sleep_proc_init+0x27/0x27
    [    0.364000]  ? do_one_initcall+0x4e/0x1a0
    [    0.364000]  ? kernel_init_freeable+0x189/0x20a
    [    0.364000]  ? rest_init+0xc0/0xc0
    [    0.364000]  ? kernel_init+0xa/0x100
    [    0.364000]  ? ret_from_fork+0x25/0x30
    
    I analyzed this memory leak in detail. I found that “Acpi-State” cache and
    “Acpi-Parse” cache were merged because the size of cache objects was same
    slab cache size.
    
    I finally found “Acpi-Parse” cache and “Acpi-ParseExt” cache were leaked
    using SLAB_NEVER_MERGE flag in kmem_cache_create() function.
    
    Real ACPI cache leak point is as follows:
    [    0.360101] ACPI: Added _OSI(Module Device)
    [    0.360101] ACPI: Added _OSI(Processor Device)
    [    0.360101] ACPI: Added _OSI(3.0 _SCP Extensions)
    [    0.361043] ACPI: Added _OSI(Processor Aggregator Device)
    [    0.364016] ACPI: Unable to start the ACPI Interpreter
    [    0.365061] ACPI Error: Could not remove SCI handler (20170303/evmisc-281)
    [    0.368174] kmem_cache_destroy Acpi-Parse: Slab cache still has objects
    [    0.369332] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G        W
    4.12.0-rc4-next-20170608+ #8
    [    0.371256] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS
    VirtualBox 12/01/2006
    [    0.372000] Call Trace:
    [    0.372000]  ? dump_stack+0x5c/0x81
    [    0.372000]  ? kmem_cache_destroy+0x1aa/0x1c0
    [    0.372000]  ? acpi_sleep_proc_init+0x27/0x27
    [    0.372000]  ? acpi_os_delete_cache+0xa/0x10
    [    0.372000]  ? acpi_ut_delete_caches+0x56/0x7b
    [    0.372000]  ? acpi_terminate+0xa/0x14
    [    0.372000]  ? acpi_init+0x2af/0x34f
    [    0.372000]  ? __class_create+0x4c/0x80
    [    0.372000]  ? video_setup+0x7f/0x7f
    [    0.372000]  ? acpi_sleep_proc_init+0x27/0x27
    [    0.372000]  ? do_one_initcall+0x4e/0x1a0
    [    0.372000]  ? kernel_init_freeable+0x189/0x20a
    [    0.372000]  ? rest_init+0xc0/0xc0
    [    0.372000]  ? kernel_init+0xa/0x100
    [    0.372000]  ? ret_from_fork+0x25/0x30
    [    0.388039] kmem_cache_destroy Acpi-ParseExt: Slab cache still has objects
    [    0.389063] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G        W
    4.12.0-rc4-next-20170608+ #8
    [    0.390557] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS
    VirtualBox 12/01/2006
    [    0.392000] Call Trace:
    [    0.392000]  ? dump_stack+0x5c/0x81
    [    0.392000]  ? kmem_cache_destroy+0x1aa/0x1c0
    [    0.392000]  ? acpi_sleep_proc_init+0x27/0x27
    [    0.392000]  ? acpi_os_delete_cache+0xa/0x10
    [    0.392000]  ? acpi_ut_delete_caches+0x6d/0x7b
    [    0.392000]  ? acpi_terminate+0xa/0x14
    [    0.392000]  ? acpi_init+0x2af/0x34f
    [    0.392000]  ? __class_create+0x4c/0x80
    [    0.392000]  ? video_setup+0x7f/0x7f
    [    0.392000]  ? acpi_sleep_proc_init+0x27/0x27
    [    0.392000]  ? do_one_initcall+0x4e/0x1a0
    [    0.392000]  ? kernel_init_freeable+0x189/0x20a
    [    0.392000]  ? rest_init+0xc0/0xc0
    [    0.392000]  ? kernel_init+0xa/0x100
    [    0.392000]  ? ret_from_fork+0x25/0x30
    
    When early abort is occurred due to invalid ACPI information, Linux kernel
    terminates ACPI by calling acpi_terminate() function. The function calls
    acpi_ut_delete_caches() function to delete local caches (acpi_gbl_namespace_
    cache, state_cache, operand_cache, ps_node_cache, ps_node_ext_cache).
    
    But the deletion codes in acpi_ut_delete_caches() function only delete
    slab caches using kmem_cache_destroy() function, therefore the cache
    objects should be flushed before acpi_ut_delete_caches() function.
    
    “Acpi-Parse” cache and “Acpi-ParseExt” cache are used in an AML parse
    function, acpi_ps_parse_loop(). The function should have flush codes to
    handle an error state due to invalid AML codes.
    
    This cache leak has a security threat because an old kernel (<= 4.9) shows
    memory locations of kernel functions in stack dump. Some malicious users
    could use this information to neutralize kernel ASLR.
    
    To fix ACPI cache leak for enhancing security, I made a patch which has
    flush codes in acpi_ps_parse_loop() function.
    
    I hope that this patch improves the security of Linux kernel.
    
    Thank you.
    Signed-off-by: NSeunghun Han <kkamagui@gmail.com>
    Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
    Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
    Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
    5ae25d8d
psobject.c 19.2 KB