OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
ValidateKernel.c
Go to the documentation of this file.
1
16#include "ocvalidate.h"
17#include "OcValidateLib.h"
18#include "KextInfo.h"
19
21
30STATIC
31BOOLEAN
33 IN CONST VOID *PrimaryEntry,
34 IN CONST VOID *SecondaryEntry
35 )
36{
37 CONST OC_KERNEL_ADD_ENTRY *KernelAddPrimaryEntry;
38 CONST OC_KERNEL_ADD_ENTRY *KernelAddSecondaryEntry;
39 CONST CHAR8 *KernelAddPrimaryBundlePathString;
40 CONST CHAR8 *KernelAddSecondaryBundlePathString;
41
42 KernelAddPrimaryEntry = *(CONST OC_KERNEL_ADD_ENTRY **)PrimaryEntry;
43 KernelAddSecondaryEntry = *(CONST OC_KERNEL_ADD_ENTRY **)SecondaryEntry;
44 KernelAddPrimaryBundlePathString = OC_BLOB_GET (&KernelAddPrimaryEntry->BundlePath);
45 KernelAddSecondaryBundlePathString = OC_BLOB_GET (&KernelAddSecondaryEntry->BundlePath);
46
47 if (!KernelAddPrimaryEntry->Enabled || !KernelAddSecondaryEntry->Enabled) {
48 return FALSE;
49 }
50
51 return StringIsDuplicated ("Kernel->Add", KernelAddPrimaryBundlePathString, KernelAddSecondaryBundlePathString);
52}
53
62STATIC
63BOOLEAN
65 IN CONST VOID *PrimaryEntry,
66 IN CONST VOID *SecondaryEntry
67 )
68{
69 CONST OC_KERNEL_BLOCK_ENTRY *KernelBlockPrimaryEntry;
70 CONST OC_KERNEL_BLOCK_ENTRY *KernelBlockSecondaryEntry;
71 CONST CHAR8 *KernelBlockPrimaryIdentifierString;
72 CONST CHAR8 *KernelBlockSecondaryIdentifierString;
73
74 KernelBlockPrimaryEntry = *(CONST OC_KERNEL_BLOCK_ENTRY **)PrimaryEntry;
75 KernelBlockSecondaryEntry = *(CONST OC_KERNEL_BLOCK_ENTRY **)SecondaryEntry;
76 KernelBlockPrimaryIdentifierString = OC_BLOB_GET (&KernelBlockPrimaryEntry->Identifier);
77 KernelBlockSecondaryIdentifierString = OC_BLOB_GET (&KernelBlockSecondaryEntry->Identifier);
78
79 if (!KernelBlockPrimaryEntry->Enabled || !KernelBlockSecondaryEntry->Enabled) {
80 return FALSE;
81 }
82
83 return StringIsDuplicated ("Kernel->Block", KernelBlockPrimaryIdentifierString, KernelBlockSecondaryIdentifierString);
84}
85
94STATIC
95BOOLEAN
97 IN CONST VOID *PrimaryEntry,
98 IN CONST VOID *SecondaryEntry
99 )
100{
101 //
102 // NOTE: Add and Force share the same constructor.
103 //
104 CONST OC_KERNEL_ADD_ENTRY *KernelForcePrimaryEntry;
105 CONST OC_KERNEL_ADD_ENTRY *KernelForceSecondaryEntry;
106 CONST CHAR8 *KernelForcePrimaryBundlePathString;
107 CONST CHAR8 *KernelForceSecondaryBundlePathString;
108
109 KernelForcePrimaryEntry = *(CONST OC_KERNEL_ADD_ENTRY **)PrimaryEntry;
110 KernelForceSecondaryEntry = *(CONST OC_KERNEL_ADD_ENTRY **)SecondaryEntry;
111 KernelForcePrimaryBundlePathString = OC_BLOB_GET (&KernelForcePrimaryEntry->BundlePath);
112 KernelForceSecondaryBundlePathString = OC_BLOB_GET (&KernelForceSecondaryEntry->BundlePath);
113
114 if (!KernelForcePrimaryEntry->Enabled || !KernelForceSecondaryEntry->Enabled) {
115 return FALSE;
116 }
117
118 return StringIsDuplicated ("Kernel->Force", KernelForcePrimaryBundlePathString, KernelForceSecondaryBundlePathString);
119}
120
121STATIC
122UINT32
124 IN OC_GLOBAL_CONFIG *Config
125 )
126{
127 UINT32 ErrorCount;
128 UINT32 Index;
129 CONST CHAR8 *Arch;
130 CONST CHAR8 *BundlePath;
131 UINTN BundlePathSumSize;
132 CONST CHAR8 *Comment;
133 CONST CHAR8 *ExecutablePath;
134 UINTN ExecutableFixedSize;
135 UINTN ExecutablePathSumSize;
136 CONST CHAR8 *MaxKernel;
137 CONST CHAR8 *MinKernel;
138 CONST CHAR8 *PlistPath;
139 UINTN PlistFixedSize;
140 UINTN PlistPathSumSize;
141 BOOLEAN IsLiluUsed;
142 BOOLEAN IsDisableLinkeditJettisonEnabled;
143 UINTN IndexKextInfo;
144 UINTN IndexKextPrecedence;
145 BOOLEAN HasParent;
146 CONST CHAR8 *CurrentKext;
147 CONST CHAR8 *ParentKext;
148 CONST CHAR8 *ChildKext;
149
150 ErrorCount = 0;
151
152 for (Index = 0; Index < Config->Kernel.Add.Count; ++Index) {
153 Arch = OC_BLOB_GET (&Config->Kernel.Add.Values[Index]->Arch);
154 BundlePath = OC_BLOB_GET (&Config->Kernel.Add.Values[Index]->BundlePath);
155 Comment = OC_BLOB_GET (&Config->Kernel.Add.Values[Index]->Comment);
156 ExecutablePath = OC_BLOB_GET (&Config->Kernel.Add.Values[Index]->ExecutablePath);
157 MaxKernel = OC_BLOB_GET (&Config->Kernel.Add.Values[Index]->MaxKernel);
158 MinKernel = OC_BLOB_GET (&Config->Kernel.Add.Values[Index]->MinKernel);
159 PlistPath = OC_BLOB_GET (&Config->Kernel.Add.Values[Index]->PlistPath);
160
161 //
162 // Sanitise strings.
163 //
164 if (!AsciiArchIsLegal (Arch, FALSE)) {
165 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->Arch is borked (Can only be Any, i386, and x86_64)!\n", Index));
166 ++ErrorCount;
167 }
168
169 if (!AsciiFileSystemPathIsLegal (BundlePath)) {
170 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->BundlePath contains illegal character!\n", Index));
171 ++ErrorCount;
172 continue;
173 }
174
175 //
176 // Valid BundlePath must contain .kext suffix.
177 //
178 if (!OcAsciiEndsWith (BundlePath, ".kext", TRUE)) {
179 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->BundlePath does NOT contain .kext suffix!\n", Index));
180 ++ErrorCount;
181 }
182
183 if (!AsciiCommentIsLegal (Comment)) {
184 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->Comment contains illegal character!\n", Index));
185 ++ErrorCount;
186 }
187
188 if (!AsciiFileSystemPathIsLegal (ExecutablePath)) {
189 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->ExecutablePath contains illegal character!\n", Index));
190 ++ErrorCount;
191 continue;
192 }
193
194 if (!AsciiFileSystemPathIsLegal (PlistPath)) {
195 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->PlistPath contains illegal character!\n", Index));
196 ++ErrorCount;
197 continue;
198 }
199
200 //
201 // Valid PlistPath must contain .plist suffix.
202 //
203 if (!OcAsciiEndsWith (PlistPath, ".plist", TRUE)) {
204 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->PlistPath does NOT contain .plist suffix!\n", Index));
205 ++ErrorCount;
206 }
207
208 //
209 // Check the length of path relative to OC directory.
210 //
211 BundlePathSumSize = L_STR_LEN (OPEN_CORE_KEXT_PATH) + AsciiStrSize (BundlePath);
212 if (BundlePathSumSize > OC_STORAGE_SAFE_PATH_MAX) {
213 DEBUG ((
214 DEBUG_WARN,
215 "Kernel->Add[%u]->BundlePath (length %u) is too long (should not exceed %u)!\n",
216 Index,
217 AsciiStrLen (BundlePath),
219 ));
220 ++ErrorCount;
221 }
222
223 //
224 // There is one missing '\\' after the concatenation of BundlePath and ExecutablePath. Append one.
225 //
226 ExecutableFixedSize = L_STR_LEN (OPEN_CORE_KEXT_PATH) + AsciiStrLen (BundlePath) + 1;
227 ExecutablePathSumSize = ExecutableFixedSize + AsciiStrSize (ExecutablePath);
228 if (ExecutablePathSumSize > OC_STORAGE_SAFE_PATH_MAX) {
229 DEBUG ((
230 DEBUG_WARN,
231 "Kernel->Add[%u]->ExecutablePath (length %u) is too long (should not exceed %u)!\n",
232 Index,
233 AsciiStrLen (ExecutablePath),
234 OC_STORAGE_SAFE_PATH_MAX - ExecutableFixedSize
235 ));
236 ++ErrorCount;
237 }
238
239 //
240 // There is one missing '\\' after the concatenation of BundlePath and PlistPath. Append one.
241 //
242 PlistFixedSize = L_STR_LEN (OPEN_CORE_KEXT_PATH) + AsciiStrLen (BundlePath) + 1;
243 PlistPathSumSize = PlistFixedSize + AsciiStrSize (PlistPath);
244 if (PlistPathSumSize > OC_STORAGE_SAFE_PATH_MAX) {
245 DEBUG ((
246 DEBUG_WARN,
247 "Kernel->Add[%u]->PlistPath (length %u) is too long (should not exceed %u)!\n",
248 Index,
249 AsciiStrLen (PlistPath),
250 OC_STORAGE_SAFE_PATH_MAX - PlistFixedSize
251 ));
252 ++ErrorCount;
253 }
254
255 //
256 // MinKernel must not be below macOS 10.4 (Darwin version 8).
257 //
259 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->MinKernel has a Darwin version %a, which is below 8 (macOS 10.4)!\n", Index, MinKernel));
260 ++ErrorCount;
261 }
262
263 //
264 // FIXME: Handle correct kernel version checking.
265 //
266 if ((MaxKernel[0] != '\0') && (OcParseDarwinVersion (MaxKernel) == 0)) {
267 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->MaxKernel (currently set to %a) is borked!\n", Index, MaxKernel));
268 ++ErrorCount;
269 }
270
271 if ((MinKernel[0] != '\0') && (OcParseDarwinVersion (MinKernel) == 0)) {
272 DEBUG ((DEBUG_WARN, "Kernel->Add[%u]->MinKernel (currently set to %a) is borked!\n", Index, MinKernel));
273 ++ErrorCount;
274 }
275
276 for (IndexKextInfo = 0; IndexKextInfo < mKextInfoSize; ++IndexKextInfo) {
277 if (AsciiStrCmp (BundlePath, mKextInfo[IndexKextInfo].KextBundlePath) == 0) {
278 //
279 // BundlePath matched. Continue checking ExecutablePath and PlistPath.
280 //
281 if ( (AsciiStrCmp (ExecutablePath, mKextInfo[IndexKextInfo].KextExecutablePath) == 0)
282 && (AsciiStrCmp (PlistPath, mKextInfo[IndexKextInfo].KextPlistPath) == 0))
283 {
284 //
285 // Special check for Lilu and Quirks->DisableLinkeditJettison.
286 //
287 if (IndexKextInfo == INDEX_KEXT_LILU) {
288 IsLiluUsed = Config->Kernel.Add.Values[Index]->Enabled;
289 IsDisableLinkeditJettisonEnabled = Config->Kernel.Quirks.DisableLinkeditJettison;
290 if (IsLiluUsed && !IsDisableLinkeditJettisonEnabled) {
291 DEBUG ((DEBUG_WARN, "Lilu.kext is loaded at Kernel->Add[%u], but DisableLinkeditJettison is not enabled at Kernel->Quirks!\n", Index));
292 ++ErrorCount;
293 }
294 }
295
296 //
297 // Special check for BrcmFirmwareRepo, which cannot be injected by OC.
298 //
299 if (AsciiStrCmp (BundlePath, "BrcmFirmwareRepo.kext") == 0) {
300 DEBUG ((DEBUG_WARN, "BrcmFirmwareRepo.kext at Kernel->Add[%u] cannot be injected by OpenCore, please remove it!\n", Index));
301 ++ErrorCount;
302 }
303 } else {
304 DEBUG ((
305 DEBUG_WARN,
306 "Kernel->Add[%u] discovers %a, but its ExecutablePath (%a) or PlistPath (%a) is borked!\n",
307 IndexKextInfo,
308 BundlePath,
309 ExecutablePath,
310 PlistPath
311 ));
312 ++ErrorCount;
313 }
314 }
315 }
316 }
317
318 //
319 // Special checks for kext precedence from Acidanthera.
320 //
321 for (IndexKextPrecedence = 0; IndexKextPrecedence < mKextPrecedenceSize; ++IndexKextPrecedence) {
322 HasParent = FALSE;
323
324 for (Index = 0; Index < Config->Kernel.Add.Count; ++Index) {
325 CurrentKext = OC_BLOB_GET (&Config->Kernel.Add.Values[Index]->BundlePath);
326 ParentKext = mKextPrecedence[IndexKextPrecedence].Parent;
327 ChildKext = mKextPrecedence[IndexKextPrecedence].Child;
328
329 if (AsciiStrCmp (CurrentKext, ParentKext) == 0) {
330 HasParent = TRUE;
331 } else if (AsciiStrCmp (CurrentKext, ChildKext) == 0) {
332 if (!HasParent) {
333 DEBUG ((DEBUG_WARN, "Kernel->Add[%u] discovers %a, but its Parent (%a) is either placed after it or is missing!\n", Index, CurrentKext, ParentKext));
334 ++ErrorCount;
335 }
336
337 //
338 // Parent is already found before Child as guaranteed by the first if. Done.
339 //
340 break;
341 }
342 }
343 }
344
345 //
346 // Check duplicated entries in Kernel->Add.
347 //
348 ErrorCount += FindArrayDuplication (
349 Config->Kernel.Add.Values,
350 Config->Kernel.Add.Count,
351 sizeof (Config->Kernel.Add.Values[0]),
353 );
354
355 return ErrorCount;
356}
357
358STATIC
359UINT32
361 IN OC_GLOBAL_CONFIG *Config
362 )
363{
364 UINT32 ErrorCount;
365 UINT32 Index;
366 CONST CHAR8 *Arch;
367 CONST CHAR8 *Comment;
368 CONST CHAR8 *MaxKernel;
369 CONST CHAR8 *MinKernel;
370 CONST CHAR8 *Identifier;
371 CONST CHAR8 *Strategy;
372
373 ErrorCount = 0;
374
375 for (Index = 0; Index < Config->Kernel.Block.Count; ++Index) {
376 Arch = OC_BLOB_GET (&Config->Kernel.Block.Values[Index]->Arch);
377 Comment = OC_BLOB_GET (&Config->Kernel.Block.Values[Index]->Comment);
378 Identifier = OC_BLOB_GET (&Config->Kernel.Block.Values[Index]->Identifier);
379 MaxKernel = OC_BLOB_GET (&Config->Kernel.Block.Values[Index]->MaxKernel);
380 MinKernel = OC_BLOB_GET (&Config->Kernel.Block.Values[Index]->MinKernel);
381 Strategy = OC_BLOB_GET (&Config->Kernel.Block.Values[Index]->Strategy);
382
383 //
384 // Sanitise strings.
385 //
386 if (!AsciiArchIsLegal (Arch, FALSE)) {
387 DEBUG ((DEBUG_WARN, "Kernel->Block[%u]->Arch is borked (Can only be Any, i386, and x86_64)!\n", Index));
388 ++ErrorCount;
389 }
390
391 if (!AsciiCommentIsLegal (Comment)) {
392 DEBUG ((DEBUG_WARN, "Kernel->Block[%u]->Comment contains illegal character!\n", Index));
393 ++ErrorCount;
394 }
395
396 if (!AsciiIdentifierIsLegal (Identifier, TRUE)) {
397 DEBUG ((DEBUG_WARN, "Kernel->Block[%u]->Identifier contains illegal character!\n", Index));
398 ++ErrorCount;
399 }
400
401 //
402 // MinKernel must not be below macOS 10.4 (Darwin version 8).
403 //
405 DEBUG ((DEBUG_WARN, "Kernel->Block[%u]->MinKernel has a Darwin version %a, which is below 8 (macOS 10.4)!\n", Index, MinKernel));
406 ++ErrorCount;
407 }
408
409 //
410 // FIXME: Handle correct kernel version checking.
411 //
412 if ((MaxKernel[0] != '\0') && (OcParseDarwinVersion (MaxKernel) == 0)) {
413 DEBUG ((DEBUG_WARN, "Kernel->Block[%u]->MaxKernel (currently set to %a) is borked!\n", Index, MaxKernel));
414 ++ErrorCount;
415 }
416
417 if ((MinKernel[0] != '\0') && (OcParseDarwinVersion (MinKernel) == 0)) {
418 DEBUG ((DEBUG_WARN, "Kernel->Block[%u]->MinKernel (currently set to %a) is borked!\n", Index, MinKernel));
419 ++ErrorCount;
420 }
421
422 if ( (AsciiStrCmp (Strategy, "Disable") != 0)
423 && (AsciiStrCmp (Strategy, "Exclude") != 0))
424 {
425 DEBUG ((DEBUG_WARN, "Kernel->Block[%u]->Strategy is borked (Can only be Disable or Exclude)!\n", Index));
426 ++ErrorCount;
427 }
428 }
429
430 //
431 // Check duplicated entries in Kernel->Block.
432 //
433 ErrorCount += FindArrayDuplication (
434 Config->Kernel.Block.Values,
435 Config->Kernel.Block.Count,
436 sizeof (Config->Kernel.Block.Values[0]),
438 );
439
440 return ErrorCount;
441}
442
443STATIC
444UINT32
446 IN OC_GLOBAL_CONFIG *Config
447 )
448{
449 UINT32 ErrorCount;
450 CONST CHAR8 *MaxKernel;
451 CONST CHAR8 *MinKernel;
452 BOOLEAN Result;
453
454 ErrorCount = 0;
455
456 MaxKernel = OC_BLOB_GET (&Config->Kernel.Emulate.MaxKernel);
457 MinKernel = OC_BLOB_GET (&Config->Kernel.Emulate.MinKernel);
458
459 //
460 // MinKernel must not be below macOS 10.4 (Darwin version 8).
461 //
463 DEBUG ((DEBUG_WARN, "Kernel->Emulate->MinKernel has a Darwin version %a, which is below 8 (macOS 10.4)!\n", MinKernel));
464 ++ErrorCount;
465 }
466
467 //
468 // FIXME: Handle correct kernel version checking.
469 //
470 if ((MaxKernel[0] != '\0') && (OcParseDarwinVersion (MaxKernel) == 0)) {
471 DEBUG ((DEBUG_WARN, "Kernel->Emulate->MaxKernel (currently set to %a) is borked!\n", MaxKernel));
472 ++ErrorCount;
473 }
474
475 if ((MinKernel[0] != '\0') && (OcParseDarwinVersion (MinKernel) == 0)) {
476 DEBUG ((DEBUG_WARN, "Kernel->Emulate->MinKernel (currently set to %a) is borked!\n", MinKernel));
477 ++ErrorCount;
478 }
479
480 Result = DataHasProperMasking (
481 Config->Kernel.Emulate.Cpuid1Data,
482 Config->Kernel.Emulate.Cpuid1Mask,
483 sizeof (Config->Kernel.Emulate.Cpuid1Data),
484 sizeof (Config->Kernel.Emulate.Cpuid1Mask)
485 );
486
487 if (!Result) {
488 DEBUG ((DEBUG_WARN, "Kernel->Emulate->Cpuid1Data requires Cpuid1Mask to be active for replaced bits!\n"));
489 ++ErrorCount;
490 }
491
492 return ErrorCount;
493}
494
495STATIC
496UINT32
498 IN OC_GLOBAL_CONFIG *Config
499 )
500{
501 UINT32 ErrorCount;
502 UINT32 Index;
503 CONST CHAR8 *Arch;
504 CONST CHAR8 *BundlePath;
505 CONST CHAR8 *Comment;
506 CONST CHAR8 *ExecutablePath;
507 CONST CHAR8 *Identifier;
508 CONST CHAR8 *MaxKernel;
509 CONST CHAR8 *MinKernel;
510 CONST CHAR8 *PlistPath;
511
512 ErrorCount = 0;
513
514 for (Index = 0; Index < Config->Kernel.Force.Count; ++Index) {
515 Arch = OC_BLOB_GET (&Config->Kernel.Force.Values[Index]->Arch);
516 BundlePath = OC_BLOB_GET (&Config->Kernel.Force.Values[Index]->BundlePath);
517 Comment = OC_BLOB_GET (&Config->Kernel.Force.Values[Index]->Comment);
518 ExecutablePath = OC_BLOB_GET (&Config->Kernel.Force.Values[Index]->ExecutablePath);
519 Identifier = OC_BLOB_GET (&Config->Kernel.Force.Values[Index]->Identifier);
520 MaxKernel = OC_BLOB_GET (&Config->Kernel.Force.Values[Index]->MaxKernel);
521 MinKernel = OC_BLOB_GET (&Config->Kernel.Force.Values[Index]->MinKernel);
522 PlistPath = OC_BLOB_GET (&Config->Kernel.Force.Values[Index]->PlistPath);
523
524 //
525 // Sanitise strings.
526 //
527 if (!AsciiArchIsLegal (Arch, FALSE)) {
528 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->Arch is borked (Can only be Any, i386, and x86_64)!\n", Index));
529 ++ErrorCount;
530 }
531
532 if (!AsciiIdentifierIsLegal (Identifier, TRUE)) {
533 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->Identifier contains illegal character!\n", Index));
534 ++ErrorCount;
535 }
536
537 if (!AsciiFileSystemPathIsLegal (BundlePath)) {
538 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->BundlePath contains illegal character!\n", Index));
539 ++ErrorCount;
540 continue;
541 }
542
543 //
544 // Valid BundlePath must contain .kext suffix.
545 //
546 if (!OcAsciiEndsWith (BundlePath, ".kext", TRUE)) {
547 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->BundlePath does NOT contain .kext suffix!\n", Index));
548 ++ErrorCount;
549 }
550
551 if (!AsciiCommentIsLegal (Comment)) {
552 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->Comment contains illegal character!\n", Index));
553 ++ErrorCount;
554 }
555
556 if (!AsciiFileSystemPathIsLegal (ExecutablePath)) {
557 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->ExecutablePath contains illegal character!\n", Index));
558 ++ErrorCount;
559 continue;
560 }
561
562 if (!AsciiFileSystemPathIsLegal (PlistPath)) {
563 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->PlistPath contains illegal character!\n", Index));
564 ++ErrorCount;
565 continue;
566 }
567
568 //
569 // Valid PlistPath must contain .plist suffix.
570 //
571 if (!OcAsciiEndsWith (PlistPath, ".plist", TRUE)) {
572 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->PlistPath does NOT contain .plist suffix!\n", Index));
573 ++ErrorCount;
574 }
575
576 //
577 // MinKernel must not be below macOS 10.4 (Darwin version 8).
578 //
580 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->MinKernel has a Darwin version %a, which is below 8 (macOS 10.4)!\n", Index, MinKernel));
581 ++ErrorCount;
582 }
583
584 //
585 // FIXME: Handle correct kernel version checking.
586 //
587 if ((MaxKernel[0] != '\0') && (OcParseDarwinVersion (MaxKernel) == 0)) {
588 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->MaxKernel (currently set to %a) is borked!\n", Index, MaxKernel));
589 ++ErrorCount;
590 }
591
592 if ((MinKernel[0] != '\0') && (OcParseDarwinVersion (MinKernel) == 0)) {
593 DEBUG ((DEBUG_WARN, "Kernel->Force[%u]->MinKernel (currently set to %a) is borked!\n", Index, MinKernel));
594 ++ErrorCount;
595 }
596 }
597
598 //
599 // Check duplicated entries in Kernel->Force.
600 //
601 ErrorCount += FindArrayDuplication (
602 Config->Kernel.Force.Values,
603 Config->Kernel.Force.Count,
604 sizeof (Config->Kernel.Force.Values[0]),
606 );
607
608 return ErrorCount;
609}
610
611STATIC
612UINT32
614 IN OC_GLOBAL_CONFIG *Config
615 )
616{
617 UINT32 ErrorCount;
618 UINT32 Index;
619 CONST CHAR8 *Arch;
620 CONST CHAR8 *Comment;
621 CONST CHAR8 *MaxKernel;
622 CONST CHAR8 *MinKernel;
623 CONST CHAR8 *Identifier;
624 CONST CHAR8 *Base;
625 CONST UINT8 *Find;
626 UINT32 FindSize;
627 CONST UINT8 *Replace;
628 UINT32 ReplaceSize;
629 CONST UINT8 *Mask;
630 UINT32 MaskSize;
631 CONST UINT8 *ReplaceMask;
632 UINT32 ReplaceMaskSize;
633
634 ErrorCount = 0;
635
636 for (Index = 0; Index < Config->Kernel.Patch.Count; ++Index) {
637 Base = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->Base);
638 Comment = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->Comment);
639 Arch = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->Arch);
640 Identifier = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->Identifier);
641 Find = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->Find);
642 FindSize = Config->Kernel.Patch.Values[Index]->Find.Size;
643 Replace = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->Replace);
644 ReplaceSize = Config->Kernel.Patch.Values[Index]->Replace.Size;
645 Mask = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->Mask);
646 MaskSize = Config->Kernel.Patch.Values[Index]->Mask.Size;
647 ReplaceMask = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->ReplaceMask);
648 ReplaceMaskSize = Config->Kernel.Patch.Values[Index]->ReplaceMask.Size;
649 MaxKernel = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->MaxKernel);
650 MinKernel = OC_BLOB_GET (&Config->Kernel.Patch.Values[Index]->MinKernel);
651
652 //
653 // Sanitise strings.
654 //
655 if (!AsciiCommentIsLegal (Comment)) {
656 DEBUG ((DEBUG_WARN, "Kernel->Patch[%u]->Comment contains illegal character!\n", Index));
657 ++ErrorCount;
658 }
659
660 if (!AsciiArchIsLegal (Arch, FALSE)) {
661 DEBUG ((DEBUG_WARN, "Kernel->Patch[%u]->Arch is borked (Can only be Any, i386, and x86_64)!\n", Index));
662 ++ErrorCount;
663 }
664
665 if (!AsciiIdentifierIsLegal (Identifier, TRUE)) {
666 DEBUG ((DEBUG_WARN, "Kernel->Patch[%u]->Identifier contains illegal character!\n", Index));
667 ++ErrorCount;
668 }
669
670 //
671 // MinKernel must not be below macOS 10.4 (Darwin version 8).
672 //
674 DEBUG ((DEBUG_WARN, "Kernel->Patch[%u]->MinKernel has a Darwin version %a, which is below 8 (macOS 10.4)!\n", Index, MinKernel));
675 ++ErrorCount;
676 }
677
678 //
679 // FIXME: Handle correct kernel version checking.
680 //
681 if ((MaxKernel[0] != '\0') && (OcParseDarwinVersion (MaxKernel) == 0)) {
682 DEBUG ((DEBUG_WARN, "Kernel->Patch[%u]->MaxKernel (currently set to %a) is borked!\n", Index, MaxKernel));
683 ++ErrorCount;
684 }
685
686 if ((MinKernel[0] != '\0') && (OcParseDarwinVersion (MinKernel) == 0)) {
687 DEBUG ((DEBUG_WARN, "Kernel->Patch[%u]->MinKernel (currently set to %a) is borked!\n", Index, MinKernel));
688 ++ErrorCount;
689 }
690
691 //
692 // Checks for size.
693 //
694 ErrorCount += ValidatePatch (
695 "Kernel->Patch",
696 Index,
697 Base[0] != '\0' && FindSize == 0,
698 Find,
699 FindSize,
700 Replace,
701 ReplaceSize,
702 Mask,
703 MaskSize,
704 ReplaceMask,
705 ReplaceMaskSize
706 );
707 }
708
709 return ErrorCount;
710}
711
712STATIC
713UINT32
715 IN OC_GLOBAL_CONFIG *Config
716 )
717{
718 UINT32 ErrorCount;
719 BOOLEAN IsCustomSMBIOSGuidEnabled;
720 CONST CHAR8 *UpdateSMBIOSMode;
721 INT64 SetApfsTrimTimeout;
722
723 ErrorCount = 0;
724
725 //
726 // CustomSMBIOSGuid quirk requires UpdateSMBIOSMode at PlatformInfo set to Custom.
727 //
728 IsCustomSMBIOSGuidEnabled = Config->Kernel.Quirks.CustomSmbiosGuid;
729 UpdateSMBIOSMode = OC_BLOB_GET (&Config->PlatformInfo.UpdateSmbiosMode);
730 if (IsCustomSMBIOSGuidEnabled && (AsciiStrCmp (UpdateSMBIOSMode, "Custom") != 0)) {
731 DEBUG ((DEBUG_WARN, "Kernel->Quirks->CustomSMBIOSGuid is enabled, but PlatformInfo->UpdateSMBIOSMode is not set to Custom!\n"));
732 ++ErrorCount;
733 }
734
735 SetApfsTrimTimeout = Config->Kernel.Quirks.SetApfsTrimTimeout;
736 if ( (SetApfsTrimTimeout > MAX_UINT32)
737 || (SetApfsTrimTimeout < -1))
738 {
739 DEBUG ((DEBUG_WARN, "Kernel->Quirks->SetApfsTrimTimeout is invalid value %d!\n", SetApfsTrimTimeout));
740 ++ErrorCount;
741 }
742
743 return ErrorCount;
744}
745
746STATIC
747UINT32
749 IN OC_GLOBAL_CONFIG *Config
750 )
751{
752 UINT32 ErrorCount;
753 CONST CHAR8 *Arch;
754 CONST CHAR8 *KernelCache;
755
756 ErrorCount = 0;
757
758 //
759 // Sanitise Kernel->Scheme keys.
760 //
761 Arch = OC_BLOB_GET (&Config->Kernel.Scheme.KernelArch);
762 if (!AsciiArchIsLegal (Arch, TRUE)) {
763 DEBUG ((DEBUG_WARN, "Kernel->Scheme->KernelArch is borked (Can only be Auto, i386, i386-user32, or x86_64)!\n"));
764 ++ErrorCount;
765 }
766
767 KernelCache = OC_BLOB_GET (&Config->Kernel.Scheme.KernelCache);
768 if ( (AsciiStrCmp (KernelCache, "Auto") != 0)
769 && (AsciiStrCmp (KernelCache, "Cacheless") != 0)
770 && (AsciiStrCmp (KernelCache, "Mkext") != 0)
771 && (AsciiStrCmp (KernelCache, "Prelinked") != 0))
772 {
773 DEBUG ((DEBUG_WARN, "Kernel->Scheme->KernelCache is borked (Can only be Auto, Cacheless, Mkext, or Prelinked)!\n"));
774 ++ErrorCount;
775 }
776
777 return ErrorCount;
778}
779
780UINT32
782 IN OC_GLOBAL_CONFIG *Config
783 )
784{
785 UINT32 ErrorCount;
786 UINTN Index;
787 STATIC CONFIG_CHECK KernelCheckers[] = {
795 };
796
797 DEBUG ((DEBUG_VERBOSE, "config loaded into %a!\n", __func__));
798
799 ErrorCount = 0;
800
801 //
802 // Ensure correct kext info prior to verification.
803 //
805
806 for (Index = 0; Index < ARRAY_SIZE (KernelCheckers); ++Index) {
807 ErrorCount += KernelCheckers[Index](Config);
808 }
809
810 return ReportError (__func__, ErrorCount);
811}
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
VOID ValidateKextInfo(VOID)
Definition KextInfo.c:111
KEXT_INFO mKextInfo[]
Definition KextInfo.c:50
UINTN mKextInfoSize
Definition KextInfo.c:108
UINTN mKextPrecedenceSize
Definition KextInfo.c:48
KEXT_PRECEDENCE mKextPrecedence[]
Definition KextInfo.c:20
#define INDEX_KEXT_LILU
Definition KextInfo.h:19
BOOLEAN OcMatchDarwinVersion(IN UINT32 CurrentVersion OPTIONAL, IN UINT32 MinVersion OPTIONAL, IN UINT32 MaxVersion OPTIONAL)
UINT32 OcParseDarwinVersion(IN CONST CHAR8 *String)
#define KERNEL_VERSION_TIGER_MIN
#define OPEN_CORE_KEXT_PATH
Definition OcMainLib.h:60
#define OC_STORAGE_SAFE_PATH_MAX
#define L_STR_LEN(String)
Definition OcStringLib.h:26
BOOLEAN EFIAPI OcAsciiEndsWith(IN CONST CHAR8 *String, IN CONST CHAR8 *SearchString, IN BOOLEAN CaseInsensitiveMatch)
Definition OcAsciiLib.c:265
#define OC_BLOB_GET(Blob)
BOOLEAN DataHasProperMasking(IN CONST VOID *Data, IN CONST VOID *Mask, IN UINTN DataSize, IN UINTN MaskSize)
UINT32 ReportError(IN CONST CHAR8 *FuncName, IN UINT32 ErrorCount)
BOOLEAN AsciiArchIsLegal(IN CONST CHAR8 *Arch, IN BOOLEAN IsKernelArch)
UINT32 ValidatePatch(IN CONST CHAR8 *PatchSection, IN UINT32 PatchIndex, IN BOOLEAN FindSizeCanBeZero, IN CONST UINT8 *Find, IN UINT32 FindSize, IN CONST UINT8 *Replace, IN UINT32 ReplaceSize, IN CONST UINT8 *Mask, IN UINT32 MaskSize, IN CONST UINT8 *ReplaceMask, IN UINT32 ReplaceMaskSize)
BOOLEAN StringIsDuplicated(IN CONST CHAR8 *EntrySection, IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
UINT32 FindArrayDuplication(IN VOID *First, IN UINTN Number, IN UINTN Size, IN DUPLICATION_CHECK DupChecker)
BOOLEAN AsciiFileSystemPathIsLegal(IN CONST CHAR8 *Path)
BOOLEAN AsciiIdentifierIsLegal(IN CONST CHAR8 *Identifier, IN BOOLEAN IsKernelIdentifier)
BOOLEAN AsciiCommentIsLegal(IN CONST CHAR8 *Comment)
STATIC UINT32 CheckKernelAdd(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckKernelPatch(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckKernelForce(IN OC_GLOBAL_CONFIG *Config)
STATIC BOOLEAN KernelForceHasDuplication(IN CONST VOID *PrimaryEntry, IN CONST VOID *SecondaryEntry)
STATIC UINT32 CheckKernelBlock(IN OC_GLOBAL_CONFIG *Config)
STATIC BOOLEAN KernelAddHasDuplication(IN CONST VOID *PrimaryEntry, IN CONST VOID *SecondaryEntry)
STATIC UINT32 CheckKernelQuirks(IN OC_GLOBAL_CONFIG *Config)
UINT32 CheckKernel(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckKernelScheme(IN OC_GLOBAL_CONFIG *Config)
STATIC BOOLEAN KernelBlockHasDuplication(IN CONST VOID *PrimaryEntry, IN CONST VOID *SecondaryEntry)
STATIC UINT32 CheckKernelEmulate(IN OC_GLOBAL_CONFIG *Config)
UINT32(* CONFIG_CHECK)(IN OC_GLOBAL_CONFIG *Config)
Definition ocvalidate.h:27
CONST CHAR8 * Child
Definition KextInfo.h:27
CONST CHAR8 * Parent
Definition KextInfo.h:28