diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2022-11-08 19:20:50 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2022-11-09 13:32:48 +0100 |
commit | 3eef1ae6fa9df8926355bbda51078b1429bb8dd4 (patch) | |
tree | 5c94adf2e8bf64d89c53e5cd032d68c79a6a7e65 | |
parent | d9a0d78fb737445fd69ecf752ea219eda86ce6b9 (diff) | |
download | acpica-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.c | 10 |
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 */ |