summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2022-11-08 19:20:50 +0100
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2022-11-09 13:32:48 +0100
commit3eef1ae6fa9df8926355bbda51078b1429bb8dd4 (patch)
tree5c94adf2e8bf64d89c53e5cd032d68c79a6a7e65
parentd9a0d78fb737445fd69ecf752ea219eda86ce6b9 (diff)
downloadacpica-3eef1ae6fa9df8926355bbda51078b1429bb8dd4.tar.gz
dispatcher: Fix error code path in AcpiDsCallControlMethod()
A use-after-free in AcpiPsParseAml() after a failing invocaion of AcpiDsCallControlMethod() is reported by KASAN [1] and code inspection reveals that next_walk_state pushed to the thread by AcpiDsCallControlMethod() is freed on errors, but it is not popped from the thread beforehand. Thus AcpiDsGetCurrentWalkState() called by AcpiPsParseAml() subsequently returns it as the new walk state which is incorrect. To address this, make AcpiDsCallControlMethod() call AcpiDsPopWalkState() to pop NextWalkState from the thread before returning an error. Link: https://lore.kernel.org/linux-acpi/20221019073443.248215-1-chenzhongjin@huawei.com/ # [1] Reported-by: Chen Zhongjin <chenzhongjin@huawei.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--source/components/dispatcher/dsmethod.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/source/components/dispatcher/dsmethod.c b/source/components/dispatcher/dsmethod.c
index d5fc3038f..9f2d89abb 100644
--- a/source/components/dispatcher/dsmethod.c
+++ b/source/components/dispatcher/dsmethod.c
@@ -705,7 +705,7 @@ AcpiDsCallControlMethod (
if (!Info)
{
Status = AE_NO_MEMORY;
- goto Cleanup;
+ goto PopWalkState;
}
Info->Parameters = &ThisWalkState->Operands[0];
@@ -717,7 +717,7 @@ AcpiDsCallControlMethod (
ACPI_FREE (Info);
if (ACPI_FAILURE (Status))
{
- goto Cleanup;
+ goto PopWalkState;
}
NextWalkState->MethodNestingDepth = ThisWalkState->MethodNestingDepth + 1;
@@ -764,6 +764,12 @@ AcpiDsCallControlMethod (
return_ACPI_STATUS (Status);
+PopWalkState:
+
+ /* On error, pop the walk state to be deleted from thread */
+
+ AcpiDsPopWalkState(Thread);
+
Cleanup:
/* On error, we must terminate the method properly */