Index: ntoskrnl/io/pnpmgr/plugplay.c =================================================================== --- ntoskrnl/io/pnpmgr/plugplay.c (revision 67058) +++ ntoskrnl/io/pnpmgr/plugplay.c (working copy) @@ -214,22 +214,24 @@ IopGetInterfaceDeviceList(PPLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA DeviceList) { NTSTATUS Status; + PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA StackList; UNICODE_STRING DeviceInstance; PDEVICE_OBJECT DeviceObject = NULL; - ULONG BufferSize = 0; GUID FilterGuid; PZZWSTR SymbolicLinkList = NULL, LinkList; - ULONG TotalLength = 0; + ULONG TotalLength; _SEH2_TRY { - ProbeForRead(DeviceList->FilterGuid, sizeof(GUID), sizeof(UCHAR)); - RtlCopyMemory(&FilterGuid, DeviceList->FilterGuid, sizeof(GUID)); + ProbeForRead(DeviceList, sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA), sizeof(UCHAR)); + RtlCopyMemory(&StackList, DeviceList, sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA)); - if (DeviceList->Buffer != NULL && DeviceList->BufferSize != 0) + ProbeForRead(StackList.FilterGuid, sizeof(GUID), sizeof(UCHAR)); + RtlCopyMemory(&FilterGuid, StackList.FilterGuid, sizeof(GUID)); + + if (StackList.Buffer != NULL && StackList.BufferSize != 0) { - BufferSize = DeviceList->BufferSize; - ProbeForWrite(DeviceList->Buffer, BufferSize, sizeof(UCHAR)); + ProbeForWrite(StackList.Buffer, StackList.BufferSize, sizeof(UCHAR)); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -238,8 +240,7 @@ } _SEH2_END; - - Status = IopCaptureUnicodeString(&DeviceInstance, &DeviceList->DeviceInstance); + Status = IopCaptureUnicodeString(&DeviceInstance, &StackList.DeviceInstance); if (NT_SUCCESS(Status)) { /* Get the device object */ @@ -247,7 +248,7 @@ ExFreePool(DeviceInstance.Buffer); } - Status = IoGetDeviceInterfaces(&FilterGuid, DeviceObject, DeviceList->Flags, &SymbolicLinkList); + Status = IoGetDeviceInterfaces(&FilterGuid, DeviceObject, StackList.Flags, &SymbolicLinkList); ObDereferenceObject(DeviceObject); if (!NT_SUCCESS(Status)) @@ -259,16 +260,30 @@ LinkList = SymbolicLinkList; while (*SymbolicLinkList != UNICODE_NULL) { - TotalLength += (wcslen(SymbolicLinkList) + 1) * sizeof(WCHAR); SymbolicLinkList += wcslen(SymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR)); } - TotalLength += sizeof(UNICODE_NULL); + TotalLength = ((SymbolicLinkList - LinkList + 1) * sizeof(WCHAR)); - if (BufferSize >= TotalLength) + _SEH2_TRY { - RtlCopyMemory(DeviceList->Buffer, SymbolicLinkList, TotalLength * sizeof(WCHAR)); + if (StackList.Buffer != NULL && + StackList.BufferSize >= TotalLength) + { + // We've already probed the buffer for writing above. + RtlCopyMemory(StackList.Buffer, SymbolicLinkList, TotalLength); + } + + // This probing was basically already done by the caller. + ProbeForWrite(&DeviceList->BufferSize, sizeof(ULONG), sizeof(ULONG)); + DeviceList->BufferSize = TotalLength; } - DeviceList->BufferSize = TotalLength; + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ExFreePool(LinkList); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + ExFreePool(LinkList); return STATUS_SUCCESS; } @@ -831,9 +846,20 @@ } /* Copy event data to the user buffer */ - memcpy(Buffer, - &Entry->Event, - Entry->Event.TotalSize); + _SEH2_TRY + { + ProbeForWrite(Buffer, + Entry->Event.TotalSize, + sizeof(UCHAR)); + RtlCopyMemory(Buffer, + &Entry->Event, + Entry->Event.TotalSize); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; DPRINT("NtGetPlugPlayEvent() done\n");