]> git.pld-linux.org Git - packages/acpica.git/blame - cve-2017-13694.patch
- added verbose patch not to hide compiler command line, disable stripping on install
[packages/acpica.git] / cve-2017-13694.patch
CommitLineData
25d7dd99
JB
1From 4a0243ecb4c94e2d73510d096c5ea4d0711fc6c0 Mon Sep 17 00:00:00 2001
2From: Seunghun Han <kkamagui@gmail.com>
3Date: Fri, 23 Jun 2017 14:19:48 +0900
4Subject: [PATCH] acpi: acpica: fix acpi parse and parseext cache leaks
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9I'm Seunghun Han, and I work for National Security Research Institute of
10South Korea.
11
12I have been doing a research on ACPI and found an ACPI cache leak in ACPI
13early abort cases.
14
15Boot log of ACPI cache leak is as follows:
16[ 0.352414] ACPI: Added _OSI(Module Device)
17[ 0.353182] ACPI: Added _OSI(Processor Device)
18[ 0.353182] ACPI: Added _OSI(3.0 _SCP Extensions)
19[ 0.353182] ACPI: Added _OSI(Processor Aggregator Device)
20[ 0.356028] ACPI: Unable to start the ACPI Interpreter
21[ 0.356799] ACPI Error: Could not remove SCI handler (20170303/evmisc-281)
22[ 0.360215] kmem_cache_destroy Acpi-State: Slab cache still has objects
23[ 0.360648] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W
244.12.0-rc4-next-20170608+ #10
25[ 0.361273] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS
26VirtualBox 12/01/2006
27[ 0.361873] Call Trace:
28[ 0.362243] ? dump_stack+0x5c/0x81
29[ 0.362591] ? kmem_cache_destroy+0x1aa/0x1c0
30[ 0.362944] ? acpi_sleep_proc_init+0x27/0x27
31[ 0.363296] ? acpi_os_delete_cache+0xa/0x10
32[ 0.363646] ? acpi_ut_delete_caches+0x6d/0x7b
33[ 0.364000] ? acpi_terminate+0xa/0x14
34[ 0.364000] ? acpi_init+0x2af/0x34f
35[ 0.364000] ? __class_create+0x4c/0x80
36[ 0.364000] ? video_setup+0x7f/0x7f
37[ 0.364000] ? acpi_sleep_proc_init+0x27/0x27
38[ 0.364000] ? do_one_initcall+0x4e/0x1a0
39[ 0.364000] ? kernel_init_freeable+0x189/0x20a
40[ 0.364000] ? rest_init+0xc0/0xc0
41[ 0.364000] ? kernel_init+0xa/0x100
42[ 0.364000] ? ret_from_fork+0x25/0x30
43
44I analyzed this memory leak in detail. I found that “Acpi-State” cache and
45“Acpi-Parse” cache were merged because the size of cache objects was same
46slab cache size.
47
48I finally found “Acpi-Parse” cache and “Acpi-ParseExt” cache were leaked
49using SLAB_NEVER_MERGE flag in kmem_cache_create() function.
50
51Real ACPI cache leak point is as follows:
52[ 0.360101] ACPI: Added _OSI(Module Device)
53[ 0.360101] ACPI: Added _OSI(Processor Device)
54[ 0.360101] ACPI: Added _OSI(3.0 _SCP Extensions)
55[ 0.361043] ACPI: Added _OSI(Processor Aggregator Device)
56[ 0.364016] ACPI: Unable to start the ACPI Interpreter
57[ 0.365061] ACPI Error: Could not remove SCI handler (20170303/evmisc-281)
58[ 0.368174] kmem_cache_destroy Acpi-Parse: Slab cache still has objects
59[ 0.369332] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G W
604.12.0-rc4-next-20170608+ #8
61[ 0.371256] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS
62VirtualBox 12/01/2006
63[ 0.372000] Call Trace:
64[ 0.372000] ? dump_stack+0x5c/0x81
65[ 0.372000] ? kmem_cache_destroy+0x1aa/0x1c0
66[ 0.372000] ? acpi_sleep_proc_init+0x27/0x27
67[ 0.372000] ? acpi_os_delete_cache+0xa/0x10
68[ 0.372000] ? acpi_ut_delete_caches+0x56/0x7b
69[ 0.372000] ? acpi_terminate+0xa/0x14
70[ 0.372000] ? acpi_init+0x2af/0x34f
71[ 0.372000] ? __class_create+0x4c/0x80
72[ 0.372000] ? video_setup+0x7f/0x7f
73[ 0.372000] ? acpi_sleep_proc_init+0x27/0x27
74[ 0.372000] ? do_one_initcall+0x4e/0x1a0
75[ 0.372000] ? kernel_init_freeable+0x189/0x20a
76[ 0.372000] ? rest_init+0xc0/0xc0
77[ 0.372000] ? kernel_init+0xa/0x100
78[ 0.372000] ? ret_from_fork+0x25/0x30
79[ 0.388039] kmem_cache_destroy Acpi-ParseExt: Slab cache still has objects
80[ 0.389063] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G W
814.12.0-rc4-next-20170608+ #8
82[ 0.390557] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS
83VirtualBox 12/01/2006
84[ 0.392000] Call Trace:
85[ 0.392000] ? dump_stack+0x5c/0x81
86[ 0.392000] ? kmem_cache_destroy+0x1aa/0x1c0
87[ 0.392000] ? acpi_sleep_proc_init+0x27/0x27
88[ 0.392000] ? acpi_os_delete_cache+0xa/0x10
89[ 0.392000] ? acpi_ut_delete_caches+0x6d/0x7b
90[ 0.392000] ? acpi_terminate+0xa/0x14
91[ 0.392000] ? acpi_init+0x2af/0x34f
92[ 0.392000] ? __class_create+0x4c/0x80
93[ 0.392000] ? video_setup+0x7f/0x7f
94[ 0.392000] ? acpi_sleep_proc_init+0x27/0x27
95[ 0.392000] ? do_one_initcall+0x4e/0x1a0
96[ 0.392000] ? kernel_init_freeable+0x189/0x20a
97[ 0.392000] ? rest_init+0xc0/0xc0
98[ 0.392000] ? kernel_init+0xa/0x100
99[ 0.392000] ? ret_from_fork+0x25/0x30
100
101When early abort is occurred due to invalid ACPI information, Linux kernel
102terminates ACPI by calling acpi_terminate() function. The function calls
103acpi_ut_delete_caches() function to delete local caches (acpi_gbl_namespace_
104cache, state_cache, operand_cache, ps_node_cache, ps_node_ext_cache).
105
106But the deletion codes in acpi_ut_delete_caches() function only delete
107slab caches using kmem_cache_destroy() function, therefore the cache
108objects should be flushed before acpi_ut_delete_caches() function.
109
110“Acpi-Parse” cache and “Acpi-ParseExt” cache are used in an AML parse
111function, acpi_ps_parse_loop(). The function should have flush codes to
112handle an error state due to invalid AML codes.
113
114This cache leak has a security threat because an old kernel (<= 4.9) shows
115memory locations of kernel functions in stack dump. Some malicious users
116could use this information to neutralize kernel ASLR.
117
118To fix ACPI cache leak for enhancing security, I made a patch which has
119flush codes in acpi_ps_parse_loop() function.
120
121I hope that this patch improves the security of Linux kernel.
122
123Thank you.
124
125Signed-off-by: Seunghun Han <kkamagui@gmail.com>
126
127Github-Location: https://github.com/acpica/acpica/pull/278/commits/4a0243ecb4c94e2d73510d096c5ea4d0711fc6c0
128
129---
130 source/components/parser/psobject.c | 44 ++++++++++++++-----------------------
131 1 file changed, 16 insertions(+), 28 deletions(-)
132
70586bb3 133Index: acpica-unix-20191213/source/components/parser/psobject.c
25d7dd99 134===================================================================
70586bb3
JB
135--- acpica-unix-20191213.orig/source/components/parser/psobject.c
136+++ acpica-unix-20191213/source/components/parser/psobject.c
137@@ -707,7 +707,8 @@ AcpiPsCompleteFinalOp (
25d7dd99
JB
138 ACPI_PARSE_OBJECT *Op,
139 ACPI_STATUS Status)
140 {
141- ACPI_STATUS Status2;
142+ ACPI_STATUS ReturnStatus = AE_OK;
143+ BOOLEAN Ascending = TRUE;
144
145
146 ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
70586bb3 147@@ -724,7 +725,7 @@ AcpiPsCompleteFinalOp (
25d7dd99
JB
148 {
149 if (Op)
150 {
151- if (WalkState->AscendingCallback != NULL)
152+ if (Ascending && WalkState->AscendingCallback != NULL)
153 {
154 WalkState->Op = Op;
155 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
70586bb3 156@@ -743,41 +744,28 @@ AcpiPsCompleteFinalOp (
25d7dd99
JB
157
158 if (Status == AE_CTRL_TERMINATE)
159 {
160- Status = AE_OK;
161-
162- /* Clean up */
163- do
164- {
165- if (Op)
166- {
167- Status2 = AcpiPsCompleteThisOp (WalkState, Op);
168- if (ACPI_FAILURE (Status2))
169- {
170- return_ACPI_STATUS (Status2);
171- }
172- }
173-
174- AcpiPsPopScope (&(WalkState->ParserState), &Op,
175- &WalkState->ArgTypes, &WalkState->ArgCount);
176-
177- } while (Op);
178-
179- return_ACPI_STATUS (Status);
180+ Ascending = FALSE;
181+ ReturnStatus = AE_CTRL_TERMINATE;
182 }
183
184 else if (ACPI_FAILURE (Status))
185 {
186 /* First error is most important */
187
188- (void) AcpiPsCompleteThisOp (WalkState, Op);
189- return_ACPI_STATUS (Status);
190+ Ascending = FALSE;
191+ ReturnStatus = Status;
192 }
193 }
194
195- Status2 = AcpiPsCompleteThisOp (WalkState, Op);
196- if (ACPI_FAILURE (Status2))
197+ Status = AcpiPsCompleteThisOp (WalkState, Op);
198+ if (ACPI_FAILURE (Status))
199 {
200- return_ACPI_STATUS (Status2);
201+ Ascending = FALSE;
202+ if (ACPI_SUCCESS (ReturnStatus) ||
203+ ReturnStatus == AE_CTRL_TERMINATE)
204+ {
205+ ReturnStatus = Status;
206+ }
207 }
208 }
209
70586bb3 210@@ -786,5 +774,5 @@ AcpiPsCompleteFinalOp (
25d7dd99
JB
211
212 } while (Op);
213
214- return_ACPI_STATUS (Status);
215+ return_ACPI_STATUS (ReturnStatus);
216 }
This page took 0.092217 seconds and 4 git commands to generate.