don't access pagable memory at dispatch level in NtQueryDirectoryObject
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
_____
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
--- trunk/reactos/ntoskrnl/ob/dirobj.c 2005-04-19 22:33:09 UTC (rev
14707)
+++ trunk/reactos/ntoskrnl/ob/dirobj.c 2005-04-19 22:45:48 UTC (rev
14708)
@@ -169,6 +169,7 @@
KPROCESSOR_MODE PreviousMode;
ULONG SkipEntries = 0;
ULONG NextEntry = 0;
+ ULONG CopyBytes = 0;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
@@ -318,63 +319,66 @@
Status = STATUS_MORE_ENTRIES;
}
- if(NT_SUCCESS(Status))
+ if(NT_SUCCESS(Status) && nDirectories > 0)
{
- if(nDirectories > 0)
+ PWSTR strbuf =
(PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories);
+ PWSTR deststrbuf =
(PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories);
+
+ CopyBytes = nDirectories *
sizeof(OBJECT_DIRECTORY_INFORMATION);
+
+ /* copy the names from the objects and append them to the list
of the
+ objects. copy to the temporary buffer only because the
directory
+ lock can't be released and the buffer might be pagable
memory! */
+ for(DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
+ nDirectories > 0;
+ nDirectories--, DirInfo++)
{
- _SEH_TRY
+ ULONG NameLength;
+
+ if(DirInfo->ObjectName.Length > 0)
{
- POBJECT_DIRECTORY_INFORMATION DestDirInfo =
(POBJECT_DIRECTORY_INFORMATION)Buffer;
- PWSTR strbuf =
(PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories);
+ RtlCopyMemory(strbuf,
+ DirInfo->ObjectName.Buffer,
+ DirInfo->ObjectName.Length);
+ /* change the buffer pointer to the buffer */
+ DirInfo->ObjectName.Buffer = deststrbuf;
+ NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR);
+ /* NULL-terminate the string */
+ strbuf[NameLength] = L'\0';
+ strbuf += NameLength + 1;
+ deststrbuf += NameLength + 1;
- /* copy all OBJECT_DIRECTORY_INFORMATION structures to the
buffer and
- just append all strings (whose pointers are stored in
the buffer!)
- and replace the pointers */
- for(DirInfo =
(POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
- nDirectories > 0;
- nDirectories--, DirInfo++, DestDirInfo++)
- {
- if(DirInfo->ObjectName.Length > 0)
- {
- DestDirInfo->ObjectName.Length =
DirInfo->ObjectName.Length;
- DestDirInfo->ObjectName.MaximumLength =
DirInfo->ObjectName.MaximumLength;
- DestDirInfo->ObjectName.Buffer = strbuf;
- RtlCopyMemory(strbuf,
- DirInfo->ObjectName.Buffer,
- DirInfo->ObjectName.Length);
- /* NULL-terminate the string */
- strbuf[DirInfo->ObjectName.Length / sizeof(WCHAR)] =
L'\0';
- strbuf += (DirInfo->ObjectName.Length / sizeof(WCHAR))
+ 1;
- }
-
- DestDirInfo->ObjectTypeName.Length =
DirInfo->ObjectTypeName.Length;
- DestDirInfo->ObjectTypeName.MaximumLength =
DirInfo->ObjectTypeName.MaximumLength;
- DestDirInfo->ObjectTypeName.Buffer = strbuf;
- RtlCopyMemory(strbuf,
- DirInfo->ObjectTypeName.Buffer,
- DirInfo->ObjectTypeName.Length);
- /* NULL-terminate the string */
- strbuf[DirInfo->ObjectTypeName.Length / sizeof(WCHAR)] =
L'\0';
- strbuf += (DirInfo->ObjectTypeName.Length /
sizeof(WCHAR)) + 1;
- }
+ CopyBytes += (NameLength + 1) * sizeof(WCHAR);
}
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
+
+ RtlCopyMemory(strbuf,
+ DirInfo->ObjectTypeName.Buffer,
+ DirInfo->ObjectTypeName.Length);
+ /* change the buffer pointer to the buffer */
+ DirInfo->ObjectTypeName.Buffer = deststrbuf;
+ NameLength = DirInfo->ObjectTypeName.Length / sizeof(WCHAR);
+ /* NULL-terminate the string */
+ strbuf[NameLength] = L'\0';
+ strbuf += NameLength + 1;
+ deststrbuf += NameLength + 1;
+
+ CopyBytes += (NameLength + 1) * sizeof(WCHAR);
}
}
KeReleaseSpinLock(&Directory->Lock, OldLevel);
ObDereferenceObject(Directory);
-
- ExFreePool(TemporaryBuffer);
if(NT_SUCCESS(Status) || ReturnSingleEntry)
{
_SEH_TRY
{
+ if(CopyBytes != 0)
+ {
+ RtlCopyMemory(Buffer,
+ TemporaryBuffer,
+ CopyBytes);
+ }
*Context = NextEntry;
if(ReturnLength != NULL)
{
@@ -387,6 +391,8 @@
}
_SEH_END;
}
+
+ ExFreePool(TemporaryBuffer);
}
else
{