mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
[NTOSKRNL] Check that caller has the priviliege to unload a driver
Also, probe the service name when unloading a driver if called from user-mode. This will avoid that userland applications can trigger an invalid read in the kernel (and thus, a BSOD). CORE-15468
This commit is contained in:
parent
bc5acd8102
commit
daf9743c7b
|
@ -1187,17 +1187,43 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PWSTR Start;
|
PWSTR Start;
|
||||||
BOOLEAN SafeToUnload = TRUE;
|
BOOLEAN SafeToUnload = TRUE;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
DPRINT("IopUnloadDriver('%wZ', %u)\n", DriverServiceName, UnloadPnpDrivers);
|
UNICODE_STRING CapturedServiceName;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
/* Need the appropriate priviliege */
|
||||||
|
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
|
||||||
|
{
|
||||||
|
DPRINT1("No unload privilege!\n");
|
||||||
|
return STATUS_PRIVILEGE_NOT_HELD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Capture the service name */
|
||||||
|
Status = ProbeAndCaptureUnicodeString(&CapturedServiceName, PreviousMode, DriverServiceName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
|
||||||
|
|
||||||
|
|
||||||
|
/* We need a service name */
|
||||||
|
if (CapturedServiceName.Length == 0)
|
||||||
|
{
|
||||||
|
ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the service name from the registry key name
|
* Get the service name from the registry key name
|
||||||
*/
|
*/
|
||||||
Start = wcsrchr(DriverServiceName->Buffer, L'\\');
|
Start = wcsrchr(CapturedServiceName.Buffer, L'\\');
|
||||||
if (Start == NULL)
|
if (Start == NULL)
|
||||||
Start = DriverServiceName->Buffer;
|
Start = CapturedServiceName.Buffer;
|
||||||
else
|
else
|
||||||
Start++;
|
Start++;
|
||||||
|
|
||||||
|
@ -1211,7 +1237,11 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
||||||
ObjectName.Buffer = ExAllocatePoolWithTag(PagedPool,
|
ObjectName.Buffer = ExAllocatePoolWithTag(PagedPool,
|
||||||
ObjectName.MaximumLength,
|
ObjectName.MaximumLength,
|
||||||
TAG_IO);
|
TAG_IO);
|
||||||
if (!ObjectName.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!ObjectName.Buffer)
|
||||||
|
{
|
||||||
|
ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
wcscpy(ObjectName.Buffer, DRIVER_ROOT_NAME);
|
wcscpy(ObjectName.Buffer, DRIVER_ROOT_NAME);
|
||||||
memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR));
|
memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR));
|
||||||
ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = UNICODE_NULL;
|
ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
@ -1232,6 +1262,7 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
||||||
{
|
{
|
||||||
DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
|
DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
|
||||||
ExFreePoolWithTag(ObjectName.Buffer, TAG_IO);
|
ExFreePoolWithTag(ObjectName.Buffer, TAG_IO);
|
||||||
|
ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,6 +1274,7 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
||||||
{
|
{
|
||||||
DPRINT1("Driver deletion pending\n");
|
DPRINT1("Driver deletion pending\n");
|
||||||
ObDereferenceObject(DriverObject);
|
ObDereferenceObject(DriverObject);
|
||||||
|
ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
|
||||||
return STATUS_DELETE_PENDING;
|
return STATUS_DELETE_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,11 +1290,14 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
||||||
QueryTable[0].EntryContext = &ImagePath;
|
QueryTable[0].EntryContext = &ImagePath;
|
||||||
|
|
||||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||||
DriverServiceName->Buffer,
|
CapturedServiceName.Buffer,
|
||||||
QueryTable,
|
QueryTable,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/* We no longer need service name */
|
||||||
|
ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
|
DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
|
||||||
|
|
Loading…
Reference in a new issue