Author: fireball
Date: Tue Dec 20 18:16:14 2011
New Revision: 54711
URL: http://svn.reactos.org/svn/reactos?rev=54711&view=rev
Log:
[NTOS]
- A number of fixes to CmpQueryKeyName():
* Properly check the provided buffer size against needed size.
* Don't overwrite user provided buffer.
* Write as much data as could fit into the buffer (this is normal behaviour for any query function in the kernel), returning STATUS_INFO_LENGTH_MISMATCH if not all data were written.
Thanks to r3ddr4g0n for identifying the problem, testing with DPH and testing this patch.
Modified:
trunk/reactos/ntoskrnl/config/cmsysini.c
Modified: trunk/reactos/ntoskrnl/config/cmsysini.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] Tue Dec 20 18:16:14 2011
@@ -121,6 +121,7 @@
IN KPROCESSOR_MODE PreviousMode)
{
PUNICODE_STRING KeyName;
+ ULONG BytesToCopy;
NTSTATUS Status = STATUS_SUCCESS;
PCM_KEY_BODY KeyBody = (PCM_KEY_BODY)ObjectBody;
PCM_KEY_CONTROL_BLOCK Kcb = KeyBody->KeyControlBlock;
@@ -155,16 +156,32 @@
/* Set the returned length */
*ReturnLength = KeyName->Length + sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR);
- /* Check if it fits into the provided buffer */
- if ((Length < sizeof(OBJECT_NAME_INFORMATION)) ||
- (Length < (*ReturnLength - sizeof(OBJECT_NAME_INFORMATION))))
+ /* Calculate amount of bytes to copy into the buffer */
+ BytesToCopy = KeyName->Length + sizeof(WCHAR);
+
+ /* Check if the provided buffer is too small to fit even anything */
+ if ((Length <= sizeof(OBJECT_NAME_INFORMATION)) ||
+ ((Length < (*ReturnLength)) && (BytesToCopy < sizeof(WCHAR))))
{
/* Free the buffer allocated by CmpConstructName */
ExFreePool(KeyName);
- /* Return buffer length failure */
+ /* Return buffer length failure without writing anything there because nothing fits */
return STATUS_INFO_LENGTH_MISMATCH;
}
+
+ /* Check if the provided buffer can be partially written */
+ if (Length < (*ReturnLength))
+ {
+ /* Yes, indicate so in the return status */
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+
+ /* Calculate amount of bytes which the provided buffer could handle */
+ BytesToCopy = Length - sizeof(OBJECT_NAME_INFORMATION);
+ }
+
+ /* Remove the null termination character from the size */
+ BytesToCopy -= sizeof(WCHAR);
/* Fill in the result */
_SEH2_TRY
@@ -177,7 +194,10 @@
/* Copy string content*/
RtlCopyMemory(ObjectNameInfo->Name.Buffer,
KeyName->Buffer,
- *ReturnLength);
+ BytesToCopy);
+
+ /* Null terminate it */
+ ObjectNameInfo->Name.Buffer[BytesToCopy / sizeof(WCHAR)] = 0;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{