1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: ntoskrnl/mm/ARM3/drvmgmt.c 5 * PURPOSE: ARM Memory Manager Driver Management 6 * PROGRAMMERS: ReactOS Portable Systems Group 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include <ntoskrnl.h> 12 #define NDEBUG 13 #include <debug.h> 14 15 #line 15 "ARM³::DRVMGMT" 16 #define MODULE_INVOLVED_IN_ARM3 17 #include "../ARM3/miarm.h" 18 19 /* GLOBALS *******************************************************************/ 20 21 MM_DRIVER_VERIFIER_DATA MmVerifierData; 22 LIST_ENTRY MiVerifierDriverAddedThunkListHead; 23 ULONG MiActiveVerifierThunks; 24 WCHAR MmVerifyDriverBuffer[512] = {0}; 25 ULONG MmVerifyDriverBufferLength = sizeof(MmVerifyDriverBuffer); 26 ULONG MmVerifyDriverBufferType = REG_NONE; 27 ULONG MmVerifyDriverLevel = -1; 28 PVOID MmTriageActionTaken; 29 PVOID KernelVerifier; 30 31 /* PUBLIC FUNCTIONS ***********************************************************/ 32 33 /* 34 * @unimplemented 35 */ 36 VOID 37 NTAPI 38 MmUnlockPageableImageSection(IN PVOID ImageSectionHandle) 39 { 40 UNIMPLEMENTED; 41 } 42 43 /* 44 * @unimplemented 45 */ 46 VOID 47 NTAPI 48 MmLockPageableSectionByHandle(IN PVOID ImageSectionHandle) 49 { 50 UNIMPLEMENTED; 51 } 52 53 /* 54 * @unimplemented 55 */ 56 PVOID 57 NTAPI 58 MmLockPageableDataSection(IN PVOID AddressWithinSection) 59 { 60 // 61 // We should just find the section and call MmLockPageableSectionByHandle 62 // 63 static BOOLEAN Warn; if (!Warn++) UNIMPLEMENTED; 64 return AddressWithinSection; 65 } 66 67 /* 68 * @unimplemented 69 */ 70 ULONG 71 NTAPI 72 MmTrimAllSystemPageableMemory(IN ULONG PurgeTransitionList) 73 { 74 UNIMPLEMENTED; 75 return 0; 76 } 77 78 /* 79 * @implemented 80 */ 81 NTSTATUS 82 NTAPI 83 MmAddVerifierThunks(IN PVOID ThunkBuffer, 84 IN ULONG ThunkBufferSize) 85 { 86 PDRIVER_VERIFIER_THUNK_PAIRS ThunkTable; 87 ULONG ThunkCount; 88 PDRIVER_SPECIFIED_VERIFIER_THUNKS DriverThunks; 89 PLDR_DATA_TABLE_ENTRY LdrEntry; 90 PVOID ModuleBase, ModuleEnd; 91 ULONG i; 92 NTSTATUS Status = STATUS_SUCCESS; 93 PAGED_CODE(); 94 95 // 96 // Make sure the driver verifier is initialized 97 // 98 if (!MiVerifierDriverAddedThunkListHead.Flink) return STATUS_NOT_SUPPORTED; 99 100 // 101 // Get the thunk pairs and count them 102 // 103 ThunkCount = ThunkBufferSize / sizeof(DRIVER_VERIFIER_THUNK_PAIRS); 104 if (!ThunkCount) return STATUS_INVALID_PARAMETER_1; 105 106 // 107 // Now allocate our own thunk table 108 // 109 DriverThunks = ExAllocatePoolWithTag(PagedPool, 110 sizeof(*DriverThunks) + 111 ThunkCount * 112 sizeof(DRIVER_VERIFIER_THUNK_PAIRS), 113 'tVmM'); 114 if (!DriverThunks) return STATUS_INSUFFICIENT_RESOURCES; 115 116 // 117 // Now copy the driver-fed part 118 // 119 ThunkTable = (PDRIVER_VERIFIER_THUNK_PAIRS)(DriverThunks + 1); 120 RtlCopyMemory(ThunkTable, 121 ThunkBuffer, 122 ThunkCount * sizeof(DRIVER_VERIFIER_THUNK_PAIRS)); 123 124 // 125 // Acquire the system load lock 126 // 127 KeEnterCriticalRegion(); 128 KeWaitForSingleObject(&MmSystemLoadLock, 129 WrVirtualMemory, 130 KernelMode, 131 FALSE, 132 NULL); 133 134 // 135 // Get the loader entry 136 // 137 LdrEntry = MiLookupDataTableEntry(ThunkTable->PristineRoutine); 138 if (!LdrEntry) 139 { 140 // 141 // Fail 142 // 143 Status = STATUS_INVALID_PARAMETER_2; 144 goto Cleanup; 145 } 146 147 // 148 // Get driver base and end 149 // 150 ModuleBase = LdrEntry->DllBase; 151 ModuleEnd = (PVOID)((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage); 152 153 // 154 // Don't allow hooking the kernel or HAL 155 // 156 if (ModuleBase < (PVOID)(KSEG0_BASE + MmBootImageSize)) 157 { 158 // 159 // Fail 160 // 161 Status = STATUS_INVALID_PARAMETER_2; 162 goto Cleanup; 163 } 164 165 // 166 // Loop all the thunks 167 // 168 for (i = 0; i < ThunkCount; i++) 169 { 170 // 171 // Make sure it's in the driver 172 // 173 if (((ULONG_PTR)ThunkTable->PristineRoutine < (ULONG_PTR)ModuleBase) || 174 ((ULONG_PTR)ThunkTable->PristineRoutine >= (ULONG_PTR)ModuleEnd)) 175 { 176 // 177 // Nope, fail 178 // 179 Status = STATUS_INVALID_PARAMETER_2; 180 goto Cleanup; 181 } 182 } 183 184 // 185 // Otherwise, add this entry 186 // 187 DriverThunks->DataTableEntry = LdrEntry; 188 DriverThunks->NumberOfThunks = ThunkCount; 189 MiActiveVerifierThunks++; 190 InsertTailList(&MiVerifierDriverAddedThunkListHead, 191 &DriverThunks->ListEntry); 192 DriverThunks = NULL; 193 194 Cleanup: 195 // 196 // Release the lock 197 // 198 KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE); 199 KeLeaveCriticalRegion(); 200 201 // 202 // Free the table if we failed and return status 203 // 204 if (DriverThunks) ExFreePool(DriverThunks); 205 return Status; 206 } 207 208 /* 209 * @implemented 210 */ 211 LOGICAL 212 NTAPI 213 MmIsDriverVerifying(IN PDRIVER_OBJECT DriverObject) 214 { 215 PLDR_DATA_TABLE_ENTRY LdrEntry; 216 217 // 218 // Get the loader entry 219 // 220 LdrEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection; 221 if (!LdrEntry) return FALSE; 222 223 // 224 // Check if we're verifying or not 225 // 226 return (LdrEntry->Flags & LDRP_IMAGE_VERIFYING) ? TRUE: FALSE; 227 } 228 229 /* 230 * @implemented 231 */ 232 NTSTATUS 233 NTAPI 234 MmIsVerifierEnabled(OUT PULONG VerifierFlags) 235 { 236 // 237 // Check if we've actually added anything to the list 238 // 239 if (MiVerifierDriverAddedThunkListHead.Flink) 240 { 241 // 242 // We have, read the verifier level 243 // 244 *VerifierFlags = MmVerifierData.Level; 245 return STATUS_SUCCESS; 246 } 247 248 // 249 // Otherwise, we're disabled 250 // 251 *VerifierFlags = 0; 252 return STATUS_NOT_SUPPORTED; 253 } 254 255 /* EOF */ 256