From 8612d6c0aa84a5bda1e76c5f97d286dc33648df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 14 Feb 2024 21:56:53 +0100 Subject: [PATCH] [BATTC] Copy BATTERY_WAIT_STATUS structure to prevent memory overwrite. At first QueryStatus call, output is written to Irp->AssociatedIrp.SystemBuffer. Unfortunately, this is also the BattWait buffer. At return of QueryStatus call, BattWait buffer has been modified, so following code can't use it anymore. Fix memory overwrite by copying BattWait buffer on the stack. --- drivers/battery/battc/battc.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/battery/battc/battc.c b/drivers/battery/battc/battc.c index 2ad86b9d9e9..8ddacd64359 100644 --- a/drivers/battery/battc/battc.c +++ b/drivers/battery/battc/battc.c @@ -193,7 +193,7 @@ BatteryClassIoctl(PVOID ClassData, PIO_STACK_LOCATION IrpSp; NTSTATUS Status; ULONG WaitTime; - PBATTERY_WAIT_STATUS BattWait; + BATTERY_WAIT_STATUS BattWait; PBATTERY_QUERY_INFORMATION BattQueryInfo; PBATTERY_SET_INFORMATION BattSetInfo; LARGE_INTEGER Timeout; @@ -263,39 +263,39 @@ BatteryClassIoctl(PVOID ClassData, break; case IOCTL_BATTERY_QUERY_STATUS: - if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattWait) || + if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(BattWait) || IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BATTERY_STATUS)) { Status = STATUS_BUFFER_TOO_SMALL; break; } - BattWait = Irp->AssociatedIrp.SystemBuffer; + BattWait = *(PBATTERY_WAIT_STATUS)Irp->AssociatedIrp.SystemBuffer; - Timeout.QuadPart = Int32x32To64(BattWait->Timeout, -1000); + Timeout.QuadPart = Int32x32To64(BattWait.Timeout, -1000); Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context, - BattWait->BatteryTag, + BattWait.BatteryTag, (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer); BattStatus = Irp->AssociatedIrp.SystemBuffer; if (!NT_SUCCESS(Status) || - ((BattWait->PowerState & BattStatus->PowerState) && - (BattWait->HighCapacity <= BattStatus->Capacity) && - (BattWait->LowCapacity >= BattStatus->Capacity))) + ((BattWait.PowerState & BattStatus->PowerState) && + (BattWait.HighCapacity <= BattStatus->Capacity) && + (BattWait.LowCapacity >= BattStatus->Capacity))) { - BattNotify.PowerState = BattWait->PowerState; - BattNotify.HighCapacity = BattWait->HighCapacity; - BattNotify.LowCapacity = BattWait->LowCapacity; + BattNotify.PowerState = BattWait.PowerState; + BattNotify.HighCapacity = BattWait.HighCapacity; + BattNotify.LowCapacity = BattWait.LowCapacity; BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context, - BattWait->BatteryTag, + BattWait.BatteryTag, &BattNotify); ExAcquireFastMutex(&BattClass->Mutex); BattClass->EventTrigger = EVENT_BATTERY_STATUS; - BattClass->EventTriggerContext = BattWait; + BattClass->EventTriggerContext = &BattWait; BattClass->Waiting = TRUE; ExReleaseFastMutex(&BattClass->Mutex); @@ -303,7 +303,7 @@ BatteryClassIoctl(PVOID ClassData, Executive, KernelMode, FALSE, - BattWait->Timeout != -1 ? &Timeout : NULL); + BattWait.Timeout != -1 ? &Timeout : NULL); ExAcquireFastMutex(&BattClass->Mutex); BattClass->Waiting = FALSE; @@ -314,7 +314,7 @@ BatteryClassIoctl(PVOID ClassData, if (Status == STATUS_SUCCESS) { Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context, - BattWait->BatteryTag, + BattWait.BatteryTag, (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer); if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);