Author: ion Date: Sun Oct 8 06:10:34 2006 New Revision: 24437
URL: http://svn.reactos.org/svn/reactos?rev=24437&view=rev Log: - Stub LdrVerifyMappedImageMatchesChecksum. - Separate locating the system DLL from initializing it. - Implement split-phase PsInitSystem for Phase 0 and 1, and make system dll initialization as part of phase 1. - Add MmVerifyImageIsOkForMpUse and MmCheckSystemImage to validate the system DLL. - Add a separate bugcheck for each failure in PsLocateSystemDll, matching with the NT bugchecks that would occur.
Modified: trunk/reactos/include/ndk/ldrfuncs.h trunk/reactos/lib/rtl/image.c trunk/reactos/ntoskrnl/ex/init.c trunk/reactos/ntoskrnl/include/internal/mm.h trunk/reactos/ntoskrnl/mm/pe.c trunk/reactos/ntoskrnl/ps/psmgr.c
Modified: trunk/reactos/include/ndk/ldrfuncs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/ldrfuncs.h?rev=... ============================================================================== --- trunk/reactos/include/ndk/ldrfuncs.h (original) +++ trunk/reactos/include/ndk/ldrfuncs.h Sun Oct 8 06:10:34 2006 @@ -99,4 +99,12 @@ IN ULONG Cookie OPTIONAL );
+BOOLEAN +NTAPI +LdrVerifyMappedImageMatchesChecksum( + IN PVOID BaseAddress, + IN ULONG NumberOfBytes, + IN ULONG FileLength +); + #endif
Modified: trunk/reactos/lib/rtl/image.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/image.c?rev=24437&a... ============================================================================== --- trunk/reactos/lib/rtl/image.c (original) +++ trunk/reactos/lib/rtl/image.c Sun Oct 8 06:10:34 2006 @@ -17,6 +17,16 @@ #include <debug.h>
/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +LdrVerifyMappedImageMatchesChecksum(IN PVOID BaseAddress, + IN ULONG NumberOfBytes, + IN ULONG FileLength) +{ + /* FIXME: TODO */ + return TRUE; +}
/* * @implemented
Modified: trunk/reactos/ntoskrnl/ex/init.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=2443... ============================================================================== --- trunk/reactos/ntoskrnl/ex/init.c (original) +++ trunk/reactos/ntoskrnl/ex/init.c Sun Oct 8 06:10:34 2006 @@ -953,9 +953,11 @@ /* Initialize shared user page. Set dos system path, dos device map, etc. */ InitSystemSharedUserPage(KeLoaderBlock);
+ /* Initailize the Process Manager at Phase 1 */ + if (!PsInitSystem()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED); + /* Launch initial process */ - Status = ExpLoadInitialProcess(&ProcessHandle, - &ThreadHandle); + Status = ExpLoadInitialProcess(&ProcessHandle, &ThreadHandle);
/* Wait 5 seconds for it to initialize */ Timeout.QuadPart = Int32x32To64(5, -10000000);
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/m... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/mm.h (original) +++ trunk/reactos/ntoskrnl/include/internal/mm.h Sun Oct 8 06:10:34 2006 @@ -335,6 +335,13 @@
/* FUNCTIONS */
+NTSTATUS +NTAPI +MmCheckSystemImage( + IN HANDLE ImageHandle, + IN BOOLEAN PurgeSection +); + /* aspace.c ******************************************************************/
VOID
Modified: trunk/reactos/ntoskrnl/mm/pe.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/pe.c?rev=24437&... ============================================================================== --- trunk/reactos/ntoskrnl/mm/pe.c (original) +++ trunk/reactos/ntoskrnl/mm/pe.c Sun Oct 8 06:10:34 2006 @@ -677,4 +677,108 @@ return nStatus; }
+BOOLEAN +NTAPI +MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress) +{ + PIMAGE_NT_HEADERS NtHeader; + PAGED_CODE(); + + /* Get NT Headers */ + NtHeader = RtlImageNtHeader(BaseAddress); + if (NtHeader) + { + /* Check if this image is only safe for UP while we have 2+ CPUs */ + if ((KeNumberProcessors > 1) && + (NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)) + { + /* Fail */ + return FALSE; + } + } + + /* Otherwise, it's safe */ + return TRUE; +} + +NTSTATUS +NTAPI +MmCheckSystemImage(IN HANDLE ImageHandle, + IN BOOLEAN PurgeSection) +{ + NTSTATUS Status; + HANDLE SectionHandle; + PVOID ViewBase = NULL; + SIZE_T ViewSize = 0; + IO_STATUS_BLOCK IoStatusBlock; + FILE_STANDARD_INFORMATION FileStandardInfo; + KAPC_STATE ApcState; + PAGED_CODE(); + + /* Create a section for the DLL */ + Status = ZwCreateSection(&SectionHandle, + SECTION_MAP_EXECUTE, + NULL, + NULL, + PAGE_EXECUTE, + SEC_COMMIT, + ImageHandle); + if (!NT_SUCCESS(Status)) return Status; + + /* Make sure we're in the system process */ + KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState); + + /* Map it */ + Status = ZwMapViewOfSection(SectionHandle, + NtCurrentProcess(), + &ViewBase, + 0, + 0, + NULL, + &ViewSize, + ViewShare, + 0, + PAGE_EXECUTE); + if (!NT_SUCCESS(Status)) + { + /* We failed, close the handle and return */ + KeUnstackDetachProcess(&ApcState); + ZwClose(SectionHandle); + return Status; + } + + /* Now query image information */ + Status = ZwQueryInformationFile(ImageHandle, + &IoStatusBlock, + &FileStandardInfo, + sizeof(FileStandardInfo), + FileStandardInformation); + if ( NT_SUCCESS(Status) ) + { + /* First, verify the checksum */ + if (!LdrVerifyMappedImageMatchesChecksum(ViewBase, + FileStandardInfo. + EndOfFile.LowPart, + FileStandardInfo. + EndOfFile.LowPart)) + { + /* Set checksum failure */ + Status = STATUS_IMAGE_CHECKSUM_MISMATCH; + } + + /* Check that it's a valid SMP image if we have more then one CPU */ + if (!MmVerifyImageIsOkForMpUse(ViewBase)) + { + /* Otherwise it's not the right image */ + Status = STATUS_IMAGE_MP_UP_MISMATCH; + } + } + + /* Unmap the section, close the handle, and return status */ + ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase); + KeUnstackDetachProcess(&ApcState); + ZwClose(SectionHandle); + return Status; +} + /* EOF */
Modified: trunk/reactos/ntoskrnl/ps/psmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/psmgr.c?rev=244... ============================================================================== --- trunk/reactos/ntoskrnl/ps/psmgr.c (original) +++ trunk/reactos/ntoskrnl/ps/psmgr.c Sun Oct 8 06:10:34 2006 @@ -11,6 +11,8 @@ #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h> + +extern ULONG ExpInitializationPhase;
GENERIC_MAPPING PspProcessMapping = { @@ -76,11 +78,6 @@ PspLookupKernelUserEntryPoints(VOID) { NTSTATUS Status; - - /* Get user-mode startup thunk */ - Status = PspLookupSystemDllEntryPoint(&ThunkName, - &PspSystemDllEntryPoint); - if (!NT_SUCCESS(Status)) return Status;
/* Get user-mode APC trampoline */ Status = PspLookupSystemDllEntryPoint(&ApcName, @@ -178,10 +175,14 @@ &IoStatusBlock, FILE_SHARE_READ, 0); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + { + /* Failed, bugcheck */ + KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 2, 0, 0); + }
/* FIXME: Check if the image is valid */ - Status = STATUS_SUCCESS; //MmCheckSystemImage(FileHandle, TRUE); + Status = MmCheckSystemImage(FileHandle, TRUE); if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) { /* Raise a hard error */ @@ -204,7 +205,11 @@ SEC_IMAGE, FileHandle); ZwClose(FileHandle); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + { + /* Failed, bugcheck */ + KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 3, 0, 0); + }
/* Reference the Section */ Status = ObReferenceObjectByHandle(SectionHandle, @@ -214,14 +219,58 @@ (PVOID*)&PspSystemDllSection, NULL); ZwClose(SectionHandle); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + { + /* Failed, bugcheck */ + KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 4, 0, 0); + } +
/* Map it */ Status = PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase); - - /* Now get the Entrypoints */ - PspLookupKernelUserEntryPoints(); - return STATUS_SUCCESS; + if (!NT_SUCCESS(Status)) + { + /* Failed, bugcheck */ + KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 5, 0, 0); + } + + /* Return status */ + return Status; +} + +NTSTATUS +NTAPI +PspInitializeSystemDll(VOID) +{ + NTSTATUS Status; + + /* Get user-mode startup thunk */ + Status = PspLookupSystemDllEntryPoint(&ThunkName, &PspSystemDllEntryPoint); + if (!NT_SUCCESS(Status)) + { + /* Failed, bugcheck */ + KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 7, 0, 0); + } + + /* Get all the other entrypoints */ + Status = PspLookupKernelUserEntryPoints(); + if (!NT_SUCCESS(Status)) + { + /* Failed, bugcheck */ + KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 8, 0, 0); + } + + /* Return status */ + return Status; +} + +BOOLEAN +NTAPI +PspInitPhase1(VOID) +{ + /* Initialize the System DLL and return status of operation */ + if (!NT_SUCCESS(PspInitializeSystemDll())) return FALSE; + return TRUE; }
BOOLEAN @@ -428,8 +477,25 @@ NTAPI PsInitSystem(VOID) { - /* For now, do only Phase 0 */ - return PspInitPhase0(); + /* Check the initialization phase */ + switch (ExpInitializationPhase) + { + case 0: + + /* Do Phase 0 */ + return PspInitPhase0(); + + case 1: + + /* Do Phase 1 */ + return PspInitPhase1(); + + default: + + /* Don't know any other phase! Bugcheck! */ + KeBugCheck(UNEXPECTED_INITIALIZATION_CALL); + return FALSE; + } }
/* PUBLIC FUNCTIONS **********************************************************/