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