https://git.reactos.org/?p=reactos.git;a=commitdiff;h=79b0fce5dcfd11d1ecb6880929d3660a17b34b45

commit 79b0fce5dcfd11d1ecb6880929d3660a17b34b45
Author:     Thomas Faber <thomas.fa...@reactos.org>
AuthorDate: Tue Nov 1 20:10:04 2022 -0400
Commit:     Thomas Faber <thomas.fa...@reactos.org>
CommitDate: Sun Nov 20 16:02:39 2022 -0500

    [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.
---
 ntoskrnl/config/cminit.c   | 14 ++++++++++----
 ntoskrnl/config/cmwraprs.c | 12 ++++++++++++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/ntoskrnl/config/cminit.c b/ntoskrnl/config/cminit.c
index 5d8ea072761..dd3a051e959 100644
--- a/ntoskrnl/config/cminit.c
+++ b/ntoskrnl/config/cminit.c
@@ -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))
diff --git a/ntoskrnl/config/cmwraprs.c b/ntoskrnl/config/cmwraprs.c
index 0f5e47da922..b23092e0cd9 100644
--- a/ntoskrnl/config/cmwraprs.c
+++ b/ntoskrnl/config/cmwraprs.c
@@ -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;
 }

Reply via email to