Skip to content

Commit 3a6e0d4

Browse files
committed
[BATTC] Fix IOCTL_BATTERY_QUERY_STATUS
Previously the function waited for the conditions *after* querying the status, and then returned the old status. Also, if querying failed, it waited and when the wait timed out it returned STATUS_SUCCESS without returning any data. If the call to SetStatusNotify failed and there was no timeout, it would wait forever. This is all fixed now.
1 parent ae23b4d commit 3a6e0d4

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

drivers/battery/battc/battc.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -281,32 +281,28 @@ BatteryClassIoctl(PVOID ClassData,
281281

282282
BattWait = *(PBATTERY_WAIT_STATUS)Irp->AssociatedIrp.SystemBuffer;
283283

284-
Timeout.QuadPart = Int32x32To64(BattWait.Timeout, -10000);
285-
286-
BattStatus = Irp->AssociatedIrp.SystemBuffer;
287-
Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
288-
BattWait.BatteryTag,
289-
BattStatus);
290-
291-
if (!NT_SUCCESS(Status) ||
292-
(BattWait.PowerState == BattStatus->PowerState &&
293-
BattWait.HighCapacity >= BattStatus->Capacity &&
294-
BattWait.LowCapacity <= BattStatus->Capacity))
284+
if (BattWait.Timeout != 0)
295285
{
296286
BattNotify.PowerState = BattWait.PowerState;
297287
BattNotify.HighCapacity = BattWait.HighCapacity;
298288
BattNotify.LowCapacity = BattWait.LowCapacity;
299289

300-
BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context,
301-
BattWait.BatteryTag,
302-
&BattNotify);
290+
Status = BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context,
291+
BattWait.BatteryTag,
292+
&BattNotify);
293+
if (!NT_SUCCESS(Status))
294+
{
295+
DPRINT1("SetStatusNotify failed (0x%x)\n", Status);
296+
break;
297+
}
303298

304299
ExAcquireFastMutex(&BattClass->Mutex);
305300
BattClass->EventTrigger = EVENT_BATTERY_STATUS;
306301
BattClass->EventTriggerContext = &BattWait;
307302
BattClass->Waiting = TRUE;
308303
ExReleaseFastMutex(&BattClass->Mutex);
309304

305+
Timeout.QuadPart = Int32x32To64(BattWait.Timeout, -10000);
310306
Status = KeWaitForSingleObject(&BattClass->WaitEvent,
311307
Executive,
312308
KernelMode,
@@ -321,7 +317,15 @@ BatteryClassIoctl(PVOID ClassData,
321317

322318
BattClass->MiniportInfo.DisableStatusNotify(BattClass->MiniportInfo.Context);
323319
}
324-
else
320+
321+
/* Zero the output buffer to prevent leakage of kernel data */
322+
BattStatus = Irp->AssociatedIrp.SystemBuffer;
323+
RtlZeroMemory(BattStatus, sizeof(BATTERY_STATUS));
324+
325+
Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
326+
BattWait.BatteryTag,
327+
BattStatus);
328+
if (NT_SUCCESS(Status))
325329
{
326330
Irp->IoStatus.Information = sizeof(BATTERY_STATUS);
327331
}

0 commit comments

Comments
 (0)