xref: /reactos/ntoskrnl/mm/ARM3/drvmgmt.c (revision 6b3f309a)
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
MmUnlockPageableImageSection(IN PVOID ImageSectionHandle)37 MmUnlockPageableImageSection(IN PVOID ImageSectionHandle)
38 {
39     static ULONG Warn; if (!Warn++) UNIMPLEMENTED;
40 }
41 
42 /*
43  * @unimplemented
44  */
45 VOID
46 NTAPI
MmLockPageableSectionByHandle(IN PVOID ImageSectionHandle)47 MmLockPageableSectionByHandle(IN PVOID ImageSectionHandle)
48 {
49     UNIMPLEMENTED;
50 }
51 
52 /*
53  * @unimplemented
54  */
55 PVOID
56 NTAPI
MmLockPageableDataSection(IN PVOID AddressWithinSection)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
MmTrimAllSystemPageableMemory(IN ULONG PurgeTransitionList)71 MmTrimAllSystemPageableMemory(IN ULONG PurgeTransitionList)
72 {
73     UNIMPLEMENTED;
74     return 0;
75 }
76 
77 /*
78  * @implemented
79  */
80 NTSTATUS
81 NTAPI
MmAddVerifierThunks(IN PVOID ThunkBuffer,IN ULONG ThunkBufferSize)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
MmIsDriverVerifying(IN PDRIVER_OBJECT DriverObject)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
MmIsVerifierEnabled(OUT PULONG VerifierFlags)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