mirror of
https://github.com/reactos/reactos.git
synced 2025-07-24 13:13:40 +00:00
- 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. svn path=/trunk/; revision=24437
This commit is contained in:
parent
ebd9a573ec
commit
9088db842e
6 changed files with 213 additions and 16 deletions
|
@ -99,4 +99,12 @@ LdrUnlockLoaderLock(
|
|||
IN ULONG Cookie OPTIONAL
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
LdrVerifyMappedImageMatchesChecksum(
|
||||
IN PVOID BaseAddress,
|
||||
IN ULONG NumberOfBytes,
|
||||
IN ULONG FileLength
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,16 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
LdrVerifyMappedImageMatchesChecksum(IN PVOID BaseAddress,
|
||||
IN ULONG NumberOfBytes,
|
||||
IN ULONG FileLength)
|
||||
{
|
||||
/* FIXME: TODO */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
|
@ -953,9 +953,11 @@ ExPhase2Init(PVOID Context)
|
|||
/* 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);
|
||||
|
|
|
@ -335,6 +335,13 @@ typedef VOID
|
|||
|
||||
/* FUNCTIONS */
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCheckSystemImage(
|
||||
IN HANDLE ImageHandle,
|
||||
IN BOOLEAN PurgeSection
|
||||
);
|
||||
|
||||
/* aspace.c ******************************************************************/
|
||||
|
||||
VOID
|
||||
|
|
|
@ -677,4 +677,108 @@ l_Return:
|
|||
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 */
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
extern ULONG ExpInitializationPhase;
|
||||
|
||||
GENERIC_MAPPING PspProcessMapping =
|
||||
{
|
||||
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||
|
@ -77,11 +79,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,
|
||||
&KeUserApcDispatcher);
|
||||
|
@ -178,10 +175,14 @@ PsLocateSystemDll(VOID)
|
|||
&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 @@ PsLocateSystemDll(VOID)
|
|||
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 @@ PsLocateSystemDll(VOID)
|
|||
(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);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Failed, bugcheck */
|
||||
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 5, 0, 0);
|
||||
}
|
||||
|
||||
/* Now get the Entrypoints */
|
||||
PspLookupKernelUserEntryPoints();
|
||||
return STATUS_SUCCESS;
|
||||
/* 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 @@ BOOLEAN
|
|||
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 **********************************************************/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue