From: Seunghun Han <kkamagui(a)gmail.com>
[ Upstream commit 156fd20a41e776bbf334bd5e45c4f78dfc90ce1c ]
ACPICA commit 987a3b5cf7175916e2a4b6ea5b8e70f830dfe732
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.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 gmb_h virtual_box/virtual_box, BIOS virtual_box 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.
Link: https://github.com/acpica/acpica/commit/987a3b5c
Signed-off-by: Seunghun Han <kkamagui(a)gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Link: https://patch.msgid.link/4999480.31r3eYUQgx@rjwysocki.net
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
**YES** This commit should be backported to stable kernel trees based on
the following analysis: ## Analysis of the Commit **1. Bug Fix Nature**:
This commit fixes a clear memory leak bug in the ACPICA subsystem. The
issue occurs when `acpi_ds_create_operands()` encounters an error during
operand creation and needs to clean up allocated operands. **2. Root
Cause**: The core issue is a mismatch between how operands are pushed
and popped from the stack: - `acpi_ds_obj_stack_push()` uses
`walk_state->operand_index` to track the current position -
`acpi_ds_obj_stack_pop_and_delete()` incorrectly assumes operands start
at index 0 - This causes incomplete cleanup when errors occur, leading
to memory leaks **3. Code Analysis**: The fix correctly addresses the
issue by: - Tracking the original operand count (`prev_num_operands`) -
Calculating the correct number of operands to clean up
(`new_num_operands`) - Setting `walk_state->num_operands = i` before
cleanup to ensure proper indexing - Restoring the original operand count
after cleanup **4. Security Implications**: The commit message
explicitly mentions this is a security issue - the memory leak can
expose kernel function addresses in older kernels (≤4.9), potentially
defeating ASLR. This elevates the importance beyond a simple memory
leak. **5. Pattern Consistency**: This follows the exact same pattern as
other ACPICA operand cache leak fixes that were successfully backported
(commits `97f3c0a4b057`, `2915f16bdce2`, etc.), all authored by the same
developer addressing similar issues. **6. Stability Characteristics**: -
**Small and contained**: Only 8 lines of actual logic changes - **Clear
error path**: Only affects cleanup during error conditions - **No
behavioral changes**: No impact on normal operation - **Low regression
risk**: Only modifies error handling paths **7. Backport Suitability
Criteria**: - ✅ Fixes important bug affecting users (memory leak) - ✅
Small, contained fix with minimal risk - ✅ No architectural changes - ✅
Addresses security concern (ASLR bypass potential) - ✅ Follows
established patterns for ACPICA fixes - ✅ Critical kernel subsystem
(ACPI) **8. Historical Precedent**: The similar commits in the reference
examples (Similar Commits #1, #2, #3) all have "Backport Status: YES"
and address nearly identical ACPICA operand cache leak issues with
similar fixes and commit message patterns. This commit meets all
criteria for stable tree backporting: it's an important bugfix, has
minimal regression risk, affects a critical subsystem, and follows
established patterns for similar fixes that were previously backported.
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 fb9ed5e1da89d..2bdae8a25e084 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -668,6 +668,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);
@@ -696,6 +698,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];
@@ -720,7 +723,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);
--
2.39.5
From: Seunghun Han <kkamagui(a)gmail.com>
[ Upstream commit 156fd20a41e776bbf334bd5e45c4f78dfc90ce1c ]
ACPICA commit 987a3b5cf7175916e2a4b6ea5b8e70f830dfe732
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.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 gmb_h virtual_box/virtual_box, BIOS virtual_box 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.
Link: https://github.com/acpica/acpica/commit/987a3b5c
Signed-off-by: Seunghun Han <kkamagui(a)gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Link: https://patch.msgid.link/4999480.31r3eYUQgx@rjwysocki.net
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
**YES** This commit should be backported to stable kernel trees based on
the following analysis: ## Analysis of the Commit **1. Bug Fix Nature**:
This commit fixes a clear memory leak bug in the ACPICA subsystem. The
issue occurs when `acpi_ds_create_operands()` encounters an error during
operand creation and needs to clean up allocated operands. **2. Root
Cause**: The core issue is a mismatch between how operands are pushed
and popped from the stack: - `acpi_ds_obj_stack_push()` uses
`walk_state->operand_index` to track the current position -
`acpi_ds_obj_stack_pop_and_delete()` incorrectly assumes operands start
at index 0 - This causes incomplete cleanup when errors occur, leading
to memory leaks **3. Code Analysis**: The fix correctly addresses the
issue by: - Tracking the original operand count (`prev_num_operands`) -
Calculating the correct number of operands to clean up
(`new_num_operands`) - Setting `walk_state->num_operands = i` before
cleanup to ensure proper indexing - Restoring the original operand count
after cleanup **4. Security Implications**: The commit message
explicitly mentions this is a security issue - the memory leak can
expose kernel function addresses in older kernels (≤4.9), potentially
defeating ASLR. This elevates the importance beyond a simple memory
leak. **5. Pattern Consistency**: This follows the exact same pattern as
other ACPICA operand cache leak fixes that were successfully backported
(commits `97f3c0a4b057`, `2915f16bdce2`, etc.), all authored by the same
developer addressing similar issues. **6. Stability Characteristics**: -
**Small and contained**: Only 8 lines of actual logic changes - **Clear
error path**: Only affects cleanup during error conditions - **No
behavioral changes**: No impact on normal operation - **Low regression
risk**: Only modifies error handling paths **7. Backport Suitability
Criteria**: - ✅ Fixes important bug affecting users (memory leak) - ✅
Small, contained fix with minimal risk - ✅ No architectural changes - ✅
Addresses security concern (ASLR bypass potential) - ✅ Follows
established patterns for ACPICA fixes - ✅ Critical kernel subsystem
(ACPI) **8. Historical Precedent**: The similar commits in the reference
examples (Similar Commits #1, #2, #3) all have "Backport Status: YES"
and address nearly identical ACPICA operand cache leak issues with
similar fixes and commit message patterns. This commit meets all
criteria for stable tree backporting: it's an important bugfix, has
minimal regression risk, affects a critical subsystem, and follows
established patterns for similar fixes that were previously backported.
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 fb9ed5e1da89d..2bdae8a25e084 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -668,6 +668,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);
@@ -696,6 +698,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];
@@ -720,7 +723,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);
--
2.39.5
From: Seunghun Han <kkamagui(a)gmail.com>
[ Upstream commit 156fd20a41e776bbf334bd5e45c4f78dfc90ce1c ]
ACPICA commit 987a3b5cf7175916e2a4b6ea5b8e70f830dfe732
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.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 gmb_h virtual_box/virtual_box, BIOS virtual_box 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.
Link: https://github.com/acpica/acpica/commit/987a3b5c
Signed-off-by: Seunghun Han <kkamagui(a)gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Link: https://patch.msgid.link/4999480.31r3eYUQgx@rjwysocki.net
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
**YES** This commit should be backported to stable kernel trees based on
the following analysis: ## Analysis of the Commit **1. Bug Fix Nature**:
This commit fixes a clear memory leak bug in the ACPICA subsystem. The
issue occurs when `acpi_ds_create_operands()` encounters an error during
operand creation and needs to clean up allocated operands. **2. Root
Cause**: The core issue is a mismatch between how operands are pushed
and popped from the stack: - `acpi_ds_obj_stack_push()` uses
`walk_state->operand_index` to track the current position -
`acpi_ds_obj_stack_pop_and_delete()` incorrectly assumes operands start
at index 0 - This causes incomplete cleanup when errors occur, leading
to memory leaks **3. Code Analysis**: The fix correctly addresses the
issue by: - Tracking the original operand count (`prev_num_operands`) -
Calculating the correct number of operands to clean up
(`new_num_operands`) - Setting `walk_state->num_operands = i` before
cleanup to ensure proper indexing - Restoring the original operand count
after cleanup **4. Security Implications**: The commit message
explicitly mentions this is a security issue - the memory leak can
expose kernel function addresses in older kernels (≤4.9), potentially
defeating ASLR. This elevates the importance beyond a simple memory
leak. **5. Pattern Consistency**: This follows the exact same pattern as
other ACPICA operand cache leak fixes that were successfully backported
(commits `97f3c0a4b057`, `2915f16bdce2`, etc.), all authored by the same
developer addressing similar issues. **6. Stability Characteristics**: -
**Small and contained**: Only 8 lines of actual logic changes - **Clear
error path**: Only affects cleanup during error conditions - **No
behavioral changes**: No impact on normal operation - **Low regression
risk**: Only modifies error handling paths **7. Backport Suitability
Criteria**: - ✅ Fixes important bug affecting users (memory leak) - ✅
Small, contained fix with minimal risk - ✅ No architectural changes - ✅
Addresses security concern (ASLR bypass potential) - ✅ Follows
established patterns for ACPICA fixes - ✅ Critical kernel subsystem
(ACPI) **8. Historical Precedent**: The similar commits in the reference
examples (Similar Commits #1, #2, #3) all have "Backport Status: YES"
and address nearly identical ACPICA operand cache leak issues with
similar fixes and commit message patterns. This commit meets all
criteria for stable tree backporting: it's an important bugfix, has
minimal regression risk, affects a critical subsystem, and follows
established patterns for similar fixes that were previously backported.
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 fb9ed5e1da89d..2bdae8a25e084 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -668,6 +668,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);
@@ -696,6 +698,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];
@@ -720,7 +723,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);
--
2.39.5
From: Seunghun Han <kkamagui(a)gmail.com>
[ Upstream commit 156fd20a41e776bbf334bd5e45c4f78dfc90ce1c ]
ACPICA commit 987a3b5cf7175916e2a4b6ea5b8e70f830dfe732
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.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 gmb_h virtual_box/virtual_box, BIOS virtual_box 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.
Link: https://github.com/acpica/acpica/commit/987a3b5c
Signed-off-by: Seunghun Han <kkamagui(a)gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Link: https://patch.msgid.link/4999480.31r3eYUQgx@rjwysocki.net
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
**YES** This commit should be backported to stable kernel trees based on
the following analysis: ## Analysis of the Commit **1. Bug Fix Nature**:
This commit fixes a clear memory leak bug in the ACPICA subsystem. The
issue occurs when `acpi_ds_create_operands()` encounters an error during
operand creation and needs to clean up allocated operands. **2. Root
Cause**: The core issue is a mismatch between how operands are pushed
and popped from the stack: - `acpi_ds_obj_stack_push()` uses
`walk_state->operand_index` to track the current position -
`acpi_ds_obj_stack_pop_and_delete()` incorrectly assumes operands start
at index 0 - This causes incomplete cleanup when errors occur, leading
to memory leaks **3. Code Analysis**: The fix correctly addresses the
issue by: - Tracking the original operand count (`prev_num_operands`) -
Calculating the correct number of operands to clean up
(`new_num_operands`) - Setting `walk_state->num_operands = i` before
cleanup to ensure proper indexing - Restoring the original operand count
after cleanup **4. Security Implications**: The commit message
explicitly mentions this is a security issue - the memory leak can
expose kernel function addresses in older kernels (≤4.9), potentially
defeating ASLR. This elevates the importance beyond a simple memory
leak. **5. Pattern Consistency**: This follows the exact same pattern as
other ACPICA operand cache leak fixes that were successfully backported
(commits `97f3c0a4b057`, `2915f16bdce2`, etc.), all authored by the same
developer addressing similar issues. **6. Stability Characteristics**: -
**Small and contained**: Only 8 lines of actual logic changes - **Clear
error path**: Only affects cleanup during error conditions - **No
behavioral changes**: No impact on normal operation - **Low regression
risk**: Only modifies error handling paths **7. Backport Suitability
Criteria**: - ✅ Fixes important bug affecting users (memory leak) - ✅
Small, contained fix with minimal risk - ✅ No architectural changes - ✅
Addresses security concern (ASLR bypass potential) - ✅ Follows
established patterns for ACPICA fixes - ✅ Critical kernel subsystem
(ACPI) **8. Historical Precedent**: The similar commits in the reference
examples (Similar Commits #1, #2, #3) all have "Backport Status: YES"
and address nearly identical ACPICA operand cache leak issues with
similar fixes and commit message patterns. This commit meets all
criteria for stable tree backporting: it's an important bugfix, has
minimal regression risk, affects a critical subsystem, and follows
established patterns for similar fixes that were previously backported.
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 fb9ed5e1da89d..2bdae8a25e084 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -668,6 +668,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);
@@ -696,6 +698,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];
@@ -720,7 +723,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);
--
2.39.5
Hi,
We’re thrilled to give you exclusive access to the CWIEME Berlin 2025 Visitor Contact List!
This database includes 8,678 verified visitor contacts and 550 exhibitor contacts, each with detailed
Each contact contains: Contact name, Job Title, Business Name, Physical Address, Phone Numbers, Official Email address and many more.
Limited-Time Offer: Get 20% OFF – Valid only until May 31st.
Interested? Simply reply with “Send me pricing” to receive more details.
Kind regards,
Garnet Conwell
Sr. Marketing Manager
P.S. Don’t want to receive these updates? Just reply with “Unfollow.”
Hi everyone,
Looking at
https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
there are a number of criteria for patches to -stable releases.
However, there is no mention of preserving the stability of internal
kernel ABIs and/or APIs.
Do successive patch releases of -stable kernels provide any guarantees
that they will not change ABIs and/or APIs, remove functionality, change
behaviour, etc.? For example, would a -stable commit be allowed to
make a change that would break an out-of-tree (but open-source) device
driver if that's the only way to fix a bug?
I know that during the development of new major/minor versions
developers are free to break ABIs and APIs at will as long as they fix
up all the in-tree code. Does that still hold true for -stable commits
or do things get more restrictive?
Thanks,
Chris
The patch titled
Subject: mm: fix the inaccurate memory statistics issue for users
has been added to the -mm mm-hotfixes-unstable branch. Its filename is
mm-fix-the-inaccurate-memory-statistics-issue-for-users.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patche…
This patch will later appear in the mm-hotfixes-unstable branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days
------------------------------------------------------
From: Baolin Wang <baolin.wang(a)linux.alibaba.com>
Subject: mm: fix the inaccurate memory statistics issue for users
Date: Sat, 24 May 2025 09:59:53 +0800
On some large machines with a high number of CPUs running a 64K pagesize
kernel, we found that the 'RES' field is always 0 displayed by the top
command for some processes, which will cause a lot of confusion for users.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
875525 root 20 0 12480 0 0 R 0.3 0.0 0:00.08 top
1 root 20 0 172800 0 0 S 0.0 0.0 0:04.52 systemd
The main reason is that the batch size of the percpu counter is quite
large on these machines, caching a significant percpu value, since
converting mm's rss stats into percpu_counter by commit f1a7941243c1 ("mm:
convert mm's rss stats into percpu_counter"). Intuitively, the batch
number should be optimized, but on some paths, performance may take
precedence over statistical accuracy. Therefore, introducing a new
interface to add the percpu statistical count and display it to users,
which can remove the confusion. In addition, this change is not expected
to be on a performance-critical path, so the modification should be
acceptable.
Link: https://lkml.kernel.org/r/4f0fd51eb4f48c1a34226456b7a8b4ebff11bf72.17480518…
Fixes: f1a7941243c1 ("mm: convert mm's rss stats into percpu_counter")
Signed-off-by: Baolin Wang <baolin.wang(a)linux.alibaba.com>
Tested-by Donet Tom <donettom(a)linux.ibm.com>
Reviewed-by: Aboorva Devarajan <aboorvad(a)linux.ibm.com>
Tested-by: Aboorva Devarajan <aboorvad(a)linux.ibm.com>
Acked-by: Shakeel Butt <shakeel.butt(a)linux.dev>
Acked-by: SeongJae Park <sj(a)kernel.org>
Cc: David Hildenbrand <david(a)redhat.com>
Cc: Liam Howlett <liam.howlett(a)oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes(a)oracle.com>
Cc: Michal Hocko <mhocko(a)suse.com>
Cc: Mike Rapoport <rppt(a)kernel.org>
Cc: Suren Baghdasaryan <surenb(a)google.com>
Cc: Vlastimil Babka <vbabka(a)suse.cz>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
fs/proc/task_mmu.c | 14 +++++++-------
include/linux/mm.h | 5 +++++
2 files changed, 12 insertions(+), 7 deletions(-)
--- a/fs/proc/task_mmu.c~mm-fix-the-inaccurate-memory-statistics-issue-for-users
+++ a/fs/proc/task_mmu.c
@@ -36,9 +36,9 @@ void task_mem(struct seq_file *m, struct
unsigned long text, lib, swap, anon, file, shmem;
unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
- anon = get_mm_counter(mm, MM_ANONPAGES);
- file = get_mm_counter(mm, MM_FILEPAGES);
- shmem = get_mm_counter(mm, MM_SHMEMPAGES);
+ anon = get_mm_counter_sum(mm, MM_ANONPAGES);
+ file = get_mm_counter_sum(mm, MM_FILEPAGES);
+ shmem = get_mm_counter_sum(mm, MM_SHMEMPAGES);
/*
* Note: to minimize their overhead, mm maintains hiwater_vm and
@@ -59,7 +59,7 @@ void task_mem(struct seq_file *m, struct
text = min(text, mm->exec_vm << PAGE_SHIFT);
lib = (mm->exec_vm << PAGE_SHIFT) - text;
- swap = get_mm_counter(mm, MM_SWAPENTS);
+ swap = get_mm_counter_sum(mm, MM_SWAPENTS);
SEQ_PUT_DEC("VmPeak:\t", hiwater_vm);
SEQ_PUT_DEC(" kB\nVmSize:\t", total_vm);
SEQ_PUT_DEC(" kB\nVmLck:\t", mm->locked_vm);
@@ -92,12 +92,12 @@ unsigned long task_statm(struct mm_struc
unsigned long *shared, unsigned long *text,
unsigned long *data, unsigned long *resident)
{
- *shared = get_mm_counter(mm, MM_FILEPAGES) +
- get_mm_counter(mm, MM_SHMEMPAGES);
+ *shared = get_mm_counter_sum(mm, MM_FILEPAGES) +
+ get_mm_counter_sum(mm, MM_SHMEMPAGES);
*text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
>> PAGE_SHIFT;
*data = mm->data_vm + mm->stack_vm;
- *resident = *shared + get_mm_counter(mm, MM_ANONPAGES);
+ *resident = *shared + get_mm_counter_sum(mm, MM_ANONPAGES);
return mm->total_vm;
}
--- a/include/linux/mm.h~mm-fix-the-inaccurate-memory-statistics-issue-for-users
+++ a/include/linux/mm.h
@@ -2708,6 +2708,11 @@ static inline unsigned long get_mm_count
return percpu_counter_read_positive(&mm->rss_stat[member]);
}
+static inline unsigned long get_mm_counter_sum(struct mm_struct *mm, int member)
+{
+ return percpu_counter_sum_positive(&mm->rss_stat[member]);
+}
+
void mm_trace_rss_stat(struct mm_struct *mm, int member);
static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
_
Patches currently in -mm which might be from baolin.wang(a)linux.alibaba.com are
mm-fix-the-inaccurate-memory-statistics-issue-for-users.patch
Cc: stable
On 2025/5/28 19:42, Lance Yang wrote:
>
> Thanks for taking the time to review!
>
> On 2025/5/28 19:05, Florian Westphal wrote:
>> Lance Yang <ioworker0(a)gmail.com> wrote:
>>> From: Lance Yang <lance.yang(a)linux.dev>
>>>
>>> When no logger is registered, nf_conntrack_log_invalid fails to log
>>> invalid
>>> packets, leaving users unaware of actual invalid traffic. Improve
>>> this by
>>> loading nf_log_syslog, similar to how 'iptables -I FORWARD 1 -m
>>> conntrack
>>> --ctstate INVALID -j LOG' triggers it.
>>
>> Acked-by: Florian Westphal <fw(a)strlen.de>
>
> Hmm... should this patch be backported to stable kernels? Without it,
> nf_conntrack_log_invalid won't log invalid packets when no logger is
> registered, causing unnecessary debugging effort ;)
>
> Back then, I actually thought my machine wasn't seeing any invalid
> packets... turns out they just weren't logged in dmesg :(
>
> Thanks,
> Lance
[Sinldo Technology]
Company Profile
Hong Kong Sinldo Technology Co., Ltd. was established in 2009 and focuses on the supply chain of Qualcomm chips. As a leading supplier in the industry,
We have established solid cooperative relationships with many internationally renowned manufacturers and are committed to providing customers with high-quality and reliable chip products.
Business Scope:
Import and distribution of Qualcomm chips
Management and bidding for excess electronic components
Provide high-quality customer service and technical support
Mission
Stable supply
Vision
Mutual benefit and Triumph
Value
Reduce Fees and increase efficiency
Environment
The company is located in the core business district, with convenient transportation, elegant environment and complete surrounding supporting facilities, which facilitates the travel and business exchanges of employees and customers.
Milestones
2025
2020
2015
2009
It is expected to complete the upgrade strategic planning, further increase market share, and strive for sustainable development
The company implemented a digital management system and began to actively develop online Deals channels
The company has added multiple 4G Qualcomm chips and established partnerships with more OEM customers。
The company was formally established in Shenzhen and initially established cooperative relationships with global suppliers
Company Environment
Coastal Huanqing
Building
Office Area
storehouse
[Qualcomm]Company Spot
[ WIFI6 - IPQ5018 Kits ]
IPQ5018-0-MRQFN232-MT-01-0
QCN6102-0-DRQFN116-TR-01-0
QCA8337-AL3C
Snapdragon SDM-450-B Kits
SDM-450-B-792NSP-TR-01-0-AA
WTR-2965-0-59F0WNSP-TR-07-1
PMI-8952-0-144WLNSP-TR-02-0-00
WCN-3680B-0-79BWLNSP-TR-05-1
PM-8953-0-187F0WNSP-TR-01-1
MDM9x07 Kits
MDM-9607-0-328PSP-TR-00-0
MDM-9207-0-328PSP-TR-00-0
WTR-2965-0-59F0WNSP-TR-07-1
PMD-9607-0-94WLNSP-TR-04-2
[Sinldo Technology Co., Ltd.]
Email:yesunjian888(a)gmail.com
Skype:625285556(a)qq.com
Address:Room 2305, Hai'an Huanqing Building,
Futian Road, Futian District, Shenzhen
Wechat
Hit subscribe now to receive regular updates and our product’s latest features! Subscribe
If you don't want to receive our emails, you can easily unsubscribe here.
Alan Ye
Purchasing Manager
:+86 136 0651 6680
QUALCOMM
Supply chain : yesunjian888(a)gmail.com
With kernel 6.12.30 waking up from hibernate fails in a Ryzen 3 5600G
system with the latest BIOS. At the end of the wake-up procedure the
screen goes black instead of showing the log-in screen and the system
becomes unresponsive. A hard reset is necessary.
Seeing messages like the following in the system log, I suspected an
amdgpu problem:
May 23 19:09:30 LUX kernel: [16885.524496] amdgpu 0000:30:00.0: [drm]
*ERROR* flip_done timed out
May 23 19:09:30 LUX kernel: [16885.524501] amdgpu 0000:30:00.0: [drm]
*ERROR* [CRTC:73:crtc-0] commit wait timed out
I don't know whether those messages and the problem are really related
but I bisected in 'drivers/gpu/drm/amd' anyway and the result was:
> git bisect bad
25e07c8403f4daad35cffc18d96e32a80a2a3222 is the first bad commit
commit 25e07c8403f4daad35cffc18d96e32a80a2a3222 (HEAD)
Author: Alex Deucher <alexander.deucher(a)amd.com>
Date: Thu May 1 13:46:46 2025 -0400
drm/amdgpu: fix pm notifier handling
commit 4aaffc85751da5722e858e4333e8cf0aa4b6c78f upstream.
Set the s3/s0ix and s4 flags in the pm notifier so that we can skip
the resource evictions properly in pm prepare based on whether
we are suspending or hibernating. Drop the eviction as processes
are not frozen at this time, we we can end up getting stuck trying
to evict VRAM while applications continue to submit work which
causes the buffers to get pulled back into VRAM.
HTH. Thanks.
Rainer
--
The truth always turns out to be simpler than you thought.
Richard Feynman
The patch titled
Subject: mm: fix uprobe pte be overwritten when expanding vma
has been added to the -mm mm-unstable branch. Its filename is
mm-fix-uprobe-pte-be-overwritten-when-expanding-vma.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patche…
This patch will later appear in the mm-unstable branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days
------------------------------------------------------
From: Pu Lehui <pulehui(a)huawei.com>
Subject: mm: fix uprobe pte be overwritten when expanding vma
Date: Thu, 29 May 2025 15:56:47 +0000
Patch series "Fix uprobe pte be overwritten when expanding vma".
This patch (of 4):
We encountered a BUG alert triggered by Syzkaller as follows:
BUG: Bad rss-counter state mm:00000000b4a60fca type:MM_ANONPAGES val:1
And we can reproduce it with the following steps:
1. register uprobe on file at zero offset
2. mmap the file at zero offset:
addr1 = mmap(NULL, 2 * 4096, PROT_NONE, MAP_PRIVATE, fd, 0);
3. mremap part of vma1 to new vma2:
addr2 = mremap(addr1, 4096, 2 * 4096, MREMAP_MAYMOVE);
4. mremap back to orig addr1:
mremap(addr2, 4096, 4096, MREMAP_MAYMOVE | MREMAP_FIXED, addr1);
In step 3, the vma1 range [addr1, addr1 + 4096] will be remap to new vma2
with range [addr2, addr2 + 8192], and remap uprobe anon page from the vma1
to vma2, then unmap the vma1 range [addr1, addr1 + 4096].
In step 4, the vma2 range [addr2, addr2 + 4096] will be remap back to the
addr range [addr1, addr1 + 4096]. Since the addr range [addr1 + 4096,
addr1 + 8192] still maps the file, it will take vma_merge_new_range to
expand the range, and then do uprobe_mmap in vma_complete. Since the
merged vma pgoff is also zero offset, it will install uprobe anon page to
the merged vma. However, the upcomming move_page_tables step, which use
set_pte_at to remap the vma2 uprobe pte to the merged vma, will overwrite
the newly uprobe pte in the merged vma, and lead that pte to be orphan.
Since the uprobe pte will be remapped to the merged vma, we can remove the
unnecessary uprobe_mmap upon merged vma.
This problem was first found in linux-6.6.y and also exists in the
community syzkaller:
https://lore.kernel.org/all/000000000000ada39605a5e71711@google.com/T/
Link: https://lkml.kernel.org/r/20250529155650.4017699-1-pulehui@huaweicloud.com
Link: https://lkml.kernel.org/r/20250529155650.4017699-2-pulehui@huaweicloud.com
Fixes: 2b1444983508 ("uprobes, mm, x86: Add the ability to install and remove uprobes breakpoints")
Signed-off-by: Pu Lehui <pulehui(a)huawei.com>
Suggested-by: Lorenzo Stoakes <lorenzo.stoakes(a)oracle.com>
Cc: Jann Horn <jannh(a)google.com>
Cc: Liam Howlett <liam.howlett(a)oracle.com>
Cc: "Masami Hiramatsu (Google)" <mhiramat(a)kernel.org>
Cc: Oleg Nesterov <oleg(a)redhat.com>
Cc: Peter Zijlstra <peterz(a)infradead.org>
Cc: Vlastimil Babka <vbabka(a)suse.cz>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
mm/vma.c | 20 +++++++++++++++++---
mm/vma.h | 7 +++++++
2 files changed, 24 insertions(+), 3 deletions(-)
--- a/mm/vma.c~mm-fix-uprobe-pte-be-overwritten-when-expanding-vma
+++ a/mm/vma.c
@@ -169,6 +169,9 @@ static void init_multi_vma_prep(struct v
vp->file = vma->vm_file;
if (vp->file)
vp->mapping = vma->vm_file->f_mapping;
+
+ if (vmg && vmg->skip_vma_uprobe)
+ vp->skip_vma_uprobe = true;
}
/*
@@ -358,10 +361,13 @@ static void vma_complete(struct vma_prep
if (vp->file) {
i_mmap_unlock_write(vp->mapping);
- uprobe_mmap(vp->vma);
- if (vp->adj_next)
- uprobe_mmap(vp->adj_next);
+ if (!vp->skip_vma_uprobe) {
+ uprobe_mmap(vp->vma);
+
+ if (vp->adj_next)
+ uprobe_mmap(vp->adj_next);
+ }
}
if (vp->remove) {
@@ -1830,6 +1836,14 @@ struct vm_area_struct *copy_vma(struct v
faulted_in_anon_vma = false;
}
+ /*
+ * If the VMA we are copying might contain a uprobe PTE, ensure
+ * that we do not establish one upon merge. Otherwise, when mremap()
+ * moves page tables, it will orphan the newly created PTE.
+ */
+ if (vma->vm_file)
+ vmg.skip_vma_uprobe = true;
+
new_vma = find_vma_prev(mm, addr, &vmg.prev);
if (new_vma && new_vma->vm_start < addr + len)
return NULL; /* should never get here */
--- a/mm/vma.h~mm-fix-uprobe-pte-be-overwritten-when-expanding-vma
+++ a/mm/vma.h
@@ -19,6 +19,8 @@ struct vma_prepare {
struct vm_area_struct *insert;
struct vm_area_struct *remove;
struct vm_area_struct *remove2;
+
+ bool skip_vma_uprobe :1;
};
struct unlink_vma_file_batch {
@@ -120,6 +122,11 @@ struct vma_merge_struct {
*/
bool give_up_on_oom :1;
+ /*
+ * If set, skip uprobe_mmap upon merged vma.
+ */
+ bool skip_vma_uprobe :1;
+
/* Internal flags set during merge process: */
/*
_
Patches currently in -mm which might be from pulehui(a)huawei.com are
mm-fix-uprobe-pte-be-overwritten-when-expanding-vma.patch
mm-expose-abnormal-new_pte-during-move_ptes.patch
selftests-mm-extract-read_sysfs-and-write_sysfs-into-vm_util.patch
selftests-mm-add-test-about-uprobe-pte-be-orphan-during-vma-merge.patch
There are several issues in pud_free_pmd_page() and pmd_free_pte_page(),
which are used by vmalloc:
1. flush_tlb_kernel_range() does not flush paging-structure caches for
inactive PCIDs, but we're using it when freeing kernel page tables.
2. flush_tlb_kernel_range() only flushes paging-structure cache entries
that intersect with the flush range, and pud_free_pmd_page() passes in
the first PAGE_SIZE bytes of the area covered by the PMD table; but
pud_free_pmd_page() is actually designed to also remove PTE tables that
were installed in the PMD table, so we need to also flush those.
3. [theoretical issue] invlpgb_kernel_range_flush() expects an exclusive
range, it does: `nr = (info->end - addr) >> PAGE_SHIFT;`
But pmd_free_pte_page() and pud_free_pmd_page() provide inclusive
ranges (`addr, addr + PAGE_SIZE-1`).
To fix it:
1. Add a new helper flush_tlb_kernel_pgtable_range() for flushing paging
structure caches for kernel page tables, and use that.
2. Flush PUD_SIZE instead of PAGE_SIZE in pud_free_pmd_page().
3. Remove `-1` in end address calculations.
Note that since I'm not touching invlpgb_kernel_range_flush() or
invlpgb_flush_addr_nosync() in this patch, the flush on PMD table deletion
with INVLPGB might be a bit slow due to using PTE_STRIDE instead of
PMD_STRIDE. I don't think that matters.
Backport notes:
Kernels before 6.16 don't have invlpgb_kernel_range_flush(); for them,
kernel_tlb_flush_pgtable() should just unconditionally call
flush_tlb_all().
I am marking this as fixing commit 28ee90fe6048 ("x86/mm: implement free
pmd/pte page interfaces"); that is technically incorrect, since back then
no paging-structure cache invalidations were performed at all, but probably
makes the most sense here.
Cc: stable(a)vger.kernel.org
Fixes: 28ee90fe6048 ("x86/mm: implement free pmd/pte page interfaces")
Signed-off-by: Jann Horn <jannh(a)google.com>
---
arch/x86/include/asm/tlb.h | 4 ++++
arch/x86/include/asm/tlbflush.h | 1 +
arch/x86/mm/pgtable.c | 13 +++++++++----
arch/x86/mm/tlb.c | 37 +++++++++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h
index 866ea78ba156..56a4b93a0742 100644
--- a/arch/x86/include/asm/tlb.h
+++ b/arch/x86/include/asm/tlb.h
@@ -153,6 +153,10 @@ static inline void invlpgb_flush_all(void)
/* Flush addr, including globals, for all PCIDs. */
static inline void invlpgb_flush_addr_nosync(unsigned long addr, u16 nr)
{
+ /*
+ * Don't set INVLPGB_FLAG_FINAL_ONLY here without adjusting
+ * kernel_tlb_flush_pgtable().
+ */
__invlpgb(0, 0, addr, nr, PTE_STRIDE, INVLPGB_FLAG_INCLUDE_GLOBAL);
}
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index e9b81876ebe4..06a4a2b7a9f5 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -318,6 +318,7 @@ extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
unsigned long end, unsigned int stride_shift,
bool freed_tables);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+void flush_tlb_kernel_pgtable_range(unsigned long start, unsigned long end);
static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a)
{
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 62777ba4de1a..0779ed02226c 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -745,8 +745,13 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr)
pud_clear(pud);
- /* INVLPG to clear all paging-structure caches */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1);
+ /*
+ * Clear paging-structure caches.
+ * Note that since this function can remove a PMD table together with the
+ * PTE tables it points to, we can't just flush the first PAGE_SIZE, we
+ * must flush PUD_SIZE!
+ */
+ flush_tlb_kernel_pgtable_range(addr, addr + PUD_SIZE);
for (i = 0; i < PTRS_PER_PMD; i++) {
if (!pmd_none(pmd_sv[i])) {
@@ -778,8 +783,8 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
pte = (pte_t *)pmd_page_vaddr(*pmd);
pmd_clear(pmd);
- /* INVLPG to clear all paging-structure caches */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1);
+ /* clear paging-structure caches */
+ flush_tlb_kernel_pgtable_range(addr, addr + PAGE_SIZE);
free_page((unsigned long)pte);
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 39f80111e6f1..26b78451a7ed 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -1525,6 +1525,22 @@ static void kernel_tlb_flush_range(struct flush_tlb_info *info)
on_each_cpu(do_kernel_range_flush, info, 1);
}
+static void kernel_tlb_flush_pgtable(struct flush_tlb_info *info)
+{
+ /*
+ * The special thing about removing kernel page tables is that we can't
+ * use a flush that just removes global TLB entries; we need one that
+ * flushes paging structure caches across all PCIDs.
+ * With INVLPGB, that's explicitly supported.
+ * Otherwise, there's no good way (INVLPG and INVPCID can't specifically
+ * target one address across all PCIDs), just throw everything away.
+ */
+ if (cpu_feature_enabled(X86_FEATURE_INVLPGB))
+ invlpgb_kernel_range_flush(info);
+ else
+ flush_tlb_all();
+}
+
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
struct flush_tlb_info *info;
@@ -1542,6 +1558,27 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
put_flush_tlb_info();
}
+/*
+ * Flush paging-structure cache entries for page tables covering the specified
+ * range and synchronize with concurrent hardware page table walks, in
+ * preparation for freeing page tables in the region.
+ * This must not be used for flushing translations to data pages.
+ */
+void flush_tlb_kernel_pgtable_range(unsigned long start, unsigned long end)
+{
+ struct flush_tlb_info *info;
+
+ /* We don't synchronize against GUP-fast. */
+ VM_WARN_ON(start < TASK_SIZE_MAX);
+
+ guard(preempt)();
+
+ info = get_flush_tlb_info(NULL, start, end, PMD_SHIFT, true,
+ TLB_GENERATION_INVALID);
+ kernel_tlb_flush_pgtable(info);
+ put_flush_tlb_info();
+}
+
/*
* This can be used from process context to figure out what the value of
* CR3 is without needing to do a (slow) __read_cr3().
---
base-commit: b1456f6dc167f7f101746e495bede2bac3d0e19f
change-id: 20250528-x86-fix-vmap-pt-del-flush-f9fa4f287c93
--
Jann Horn <jannh(a)google.com>
From: Lee Jones <joneslee(a)google.com>
This is the second attempt at achieving the same goal. This time, the
submission avoids forking the current code base, ensuring it remains
easier to maintain over time.
The set has been tested using the SCM_RIGHTS test suite [1] using QEMU
and has been seen to successfully mitigate a UAF on on a top tier
handset.
RESULTS:
TAP version 13
1..20
# Starting 20 tests from 5 test cases.
# RUN scm_rights.dgram.self_ref ...
# OK scm_rights.dgram.self_ref
ok 1 scm_rights.dgram.self_ref
# RUN scm_rights.dgram.triangle ...
# OK scm_rights.dgram.triangle
ok 2 scm_rights.dgram.triangle
# RUN scm_rights.dgram.cross_edge ...
# OK scm_rights.dgram.cross_edge
ok 3 scm_rights.dgram.cross_edge
# RUN scm_rights.dgram.backtrack_from_scc ...
# OK scm_rights.dgram.backtrack_from_scc
ok 4 scm_rights.dgram.backtrack_from_scc
# RUN scm_rights.stream.self_ref ...
# OK scm_rights.stream.self_ref
ok 5 scm_rights.stream.self_ref
# RUN scm_rights.stream.triangle ...
# OK scm_rights.stream.triangle
ok 6 scm_rights.stream.triangle
# RUN scm_rights.stream.cross_edge ...
# OK scm_rights.stream.cross_edge
ok 7 scm_rights.stream.cross_edge
# RUN scm_rights.stream.backtrack_from_scc ...
# OK scm_rights.stream.backtrack_from_scc
ok 8 scm_rights.stream.backtrack_from_scc
# RUN scm_rights.stream_oob.self_ref ...
# OK scm_rights.stream_oob.self_ref
ok 9 scm_rights.stream_oob.self_ref
# RUN scm_rights.stream_oob.triangle ...
# OK scm_rights.stream_oob.triangle
ok 10 scm_rights.stream_oob.triangle
# RUN scm_rights.stream_oob.cross_edge ...
# OK scm_rights.stream_oob.cross_edge
ok 11 scm_rights.stream_oob.cross_edge
# RUN scm_rights.stream_oob.backtrack_from_scc ...
# OK scm_rights.stream_oob.backtrack_from_scc
ok 12 scm_rights.stream_oob.backtrack_from_scc
# RUN scm_rights.stream_listener.self_ref ...
# OK scm_rights.stream_listener.self_ref
ok 13 scm_rights.stream_listener.self_ref
# RUN scm_rights.stream_listener.triangle ...
# OK scm_rights.stream_listener.triangle
ok 14 scm_rights.stream_listener.triangle
# RUN scm_rights.stream_listener.cross_edge ...
# OK scm_rights.stream_listener.cross_edge
ok 15 scm_rights.stream_listener.cross_edge
# RUN scm_rights.stream_listener.backtrack_from_scc ...
# OK scm_rights.stream_listener.backtrack_from_scc
ok 16 scm_rights.stream_listener.backtrack_from_scc
# RUN scm_rights.stream_listener_oob.self_ref ...
# OK scm_rights.stream_listener_oob.self_ref
ok 17 scm_rights.stream_listener_oob.self_ref
# RUN scm_rights.stream_listener_oob.triangle ...
# OK scm_rights.stream_listener_oob.triangle
ok 18 scm_rights.stream_listener_oob.triangle
# RUN scm_rights.stream_listener_oob.cross_edge ...
# OK scm_rights.stream_listener_oob.cross_edge
ok 19 scm_rights.stream_listener_oob.cross_edge
# RUN scm_rights.stream_listener_oob.backtrack_from_scc ...
# OK scm_rights.stream_listener_oob.backtrack_from_scc
ok 20 scm_rights.stream_listener_oob.backtrack_from_scc
# PASSED: 20 / 20 tests passed.
# Totals: pass:20 fail:0 xfail:0 xpass:0 skip:0 error:0
[0] https://lore.kernel.org/all/20250304030149.82265-1-kuniyu@amazon.com/
[1] https://lore.kernel.org/all/20240325202425.60930-16-kuniyu@amazon.com/
Kuniyuki Iwashima (24):
af_unix: Return struct unix_sock from unix_get_socket().
af_unix: Run GC on only one CPU.
af_unix: Try to run GC async.
af_unix: Replace BUG_ON() with WARN_ON_ONCE().
af_unix: Remove io_uring code for GC.
af_unix: Remove CONFIG_UNIX_SCM.
af_unix: Allocate struct unix_vertex for each inflight AF_UNIX fd.
af_unix: Allocate struct unix_edge for each inflight AF_UNIX fd.
af_unix: Link struct unix_edge when queuing skb.
af_unix: Bulk update unix_tot_inflight/unix_inflight when queuing skb.
af_unix: Iterate all vertices by DFS.
af_unix: Detect Strongly Connected Components.
af_unix: Save listener for embryo socket.
af_unix: Fix up unix_edge.successor for embryo socket.
af_unix: Save O(n) setup of Tarjan's algo.
af_unix: Skip GC if no cycle exists.
af_unix: Avoid Tarjan's algorithm if unnecessary.
af_unix: Assign a unique index to SCC.
af_unix: Detect dead SCC.
af_unix: Replace garbage collection algorithm.
af_unix: Remove lock dance in unix_peek_fds().
af_unix: Try not to hold unix_gc_lock during accept().
af_unix: Don't access successor in unix_del_edges() during GC.
af_unix: Add dead flag to struct scm_fp_list.
Michal Luczaj (1):
af_unix: Fix garbage collection of embryos carrying OOB with
SCM_RIGHTS
Shigeru Yoshida (1):
af_unix: Fix uninit-value in __unix_walk_scc()
include/net/af_unix.h | 49 ++-
include/net/scm.h | 11 +
net/Makefile | 2 +-
net/core/scm.c | 17 ++
net/unix/Kconfig | 5 -
net/unix/Makefile | 2 -
net/unix/af_unix.c | 120 +++++---
net/unix/garbage.c | 691 +++++++++++++++++++++++++++++-------------
net/unix/scm.c | 161 ----------
net/unix/scm.h | 10 -
10 files changed, 617 insertions(+), 451 deletions(-)
delete mode 100644 net/unix/scm.c
delete mode 100644 net/unix/scm.h
--
2.49.0.1112.g889b7c5bd8-goog
Hi Greg and Sasha,
Please find attached backports of commit 2e43ae7dd71c ("drm/i915/gvt:
fix unterminated-string-initialization warning") to address an instance
of -Wunterminated-string-initialization that appears in the i915 driver
with GCC 15 and Clang 21 due to its use of -Wextra. Please let me know
if there are any issues.
Cheers,
Nathan
From: Fedor Pchelkin <pchelkin(a)ispras.ru>
echo_skb_max should define the supported upper limit of echo_skb[]
allocated inside the netdevice's priv. The corresponding size value
provided by this driver to alloc_candev() is KVASER_PCIEFD_CAN_TX_MAX_COUNT
which is 17.
But later echo_skb_max is rounded up to the nearest power of two (for the
max case, that would be 32) and the tx/ack indices calculated further
during tx/rx may exceed the upper array boundary. Kasan reported this for
the ack case inside kvaser_pciefd_handle_ack_packet(), though the xmit
function has actually caught the same thing earlier.
BUG: KASAN: slab-out-of-bounds in kvaser_pciefd_handle_ack_packet+0x2d7/0x92a drivers/net/can/kvaser_pciefd.c:1528
Read of size 8 at addr ffff888105e4f078 by task swapper/4/0
CPU: 4 UID: 0 PID: 0 Comm: swapper/4 Not tainted 6.15.0 #12 PREEMPT(voluntary)
Call Trace:
<IRQ>
dump_stack_lvl lib/dump_stack.c:122
print_report mm/kasan/report.c:521
kasan_report mm/kasan/report.c:634
kvaser_pciefd_handle_ack_packet drivers/net/can/kvaser_pciefd.c:1528
kvaser_pciefd_read_packet drivers/net/can/kvaser_pciefd.c:1605
kvaser_pciefd_read_buffer drivers/net/can/kvaser_pciefd.c:1656
kvaser_pciefd_receive_irq drivers/net/can/kvaser_pciefd.c:1684
kvaser_pciefd_irq_handler drivers/net/can/kvaser_pciefd.c:1733
__handle_irq_event_percpu kernel/irq/handle.c:158
handle_irq_event kernel/irq/handle.c:210
handle_edge_irq kernel/irq/chip.c:833
__common_interrupt arch/x86/kernel/irq.c:296
common_interrupt arch/x86/kernel/irq.c:286
</IRQ>
Tx max count definitely matters for kvaser_pciefd_tx_avail(), but for seq
numbers' generation that's not the case - we're free to calculate them as
would be more convenient, not taking tx max count into account. The only
downside is that the size of echo_skb[] should correspond to the max seq
number (not tx max count), so in some situations a bit more memory would
be consumed than could be.
Thus make the size of the underlying echo_skb[] sufficient for the rounded
max tx value.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 8256e0ca6010 ("can: kvaser_pciefd: Fix echo_skb race")
Cc: stable(a)vger.kernel.org
Signed-off-by: Fedor Pchelkin <pchelkin(a)ispras.ru>
Link: https://patch.msgid.link/20250528192713.63894-1-pchelkin@ispras.ru
Signed-off-by: Marc Kleine-Budde <mkl(a)pengutronix.de>
---
drivers/net/can/kvaser_pciefd.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
index 7d3066691d5d..52301511ed1b 100644
--- a/drivers/net/can/kvaser_pciefd.c
+++ b/drivers/net/can/kvaser_pciefd.c
@@ -966,7 +966,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
u32 status, tx_nr_packets_max;
netdev = alloc_candev(sizeof(struct kvaser_pciefd_can),
- KVASER_PCIEFD_CAN_TX_MAX_COUNT);
+ roundup_pow_of_two(KVASER_PCIEFD_CAN_TX_MAX_COUNT));
if (!netdev)
return -ENOMEM;
@@ -995,7 +995,6 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
can->tx_max_count = min(KVASER_PCIEFD_CAN_TX_MAX_COUNT, tx_nr_packets_max - 1);
can->can.clock.freq = pcie->freq;
- can->can.echo_skb_max = roundup_pow_of_two(can->tx_max_count);
spin_lock_init(&can->lock);
can->can.bittiming_const = &kvaser_pciefd_bittiming_const;
base-commit: 271683bb2cf32e5126c592b5d5e6a756fa374fd9
--
2.47.2
From: Yanqing Wang <ot_yanqing.wang(a)mediatek.com>
Identify the cause of the suspend/resume hang: netif_carrier_off()
is called during link state changes and becomes stuck while
executing linkwatch_work().
To resolve this issue, call netif_device_detach() during the Ethernet
suspend process to temporarily detach the network device from the
kernel and prevent the suspend/resume hang.
Fixes: 8c7bd5a454ff ("net: ethernet: mtk-star-emac: new driver")
Signed-off-by: Yanqing Wang <ot_yanqing.wang(a)mediatek.com>
Signed-off-by: Macpaul Lin <macpaul.lin(a)mediatek.com>
Signed-off-by: Biao Huang <biao.huang(a)mediatek.com>
---
drivers/net/ethernet/mediatek/mtk_star_emac.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index b175119a6a7d..b83886a41121 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -1463,6 +1463,8 @@ static __maybe_unused int mtk_star_suspend(struct device *dev)
if (netif_running(ndev))
mtk_star_disable(ndev);
+ netif_device_detach(ndev);
+
clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
return 0;
@@ -1487,6 +1489,8 @@ static __maybe_unused int mtk_star_resume(struct device *dev)
clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
}
+ netif_device_attach(ndev);
+
return ret;
}
--
2.45.2