xref: /reactos/ntoskrnl/mm/ARM3/drvmgmt.c (revision b09b5584)
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