Skip to content

Commit

Permalink
UsbDk: Fix paged memory access under spinlock
Browse files Browse the repository at this point in the history
This patch fixes access to bus device relations array
allocated from paged memory pool under child device list
spinlock.

Fixed by creation of temporary non-paged copy of the paged data.

Signed-off-by: Dmitry Fleytman <[email protected]>
  • Loading branch information
Dmitry Fleytman committed Oct 28, 2015
1 parent accb8b6 commit f228c84
Showing 1 changed file with 58 additions and 3 deletions.
61 changes: 58 additions & 3 deletions UsbDk/FilterDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,15 @@ void CUsbDkHubFilterStrategy::Delete()
class CDeviceRelations
{
public:
CDeviceRelations(PDEVICE_RELATIONS Relations)
: m_Relations(Relations)
CDeviceRelations()
{}

virtual NTSTATUS Create(PDEVICE_RELATIONS Relations)
{
m_Relations = Relations;
return STATUS_SUCCESS;
}

template <typename TPredicate, typename TFunctor>
bool ForEachIf(TPredicate Predicate, TFunctor Functor) const
{
Expand Down Expand Up @@ -178,6 +183,48 @@ class CDeviceRelations
CDeviceRelations& operator= (const CDeviceRelations&) = delete;
};

class CNonPagedDeviceRelations : public CDeviceRelations
{
public:
virtual NTSTATUS Create(PDEVICE_RELATIONS Relations)
{
PDEVICE_RELATIONS NonPagedRelations = nullptr;

if (Relations != nullptr)
{
m_PagedRelations = Relations;

size_t RelationsSize = sizeof(DEVICE_RELATIONS) +
sizeof(PDEVICE_OBJECT ) * Relations->Count -
sizeof(PDEVICE_OBJECT);

auto status = m_NonPagedCopy.Create(RelationsSize, NonPagedPool);
if (!NT_SUCCESS(status))
{
return status;
}

NonPagedRelations = static_cast<PDEVICE_RELATIONS>(m_NonPagedCopy.Ptr());
RtlMoveMemory(NonPagedRelations, Relations, RelationsSize);
}

return CDeviceRelations::Create(NonPagedRelations);
}

~CNonPagedDeviceRelations()
{
auto NonPagedRelations = static_cast<PDEVICE_RELATIONS>(m_NonPagedCopy.Ptr());

if (NonPagedRelations != nullptr)
{
RtlMoveMemory(m_PagedRelations, NonPagedRelations, m_NonPagedCopy.Size());
}
}
private:
CWdmMemoryBuffer m_NonPagedCopy;
PDEVICE_RELATIONS m_PagedRelations = nullptr;
};

NTSTATUS CUsbDkHubFilterStrategy::PNPPreProcess(PIRP Irp)
{
auto irpStack = IoGetCurrentIrpStackLocation(Irp);
Expand All @@ -188,7 +235,15 @@ NTSTATUS CUsbDkHubFilterStrategy::PNPPreProcess(PIRP Irp)
return PostProcessOnSuccess(Irp,
[this](PIRP Irp)
{
CDeviceRelations Relations((PDEVICE_RELATIONS)Irp->IoStatus.Information);
CNonPagedDeviceRelations Relations;
auto status = Relations.Create((PDEVICE_RELATIONS)Irp->IoStatus.Information);

if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! Failed to create device relations object: %!STATUS!", status);
return;
}

DropRemovedDevices(Relations);
AddNewDevices(Relations);
WipeHiddenDevices(Relations);
Expand Down

0 comments on commit f228c84

Please sign in to comment.