mirror of
https://github.com/reactos/reactos.git
synced 2025-07-28 01:41:48 +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
|
IN ULONG Cookie OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
LdrVerifyMappedImageMatchesChecksum(
|
||||||
|
IN PVOID BaseAddress,
|
||||||
|
IN ULONG NumberOfBytes,
|
||||||
|
IN ULONG FileLength
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,16 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
LdrVerifyMappedImageMatchesChecksum(IN PVOID BaseAddress,
|
||||||
|
IN ULONG NumberOfBytes,
|
||||||
|
IN ULONG FileLength)
|
||||||
|
{
|
||||||
|
/* FIXME: TODO */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -953,9 +953,11 @@ ExPhase2Init(PVOID Context)
|
||||||
/* Initialize shared user page. Set dos system path, dos device map, etc. */
|
/* Initialize shared user page. Set dos system path, dos device map, etc. */
|
||||||
InitSystemSharedUserPage(KeLoaderBlock);
|
InitSystemSharedUserPage(KeLoaderBlock);
|
||||||
|
|
||||||
|
/* Initailize the Process Manager at Phase 1 */
|
||||||
|
if (!PsInitSystem()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED);
|
||||||
|
|
||||||
/* Launch initial process */
|
/* Launch initial process */
|
||||||
Status = ExpLoadInitialProcess(&ProcessHandle,
|
Status = ExpLoadInitialProcess(&ProcessHandle, &ThreadHandle);
|
||||||
&ThreadHandle);
|
|
||||||
|
|
||||||
/* Wait 5 seconds for it to initialize */
|
/* Wait 5 seconds for it to initialize */
|
||||||
Timeout.QuadPart = Int32x32To64(5, -10000000);
|
Timeout.QuadPart = Int32x32To64(5, -10000000);
|
||||||
|
|
|
@ -335,6 +335,13 @@ typedef VOID
|
||||||
|
|
||||||
/* FUNCTIONS */
|
/* FUNCTIONS */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmCheckSystemImage(
|
||||||
|
IN HANDLE ImageHandle,
|
||||||
|
IN BOOLEAN PurgeSection
|
||||||
|
);
|
||||||
|
|
||||||
/* aspace.c ******************************************************************/
|
/* aspace.c ******************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -677,4 +677,108 @@ l_Return:
|
||||||
return nStatus;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
extern ULONG ExpInitializationPhase;
|
||||||
|
|
||||||
GENERIC_MAPPING PspProcessMapping =
|
GENERIC_MAPPING PspProcessMapping =
|
||||||
{
|
{
|
||||||
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||||
|
@ -77,11 +79,6 @@ PspLookupKernelUserEntryPoints(VOID)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Get user-mode startup thunk */
|
|
||||||
Status = PspLookupSystemDllEntryPoint(&ThunkName,
|
|
||||||
&PspSystemDllEntryPoint);
|
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
|
||||||
|
|
||||||
/* Get user-mode APC trampoline */
|
/* Get user-mode APC trampoline */
|
||||||
Status = PspLookupSystemDllEntryPoint(&ApcName,
|
Status = PspLookupSystemDllEntryPoint(&ApcName,
|
||||||
&KeUserApcDispatcher);
|
&KeUserApcDispatcher);
|
||||||
|
@ -178,10 +175,14 @@ PsLocateSystemDll(VOID)
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
0);
|
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 */
|
/* FIXME: Check if the image is valid */
|
||||||
Status = STATUS_SUCCESS; //MmCheckSystemImage(FileHandle, TRUE);
|
Status = MmCheckSystemImage(FileHandle, TRUE);
|
||||||
if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
|
if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
|
||||||
{
|
{
|
||||||
/* Raise a hard error */
|
/* Raise a hard error */
|
||||||
|
@ -204,7 +205,11 @@ PsLocateSystemDll(VOID)
|
||||||
SEC_IMAGE,
|
SEC_IMAGE,
|
||||||
FileHandle);
|
FileHandle);
|
||||||
ZwClose(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 */
|
/* Reference the Section */
|
||||||
Status = ObReferenceObjectByHandle(SectionHandle,
|
Status = ObReferenceObjectByHandle(SectionHandle,
|
||||||
|
@ -214,14 +219,58 @@ PsLocateSystemDll(VOID)
|
||||||
(PVOID*)&PspSystemDllSection,
|
(PVOID*)&PspSystemDllSection,
|
||||||
NULL);
|
NULL);
|
||||||
ZwClose(SectionHandle);
|
ZwClose(SectionHandle);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Failed, bugcheck */
|
||||||
|
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 4, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Map it */
|
/* Map it */
|
||||||
Status = PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase);
|
Status = PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Failed, bugcheck */
|
||||||
|
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 5, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Now get the Entrypoints */
|
/* Return status */
|
||||||
PspLookupKernelUserEntryPoints();
|
return Status;
|
||||||
return STATUS_SUCCESS;
|
}
|
||||||
|
|
||||||
|
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
|
BOOLEAN
|
||||||
|
@ -428,8 +477,25 @@ BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
PsInitSystem(VOID)
|
PsInitSystem(VOID)
|
||||||
{
|
{
|
||||||
/* For now, do only Phase 0 */
|
/* Check the initialization phase */
|
||||||
return PspInitPhase0();
|
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 **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue