Linux v4.12.10
This commit is contained in:
parent
b842984e58
commit
2ef60f262b
|
@ -0,0 +1,231 @@
|
|||
From patchwork Fri Jun 23 09:36:37 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Subject: [V4] acpi: acpica: fix acpi parse and parseext cache leaks
|
||||
From: Seunghun Han <kkamagui@gmail.com>
|
||||
X-Patchwork-Id: 9806085
|
||||
Message-Id: <1498210597-112293-1-git-send-email-kkamagui@gmail.com>
|
||||
To: lv.zheng@intel.com
|
||||
Cc: robert.moore@intel.com, rafael.j.wysocki@intel.com,
|
||||
linux-acpi@vger.kernel.org, devel@acpica.org,
|
||||
linux-kernel@vger.kernel.org, Seunghun Han <kkamagui@gmail.com>
|
||||
Date: Fri, 23 Jun 2017 18:36:37 +0900
|
||||
|
||||
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: Seunghun Han <kkamagui@gmail.com>
|
||||
---
|
||||
Changes since v3: change control transfer according to reviewer's comments.
|
||||
Changes since v2: merge flush code with existing code and change comments.
|
||||
Changes since v1: move flush code to acpi_ps_complete_final_op() function.
|
||||
|
||||
drivers/acpi/acpica/psobject.c | 53 +++++++++++++-----------------------------
|
||||
1 file changed, 16 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
|
||||
index 5bcb618..4539391 100644
|
||||
--- a/drivers/acpi/acpica/psobject.c
|
||||
+++ b/drivers/acpi/acpica/psobject.c
|
||||
@@ -608,7 +608,8 @@ acpi_status
|
||||
acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
||||
union acpi_parse_object *op, acpi_status status)
|
||||
{
|
||||
- acpi_status status2;
|
||||
+ acpi_status return_status = AE_OK;
|
||||
+ u8 ascending = TRUE;
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
|
||||
|
||||
@@ -622,7 +623,8 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
||||
op));
|
||||
do {
|
||||
if (op) {
|
||||
- if (walk_state->ascending_callback != NULL) {
|
||||
+ if (ascending &&
|
||||
+ walk_state->ascending_callback != NULL) {
|
||||
walk_state->op = op;
|
||||
walk_state->op_info =
|
||||
acpi_ps_get_opcode_info(op->common.
|
||||
@@ -644,49 +646,26 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
||||
}
|
||||
|
||||
if (status == AE_CTRL_TERMINATE) {
|
||||
- status = AE_OK;
|
||||
-
|
||||
- /* Clean up */
|
||||
- do {
|
||||
- if (op) {
|
||||
- status2 =
|
||||
- acpi_ps_complete_this_op
|
||||
- (walk_state, op);
|
||||
- if (ACPI_FAILURE
|
||||
- (status2)) {
|
||||
- return_ACPI_STATUS
|
||||
- (status2);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- acpi_ps_pop_scope(&
|
||||
- (walk_state->
|
||||
- parser_state),
|
||||
- &op,
|
||||
- &walk_state->
|
||||
- arg_types,
|
||||
- &walk_state->
|
||||
- arg_count);
|
||||
-
|
||||
- } while (op);
|
||||
-
|
||||
- return_ACPI_STATUS(status);
|
||||
+ ascending = FALSE;
|
||||
+ return_status = AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
else if (ACPI_FAILURE(status)) {
|
||||
|
||||
/* First error is most important */
|
||||
|
||||
- (void)
|
||||
- acpi_ps_complete_this_op(walk_state,
|
||||
- op);
|
||||
- return_ACPI_STATUS(status);
|
||||
+ ascending = FALSE;
|
||||
+ return_status = status;
|
||||
}
|
||||
}
|
||||
|
||||
- status2 = acpi_ps_complete_this_op(walk_state, op);
|
||||
- if (ACPI_FAILURE(status2)) {
|
||||
- return_ACPI_STATUS(status2);
|
||||
+ status = acpi_ps_complete_this_op(walk_state, op);
|
||||
+ if (ACPI_FAILURE(status)) {
|
||||
+ ascending = FALSE;
|
||||
+ if (ACPI_SUCCESS(return_status) ||
|
||||
+ return_status == AE_CTRL_TERMINATE) {
|
||||
+ return_status = status;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,5 +675,5 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
||||
|
||||
} while (op);
|
||||
|
||||
- return_ACPI_STATUS(status);
|
||||
+ return_ACPI_STATUS(return_status);
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
From patchwork Thu Aug 24 05:11:35 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: acpi: acpica: fix acpi operand cache leak in dsutils.c
|
||||
From: Seunghun Han <kkamagui@gmail.com>
|
||||
X-Patchwork-Id: 9919053
|
||||
Message-Id: <1503551495-33286-1-git-send-email-kkamagui@gmail.com>
|
||||
To: lv.zheng@intel.com
|
||||
Cc: robert.moore@intel.com, rafael.j.wysocki@intel.com,
|
||||
linux-acpi@vger.kernel.org, devel@acpica.org,
|
||||
linux-kernel@vger.kernel.org, security@kernel.org,
|
||||
Seunghun Han <kkamagui@gmail.com>
|
||||
Date: Thu, 24 Aug 2017 14:11:35 +0900
|
||||
|
||||
I found an ACPI cache leak in ACPI early termination and boot continuing case.
|
||||
|
||||
When early termination is occurred due to malicious ACPI table, Linux kernel
|
||||
terminates ACPI function and continues to boot process. While kernel terminates
|
||||
ACPI function, kmem_cache_destroy() reports Acpi-Operand cache leak.
|
||||
|
||||
Boot log of ACPI operand cache leak is as follows:
|
||||
>[ 0.585957] ACPI: Added _OSI(Module Device)
|
||||
>[ 0.587218] ACPI: Added _OSI(Processor Device)
|
||||
>[ 0.588530] ACPI: Added _OSI(3.0 _SCP Extensions)
|
||||
>[ 0.589790] ACPI: Added _OSI(Processor Aggregator Device)
|
||||
>[ 0.591534] ACPI Error: Illegal I/O port address/length above 64K: C806E00000004002/0x2 (20170303/hwvalid-155)
|
||||
>[ 0.594351] ACPI Exception: AE_LIMIT, Unable to initialize fixed events (20170303/evevent-88)
|
||||
>[ 0.597858] ACPI: Unable to start the ACPI Interpreter
|
||||
>[ 0.599162] ACPI Error: Could not remove SCI handler (20170303/evmisc-281)
|
||||
>[ 0.601836] kmem_cache_destroy Acpi-Operand: Slab cache still has objects
|
||||
>[ 0.603556] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc5 #26
|
||||
>[ 0.605159] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
|
||||
>[ 0.609177] Call Trace:
|
||||
>[ 0.610063] ? dump_stack+0x5c/0x81
|
||||
>[ 0.611118] ? kmem_cache_destroy+0x1aa/0x1c0
|
||||
>[ 0.612632] ? acpi_sleep_proc_init+0x27/0x27
|
||||
>[ 0.613906] ? acpi_os_delete_cache+0xa/0x10
|
||||
>[ 0.617986] ? acpi_ut_delete_caches+0x3f/0x7b
|
||||
>[ 0.619293] ? acpi_terminate+0xa/0x14
|
||||
>[ 0.620394] ? acpi_init+0x2af/0x34f
|
||||
>[ 0.621616] ? __class_create+0x4c/0x80
|
||||
>[ 0.623412] ? video_setup+0x7f/0x7f
|
||||
>[ 0.624585] ? acpi_sleep_proc_init+0x27/0x27
|
||||
>[ 0.625861] ? do_one_initcall+0x4e/0x1a0
|
||||
>[ 0.627513] ? kernel_init_freeable+0x19e/0x21f
|
||||
>[ 0.628972] ? rest_init+0x80/0x80
|
||||
>[ 0.630043] ? kernel_init+0xa/0x100
|
||||
>[ 0.631084] ? ret_from_fork+0x25/0x30
|
||||
>[ 0.633343] vgaarb: loaded
|
||||
>[ 0.635036] EDAC MC: Ver: 3.0.0
|
||||
>[ 0.638601] PCI: Probing PCI hardware
|
||||
>[ 0.639833] PCI host bridge to bus 0000:00
|
||||
>[ 0.641031] pci_bus 0000:00: root bus resource [io 0x0000-0xffff]
|
||||
> ... Continue to boot and log is omitted ...
|
||||
|
||||
I analyzed this memory leak in detail and found acpi_ds_obj_stack_pop_and_
|
||||
delete() function miscalculated the top of the stack. acpi_ds_obj_stack_push()
|
||||
function uses walk_state->operand_index for start position of the top, but
|
||||
acpi_ds_obj_stack_pop_and_delete() function considers index 0 for it.
|
||||
Therefore, this causes acpi operand memory leak.
|
||||
|
||||
This cache leak causes 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.
|
||||
|
||||
I made a patch to fix ACPI operand cache leak.
|
||||
|
||||
Signed-off-by: Seunghun Han <kkamagui@gmail.com>
|
||||
---
|
||||
drivers/acpi/acpica/dsutils.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
|
||||
index 0dabd9b..2c8a060 100644
|
||||
--- a/drivers/acpi/acpica/dsutils.c
|
||||
+++ b/drivers/acpi/acpica/dsutils.c
|
||||
@@ -705,6 +705,8 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
|
||||
union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
|
||||
u32 arg_count = 0;
|
||||
u32 index = walk_state->num_operands;
|
||||
+ u32 prev_num_operands = walk_state->num_operands;
|
||||
+ u32 new_num_operands;
|
||||
u32 i;
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
|
||||
@@ -733,6 +735,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
|
||||
|
||||
/* Create the interpreter arguments, in reverse order */
|
||||
|
||||
+ new_num_operands = index;
|
||||
index--;
|
||||
for (i = 0; i < arg_count; i++) {
|
||||
arg = arguments[index];
|
||||
@@ -757,7 +760,11 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
|
||||
* pop everything off of the operand stack and delete those
|
||||
* objects
|
||||
*/
|
||||
- acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
|
||||
+ walk_state->num_operands = i;
|
||||
+ acpi_ds_obj_stack_pop_and_delete(new_num_operands, walk_state);
|
||||
+
|
||||
+ /* Restore operand count */
|
||||
+ walk_state->num_operands = prev_num_operands;
|
||||
|
||||
ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index));
|
||||
return_ACPI_STATUS(status);
|
|
@ -0,0 +1,96 @@
|
|||
From patchwork Wed Jul 19 07:07:23 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: acpi: acpica: fix acpi operand cache leak in nseval.c
|
||||
From: Seunghun Han <kkamagui@gmail.com>
|
||||
X-Patchwork-Id: 9850567
|
||||
Message-Id: <1500448043-137615-1-git-send-email-kkamagui@gmail.com>
|
||||
To: Lv Zheng <lv.zheng@intel.com>
|
||||
Cc: Robert Moore <robert.moore@intel.com>,
|
||||
"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
|
||||
linux-acpi@vger.kernel.org, devel@acpica.org,
|
||||
linux-kernel@vger.kernel.org, security@kernel.org,
|
||||
Seunghun Han <kkamagui@gmail.com>
|
||||
Date: Wed, 19 Jul 2017 16:07:23 +0900
|
||||
|
||||
I found an ACPI cache leak in ACPI early termination and boot continuing case.
|
||||
|
||||
When early termination occurs due to malicious ACPI table, Linux kernel
|
||||
terminates ACPI function and continues to boot process. While kernel terminates
|
||||
ACPI function, kmem_cache_destroy() reports Acpi-Operand cache leak.
|
||||
|
||||
Boot log of ACPI operand cache leak is as follows:
|
||||
>[ 0.464168] ACPI: Added _OSI(Module Device)
|
||||
>[ 0.467022] ACPI: Added _OSI(Processor Device)
|
||||
>[ 0.469376] ACPI: Added _OSI(3.0 _SCP Extensions)
|
||||
>[ 0.471647] ACPI: Added _OSI(Processor Aggregator Device)
|
||||
>[ 0.477997] ACPI Error: Null stack entry at ffff880215c0aad8 (20170303/exresop-174)
|
||||
>[ 0.482706] ACPI Exception: AE_AML_INTERNAL, While resolving operands for [OpcodeName unavailable] (20170303/dswexec-461)
|
||||
>[ 0.487503] ACPI Error: Method parse/execution failed [\DBG] (Node ffff88021710ab40), AE_AML_INTERNAL (20170303/psparse-543)
|
||||
>[ 0.492136] ACPI Error: Method parse/execution failed [\_SB._INI] (Node ffff88021710a618), AE_AML_INTERNAL (20170303/psparse-543)
|
||||
>[ 0.497683] ACPI: Interpreter enabled
|
||||
>[ 0.499385] ACPI: (supports S0)
|
||||
>[ 0.501151] ACPI: Using IOAPIC for interrupt routing
|
||||
>[ 0.503342] ACPI Error: Null stack entry at ffff880215c0aad8 (20170303/exresop-174)
|
||||
>[ 0.506522] ACPI Exception: AE_AML_INTERNAL, While resolving operands for [OpcodeName unavailable] (20170303/dswexec-461)
|
||||
>[ 0.510463] ACPI Error: Method parse/execution failed [\DBG] (Node ffff88021710ab40), AE_AML_INTERNAL (20170303/psparse-543)
|
||||
>[ 0.514477] ACPI Error: Method parse/execution failed [\_PIC] (Node ffff88021710ab18), AE_AML_INTERNAL (20170303/psparse-543)
|
||||
>[ 0.518867] ACPI Exception: AE_AML_INTERNAL, Evaluating _PIC (20170303/bus-991)
|
||||
>[ 0.522384] kmem_cache_destroy Acpi-Operand: Slab cache still has objects
|
||||
>[ 0.524597] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc5 #26
|
||||
>[ 0.526795] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
|
||||
>[ 0.529668] Call Trace:
|
||||
>[ 0.530811] ? dump_stack+0x5c/0x81
|
||||
>[ 0.532240] ? kmem_cache_destroy+0x1aa/0x1c0
|
||||
>[ 0.533905] ? acpi_os_delete_cache+0xa/0x10
|
||||
>[ 0.535497] ? acpi_ut_delete_caches+0x3f/0x7b
|
||||
>[ 0.537237] ? acpi_terminate+0xa/0x14
|
||||
>[ 0.538701] ? acpi_init+0x2af/0x34f
|
||||
>[ 0.540008] ? acpi_sleep_proc_init+0x27/0x27
|
||||
>[ 0.541593] ? do_one_initcall+0x4e/0x1a0
|
||||
>[ 0.543008] ? kernel_init_freeable+0x19e/0x21f
|
||||
>[ 0.546202] ? rest_init+0x80/0x80
|
||||
>[ 0.547513] ? kernel_init+0xa/0x100
|
||||
>[ 0.548817] ? ret_from_fork+0x25/0x30
|
||||
>[ 0.550587] vgaarb: loaded
|
||||
>[ 0.551716] EDAC MC: Ver: 3.0.0
|
||||
>[ 0.553744] PCI: Probing PCI hardware
|
||||
>[ 0.555038] PCI host bridge to bus 0000:00
|
||||
> ... Continue to boot and log is omitted ...
|
||||
|
||||
I analyzed this memory leak in detail and found acpi_ns_evaluate() function
|
||||
only removes info->return_object in AE_CTRL_RETURN_VALUE case. But, when errors
|
||||
occur, the status value is not AE_CTRL_RETURN_VALUE, and info->return_object is
|
||||
also not null. Therefore, this causes acpi operand memory leak.
|
||||
|
||||
This cache leak causes 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.
|
||||
|
||||
I made a patch to fix ACPI operand cache leak.
|
||||
|
||||
Signed-off-by: Seunghun Han <kkamagui@gmail.com>
|
||||
---
|
||||
drivers/acpi/acpica/nseval.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
|
||||
index d22167c..f13d3cf 100644
|
||||
--- a/drivers/acpi/acpica/nseval.c
|
||||
+++ b/drivers/acpi/acpica/nseval.c
|
||||
@@ -308,6 +308,14 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
|
||||
/* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
|
||||
|
||||
status = AE_OK;
|
||||
+ } else if (ACPI_FAILURE(status)) {
|
||||
+
|
||||
+ /* If return_object exists, delete it */
|
||||
+
|
||||
+ if (info->return_object) {
|
||||
+ acpi_ut_remove_reference(info->return_object);
|
||||
+ info->return_object = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
|
|
@ -1,83 +0,0 @@
|
|||
From eafad73ed3851707fa6e3124a255fc049ff9545d Mon Sep 17 00:00:00 2001
|
||||
From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
Date: Sat, 12 Aug 2017 09:09:21 -0700
|
||||
Subject: iio: hid-sensor-trigger: Fix the race with user space powering up
|
||||
sensors
|
||||
|
||||
It has been reported for a while that with iio-sensor-proxy service the
|
||||
rotation only works after one suspend/resume cycle. This required a wait
|
||||
in the systemd unit file to avoid race. I found a Yoga 900 where I could
|
||||
reproduce this.
|
||||
|
||||
The problem scenerio is:
|
||||
- During sensor driver init, enable run time PM and also set a
|
||||
auto-suspend for 3 seconds.
|
||||
This result in one runtime resume. But there is a check to avoid
|
||||
a powerup in this sequence, but rpm is active
|
||||
- User space iio-sensor-proxy tries to power up the sensor. Since rpm is
|
||||
active it will simply return. But sensors were not actually
|
||||
powered up in the prior sequence, so actaully the sensors will not work
|
||||
- After 3 seconds the auto suspend kicks
|
||||
|
||||
If we add a wait in systemd service file to fire iio-sensor-proxy after
|
||||
3 seconds, then now everything will work as the runtime resume will
|
||||
actually powerup the sensor as this is a user request.
|
||||
|
||||
To avoid this:
|
||||
- Remove the check to match user requested state, this will cause a
|
||||
brief powerup, but if the iio-sensor-proxy starts immediately it will
|
||||
still work as the sensors are ON.
|
||||
- Also move the autosuspend delay to place when user requested turn off
|
||||
of sensors, like after user finished raw read or buffer disable
|
||||
|
||||
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
Tested-by: Bastien Nocera <hadess@hadess.net>
|
||||
Cc: <Stable@vger.kernel.org>
|
||||
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
---
|
||||
drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
|
||||
index 16ade0a..0e4b379 100644
|
||||
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
|
||||
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
|
||||
@@ -111,8 +111,6 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
|
||||
s32 poll_value = 0;
|
||||
|
||||
if (state) {
|
||||
- if (!atomic_read(&st->user_requested_state))
|
||||
- return 0;
|
||||
if (sensor_hub_device_open(st->hsdev))
|
||||
return -EIO;
|
||||
|
||||
@@ -161,6 +159,9 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
|
||||
&report_val);
|
||||
}
|
||||
|
||||
+ pr_debug("HID_SENSOR %s set power_state %d report_state %d\n",
|
||||
+ st->pdev->name, state_val, report_val);
|
||||
+
|
||||
sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
|
||||
st->power_state.index,
|
||||
sizeof(state_val), &state_val);
|
||||
@@ -182,6 +183,7 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
|
||||
ret = pm_runtime_get_sync(&st->pdev->dev);
|
||||
else {
|
||||
pm_runtime_mark_last_busy(&st->pdev->dev);
|
||||
+ pm_runtime_use_autosuspend(&st->pdev->dev);
|
||||
ret = pm_runtime_put_autosuspend(&st->pdev->dev);
|
||||
}
|
||||
if (ret < 0) {
|
||||
@@ -285,8 +287,6 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
|
||||
/* Default to 3 seconds, but can be changed from sysfs */
|
||||
pm_runtime_set_autosuspend_delay(&attrb->pdev->dev,
|
||||
3000);
|
||||
- pm_runtime_use_autosuspend(&attrb->pdev->dev);
|
||||
-
|
||||
return ret;
|
||||
error_unreg_trigger:
|
||||
iio_trigger_unregister(trig);
|
||||
--
|
||||
cgit v1.1
|
||||
|
24
kernel.spec
24
kernel.spec
|
@ -54,7 +54,7 @@ Summary: The Linux kernel
|
|||
%if 0%{?released_kernel}
|
||||
|
||||
# Do we have a -stable update to apply?
|
||||
%define stable_update 9
|
||||
%define stable_update 10
|
||||
# Set rpm version accordingly
|
||||
%if 0%{?stable_update}
|
||||
%define stablerev %{stable_update}
|
||||
|
@ -669,9 +669,6 @@ Patch704: input-rmi4-remove-the-need-for-artifical-IRQ.patch
|
|||
# rhbz 1476467
|
||||
Patch706: Fix-for-module-sig-verification.patch
|
||||
|
||||
# request for bug fix
|
||||
Patch709: iio-race-fix.patch
|
||||
|
||||
# rhbz 1485086
|
||||
Patch710: pci-mark-amd-stoney-gpu-ats-as-broken.patch
|
||||
|
||||
|
@ -681,6 +678,18 @@ Patch711: rt2800-fix-TX_PIN_CFG-setting-for-non-MT7620-chips.patch
|
|||
# CVE-2017-7558 rhbz 1480266 1484810
|
||||
Patch712: net-sctp-Avoid-out-of-bounds-reads-from-address-storage.patch
|
||||
|
||||
# CVE-2017-13693 rhbz 1485346 1485356
|
||||
Patch713: acpi-acpica-fix-acpi-operand-cache-leak-in-dsutils.c.patch
|
||||
|
||||
# CVE-2017-13694 rhbz 1485348
|
||||
Patch714: V4-acpi-acpica-fix-acpi-parse-and-parseext-cache-leaks.patch
|
||||
|
||||
# CVE-2017-13695 rhbz 1485349
|
||||
Patch715: acpi-acpica-fix-acpi-operand-cache-leak-in-nseval.c.patch
|
||||
|
||||
# rhbz 1484587
|
||||
Patch716: md-raid-reset-bio-allocated-from-mempool.patch
|
||||
|
||||
# END OF PATCH DEFINITIONS
|
||||
|
||||
%endif
|
||||
|
@ -2255,6 +2264,13 @@ fi
|
|||
#
|
||||
#
|
||||
%changelog
|
||||
* Wed Aug 30 2017 Justin M. Forbes <jforbes@redhat.com> - 4.12.10-300
|
||||
- Linux v4.12.10
|
||||
- Fix for CVE-2017-13693 (rhbz 1485346 1485356)
|
||||
- Fix for CVE-2017-13694 (rhbz 1485348)
|
||||
- Fix for CVE-2017-13695 (rhbz 1485349)
|
||||
- Fix for raid 1/10 (rhbz 1484587)
|
||||
|
||||
* Fri Aug 25 2017 Justin M. Forbes <jforbes@fedoraproject.org> - 4.12.9-300
|
||||
- Linux v4.12.9
|
||||
- For for AMD Stoney GPU (rhbz 1485086)
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
From: Shaohua Li <shli@kernel.org>
|
||||
Date: 2017-08-25 2:41:16
|
||||
Subject: [PATCH] md/raid1/10: reset bio allocated from mempool
|
||||
|
||||
From: Shaohua Li <shli@fb.com>
|
||||
|
||||
Data allocated from mempool doesn't always get initialized, this happens when
|
||||
the data is reused instead of fresh allocation. In the raid1/10 case, we must
|
||||
reinitialize the bios.
|
||||
|
||||
Reported-by: Jonathan G. Underwood <jonathan.underwood@gmail.com>
|
||||
Fixes: f0250618361d(md: raid10: don't use bio's vec table to manage resync pages)
|
||||
Fixes: 98d30c5812c3(md: raid1: don't use bio's vec table to manage resync pages)
|
||||
Cc: stable@vger.kernel.org (4.12+)
|
||||
Cc: Ming Lei <ming.lei@redhat.com>
|
||||
Signed-off-by: Shaohua Li <shli@fb.com>
|
||||
---
|
||||
drivers/md/raid1.c | 19 ++++++++++++++++++-
|
||||
drivers/md/raid10.c | 35 ++++++++++++++++++++++++++++++++---
|
||||
2 files changed, 50 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
|
||||
index f50958ded9f0..79474f47eeef 100644
|
||||
--- a/drivers/md/raid1.c
|
||||
+++ b/drivers/md/raid1.c
|
||||
@@ -2564,6 +2564,23 @@ static int init_resync(struct r1conf *conf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static struct r1bio *raid1_alloc_init_r1buf(struct r1conf *conf)
|
||||
+{
|
||||
+ struct r1bio *r1bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO);
|
||||
+ struct resync_pages *rps;
|
||||
+ struct bio *bio;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = conf->poolinfo->raid_disks; i--; ) {
|
||||
+ bio = r1bio->bios[i];
|
||||
+ rps = bio->bi_private;
|
||||
+ bio_reset(bio);
|
||||
+ bio->bi_private = rps;
|
||||
+ }
|
||||
+ r1bio->master_bio = NULL;
|
||||
+ return r1bio;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* perform a "sync" on one "block"
|
||||
*
|
||||
@@ -2649,7 +2666,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
|
||||
bitmap_cond_end_sync(mddev->bitmap, sector_nr,
|
||||
mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
|
||||
- r1_bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO);
|
||||
+ r1_bio = raid1_alloc_init_r1buf(conf);
|
||||
|
||||
raise_barrier(conf, sector_nr);
|
||||
|
||||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
|
||||
index f55d4cc085f6..d51ac02e98ef 100644
|
||||
--- a/drivers/md/raid10.c
|
||||
+++ b/drivers/md/raid10.c
|
||||
@@ -2798,6 +2798,35 @@ static int init_resync(struct r10conf *conf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static struct r10bio *raid10_alloc_init_r10buf(struct r10conf *conf)
|
||||
+{
|
||||
+ struct r10bio *r10bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
|
||||
+ struct rsync_pages *rp;
|
||||
+ struct bio *bio;
|
||||
+ int nalloc;
|
||||
+ int i;
|
||||
+
|
||||
+ if (test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery) ||
|
||||
+ test_bit(MD_RECOVERY_RESHAPE, &conf->mddev->recovery))
|
||||
+ nalloc = conf->copies; /* resync */
|
||||
+ else
|
||||
+ nalloc = 2; /* recovery */
|
||||
+
|
||||
+ for (i = 0; i < nalloc; i++) {
|
||||
+ bio = r10bio->devs[i].bio;
|
||||
+ rp = bio->bi_private;
|
||||
+ bio_reset(bio);
|
||||
+ bio->bi_private = rp;
|
||||
+ bio = r10bio->devs[i].repl_bio;
|
||||
+ if (bio) {
|
||||
+ rp = bio->bi_private;
|
||||
+ bio_reset(bio);
|
||||
+ bio->bi_private = rp;
|
||||
+ }
|
||||
+ }
|
||||
+ return r10bio;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* perform a "sync" on one "block"
|
||||
*
|
||||
@@ -3027,7 +3056,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
atomic_inc(&mreplace->nr_pending);
|
||||
rcu_read_unlock();
|
||||
|
||||
- r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
|
||||
+ r10_bio = raid10_alloc_init_r10buf(conf);
|
||||
r10_bio->state = 0;
|
||||
raise_barrier(conf, rb2 != NULL);
|
||||
atomic_set(&r10_bio->remaining, 0);
|
||||
@@ -3236,7 +3265,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
}
|
||||
if (sync_blocks < max_sync)
|
||||
max_sync = sync_blocks;
|
||||
- r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
|
||||
+ r10_bio = raid10_alloc_init_r10buf(conf);
|
||||
r10_bio->state = 0;
|
||||
|
||||
r10_bio->mddev = mddev;
|
||||
@@ -4360,7 +4389,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
|
||||
|
||||
read_more:
|
||||
/* Now schedule reads for blocks from sector_nr to last */
|
||||
- r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
|
||||
+ r10_bio = raid10_alloc_init_r10buf(conf);
|
||||
r10_bio->state = 0;
|
||||
raise_barrier(conf, sectors_done != 0);
|
||||
atomic_set(&r10_bio->remaining, 0);
|
||||
--
|
||||
2.11.0
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
2
sources
2
sources
|
@ -1,3 +1,3 @@
|
|||
SHA512 (perf-man-4.12.tar.gz) = 4d3bbda1f520dba0007c351af46f45085fe4842074eb2e01aee736fd369df595f8f72ed6c1192715f1120bf3353279777f9dca1178fe93bffe5be2de700d409c
|
||||
SHA512 (linux-4.12.tar.xz) = 8e81b41b253e63233e92948941f44c6482acb52aa3a3fd172f03a38a86f2c35b2ad4fd407acd1bc3964673eba344fe104d3a03e3ff4bf9cd1f22bd44263bd728
|
||||
SHA512 (patch-4.12.9.xz) = 8f4f9e270e8d00008b505be53aa0132aefbde21ae797e9daede19d6c81b26f255773b8e91396b75bbc78153d641a2479afbc22a7dc0d95b9c24534327fb95e38
|
||||
SHA512 (patch-4.12.10.xz) = 9463d9335c551376c7cdf45f4aa8f599d7783dbd4de62f87853e1c676f0a7e1a99b25909eac994676786e850137c90897a11c61d59e25674982132b888cfb1f1
|
||||
|
|
Loading…
Reference in New Issue