[NTOS:CM] Consistently use synchronous I/O for registry hives.

Our current CmpFileRead/CmpFileWrite do not wait for completion,
so will cause stack corruption if used on files opened in async
mode.
This commit is contained in:
Thomas Faber 2022-11-01 20:10:04 -04:00
parent dfb7e2d639
commit 79b0fce5dc
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
2 changed files with 22 additions and 4 deletions

View file

@ -366,7 +366,10 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
/* Default attributes */
AttributeFlags = FILE_ATTRIBUTE_NORMAL;
/* Now create the file */
/* Now create the file.
* Note: We use FILE_SYNCHRONOUS_IO_NONALERT here to simplify CmpFileRead/CmpFileWrite.
* Windows does async I/O and therefore does not use this flag (or SYNCHRONIZE).
*/
Status = ZwCreateFile(Primary,
DesiredAccess | SYNCHRONIZE,
&ObjectAttributes,
@ -543,16 +546,19 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
AttributeFlags |= FILE_ATTRIBUTE_HIDDEN;
}
/* Now create the file */
/* Now create the file.
* Note: We use FILE_SYNCHRONOUS_IO_NONALERT here to simplify CmpFileRead/CmpFileWrite.
* Windows does async I/O and therefore does not use this flag (or SYNCHRONIZE).
*/
Status = ZwCreateFile(Log,
DesiredAccess,
DesiredAccess | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
NULL,
AttributeFlags,
ShareMode,
CreateDisposition,
IoFlags,
FILE_SYNCHRONOUS_IO_NONALERT | IoFlags,
NULL,
0);
if ((NT_SUCCESS(Status)) && (MarkAsSystemHive))

View file

@ -89,6 +89,8 @@ CmpFileRead(IN PHHIVE RegistryHive,
_FileOffset.QuadPart = *FileOffset;
Status = ZwReadFile(HiveHandle, NULL, NULL, NULL, &IoStatusBlock,
Buffer, (ULONG)BufferLength, &_FileOffset, NULL);
/* We do synchronous I/O for simplicity - see CmpOpenHiveFiles. */
ASSERT(Status != STATUS_PENDING);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}
@ -117,6 +119,11 @@ CmpFileWrite(IN PHHIVE RegistryHive,
_FileOffset.QuadPart = *FileOffset;
Status = ZwWriteFile(HiveHandle, NULL, NULL, NULL, &IoStatusBlock,
Buffer, (ULONG)BufferLength, &_FileOffset, NULL);
/* We do synchronous I/O for simplicity - see CmpOpenHiveFiles.
* Windows optimizes here by starting an async write for each 64k chunk,
* then waiting for all writes to complete at once.
*/
ASSERT(Status != STATUS_PENDING);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}
@ -178,5 +185,10 @@ CmpFileFlush(IN PHHIVE RegistryHive,
return TRUE;
Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock);
/* This operation is always synchronous */
ASSERT(Status != STATUS_PENDING);
ASSERT(Status == IoStatusBlock.Status);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}