1 From 37f2c716f2c6ab14c3ba557a539c3ee3224931b5 Mon Sep 17 00:00:00 2001
2 From: Seunghun Han <kkamagui@gmail.com>
3 Date: Wed, 19 Jul 2017 17:04:44 +0900
4 Subject: [PATCH] acpi: acpica: fix acpi operand cache leak in nseval.c
6 I found an ACPI cache leak in ACPI early termination and boot continuing case.
8 When early termination occurs due to malicious ACPI table, Linux kernel
9 terminates ACPI function and continues to boot process. While kernel terminates
10 ACPI function, kmem_cache_destroy() reports Acpi-Operand cache leak.
12 Boot log of ACPI operand cache leak is as follows:
13 >[ 0.464168] ACPI: Added _OSI(Module Device)
14 >[ 0.467022] ACPI: Added _OSI(Processor Device)
15 >[ 0.469376] ACPI: Added _OSI(3.0 _SCP Extensions)
16 >[ 0.471647] ACPI: Added _OSI(Processor Aggregator Device)
17 >[ 0.477997] ACPI Error: Null stack entry at ffff880215c0aad8 (20170303/exresop-174)
18 >[ 0.482706] ACPI Exception: AE_AML_INTERNAL, While resolving operands for [OpcodeName unavailable] (20170303/dswexec-461)
19 >[ 0.487503] ACPI Error: Method parse/execution failed [\DBG] (Node ffff88021710ab40), AE_AML_INTERNAL (20170303/psparse-543)
20 >[ 0.492136] ACPI Error: Method parse/execution failed [\_SB._INI] (Node ffff88021710a618), AE_AML_INTERNAL (20170303/psparse-543)
21 >[ 0.497683] ACPI: Interpreter enabled
22 >[ 0.499385] ACPI: (supports S0)
23 >[ 0.501151] ACPI: Using IOAPIC for interrupt routing
24 >[ 0.503342] ACPI Error: Null stack entry at ffff880215c0aad8 (20170303/exresop-174)
25 >[ 0.506522] ACPI Exception: AE_AML_INTERNAL, While resolving operands for [OpcodeName unavailable] (20170303/dswexec-461)
26 >[ 0.510463] ACPI Error: Method parse/execution failed [\DBG] (Node ffff88021710ab40), AE_AML_INTERNAL (20170303/psparse-543)
27 >[ 0.514477] ACPI Error: Method parse/execution failed [\_PIC] (Node ffff88021710ab18), AE_AML_INTERNAL (20170303/psparse-543)
28 >[ 0.518867] ACPI Exception: AE_AML_INTERNAL, Evaluating _PIC (20170303/bus-991)
29 >[ 0.522384] kmem_cache_destroy Acpi-Operand: Slab cache still has objects
30 >[ 0.524597] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc5 #26
31 >[ 0.526795] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
32 >[ 0.529668] Call Trace:
33 >[ 0.530811] ? dump_stack+0x5c/0x81
34 >[ 0.532240] ? kmem_cache_destroy+0x1aa/0x1c0
35 >[ 0.533905] ? acpi_os_delete_cache+0xa/0x10
36 >[ 0.535497] ? acpi_ut_delete_caches+0x3f/0x7b
37 >[ 0.537237] ? acpi_terminate+0xa/0x14
38 >[ 0.538701] ? acpi_init+0x2af/0x34f
39 >[ 0.540008] ? acpi_sleep_proc_init+0x27/0x27
40 >[ 0.541593] ? do_one_initcall+0x4e/0x1a0
41 >[ 0.543008] ? kernel_init_freeable+0x19e/0x21f
42 >[ 0.546202] ? rest_init+0x80/0x80
43 >[ 0.547513] ? kernel_init+0xa/0x100
44 >[ 0.548817] ? ret_from_fork+0x25/0x30
45 >[ 0.550587] vgaarb: loaded
46 >[ 0.551716] EDAC MC: Ver: 3.0.0
47 >[ 0.553744] PCI: Probing PCI hardware
48 >[ 0.555038] PCI host bridge to bus 0000:00
49 > ... Continue to boot and log is omitted ...
51 I analyzed this memory leak in detail and found AcpiNsEvaluate() function
52 only removes Info->ReturnObject in AE_CTRL_RETURN_VALUE case. But, when errors
53 occur, the status value is not AE_CTRL_RETURN_VALUE, and Info->ReturnObject is
54 also not null. Therefore, this causes acpi operand memory leak.
56 This cache leak causes a security threat because an old kernel (<= 4.9) shows
57 memory locations of kernel functions in stack dump. Some malicious users
58 could use this information to neutralize kernel ASLR.
60 I made a patch to fix ACPI operand cache leak.
62 Signed-off-by: Seunghun Han <kkamagui@gmail.com>
64 Github-Location: https://github.com/acpica/acpica/pull/296/commits/37f2c716f2c6ab14c3ba557a539c3ee3224931b5
67 source/components/namespace/nseval.c | 10 ++++++++++
68 1 file changed, 10 insertions(+)
70 Index: acpica-unix-20191213/source/components/namespace/nseval.c
71 ===================================================================
72 --- acpica-unix-20191213.orig/source/components/namespace/nseval.c
73 +++ acpica-unix-20191213/source/components/namespace/nseval.c
74 @@ -329,6 +329,16 @@ AcpiNsEvaluate (
75 Info->ReturnObject = NULL;
78 + else if (ACPI_FAILURE(Status))
80 + /* If ReturnObject exists, delete it */
82 + if (Info->ReturnObject)
84 + AcpiUtRemoveReference (Info->ReturnObject);
85 + Info->ReturnObject = NULL;
89 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
90 "*** Completed evaluation of object %s ***\n",