23#include <Library/BaseLib.h>
24#include <Library/BaseMemoryLib.h>
25#include <Library/DebugLib.h>
34#include <Library/PrintLib.h>
35#include <Library/UefiBootServicesTableLib.h>
36#include <Library/UefiLib.h>
37#include <Library/UefiRuntimeServicesTableLib.h>
52 IN UINTN EstimatedKernelArea,
53 IN BOOLEAN HasSandyOrIvy,
68 *EndAddr = *StartAddr + EstimatedKernelArea;
87 if (SlideSupport->ValidSlideCount == 1) {
88 return SlideSupport->ValidSlides[0];
93 }
while (SlideSupport->ValidSlides[Slide] == 0);
95 return SlideSupport->ValidSlides[Slide];
112 IN UINT8 FallbackSlide,
113 IN UINT64 MaxAvailableSize
118 CHAR8 SlideList[256];
127 "OCABC: All slides are usable! You can disable ProvideCustomSlide!\n"
135 if (SlideSupport->ValidSlideCount == 0) {
138 "OCABC: No slide values are usable! Falling back to %u with 0x%08LX bytes!\n",
139 (UINT32)FallbackSlide,
142 SlideSupport->ValidSlides[SlideSupport->ValidSlideCount++] = (UINT8)FallbackSlide;
155 "OCABC: Only %u/%u slide values are usable!\n",
156 (UINT32)SlideSupport->ValidSlideCount,
163 for (Index = 0; Index <= SlideSupport->ValidSlideCount; ++Index) {
169 SlideSupport->ValidSlides[Index]
171 AsciiStrCatS (SlideList,
sizeof (SlideList), Temp);
172 }
else if ( (Index == SlideSupport->ValidSlideCount)
173 || (SlideSupport->ValidSlides[Index - 1] + 1 != SlideSupport->ValidSlides[Index]))
175 if (NumEntries == 1) {
180 SlideSupport->ValidSlides[Index - 1]
182 AsciiStrCatS (SlideList,
sizeof (SlideList), Temp);
183 }
else if (NumEntries > 1) {
188 SlideSupport->ValidSlides[Index - 1]
190 AsciiStrCatS (SlideList,
sizeof (SlideList), Temp);
193 if (Index != SlideSupport->ValidSlideCount) {
198 SlideSupport->ValidSlides[Index]
200 AsciiStrCatS (SlideList,
sizeof (SlideList), Temp);
209 DEBUG ((DEBUG_INFO,
"OCABC: %a\n", SlideList));
229 IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL,
231 IN VOID *FilterMapContext OPTIONAL,
232 IN BOOLEAN HasSandyOrIvy
235 EFI_PHYSICAL_ADDRESS AllocatedMapPages;
237 EFI_MEMORY_DESCRIPTOR *MemoryMap;
238 EFI_MEMORY_DESCRIPTOR *Desc;
241 UINTN DescriptorSize;
242 UINT32 DescriptorVersion;
246 UINT64 MaxAvailableSize;
251 EFI_PHYSICAL_ADDRESS DescEndAddr;
252 UINT64 AvailableSize;
254 MaxAvailableSize = 0;
257 if (SlideSupport->HasMemoryMapAnalysis) {
258 return SlideSupport->ValidSlideCount > 0
262 AllocatedMapPages = BASE_4GB;
273 if (EFI_ERROR (Status)) {
274 DEBUG ((DEBUG_WARN,
"OCABC: Failed to obtain memory map for KASLR - %r\n", Status));
278 if (FilterMap != NULL) {
279 FilterMap (FilterMapContext, MemoryMapSize, MemoryMap, DescriptorSize);
282 SlideSupport->HasSandyOrIvy = HasSandyOrIvy;
284 SlideSupport->EstimatedKernelArea = (UINTN)EFI_PAGES_TO_SIZE (
292 NumEntries = MemoryMapSize / DescriptorSize;
297 SlideSupport->ValidSlideCount = 0;
304 SlideSupport->EstimatedKernelArea,
305 SlideSupport->HasSandyOrIvy,
313 for (Index = 0; Index < NumEntries; ++Index) {
314 if (Desc->NumberOfPages == 0) {
320 if ((Desc->PhysicalStart < EndAddr) && (DescEndAddr > StartAddr)) {
324 if (Desc->Type != EfiConventionalMemory) {
334 AvailableSize += EFI_PAGES_TO_SIZE (Desc->NumberOfPages);
336 if (Desc->PhysicalStart < StartAddr) {
341 AvailableSize -= (StartAddr - Desc->PhysicalStart);
344 if (DescEndAddr > EndAddr) {
349 AvailableSize -= (DescEndAddr - EndAddr);
354 Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize);
357 if (AvailableSize > MaxAvailableSize) {
358 MaxAvailableSize = AvailableSize;
359 FallbackSlide = (UINT8)Slide;
366 if ((SlideSupport->ProvideMaxSlide > 0) && (Slide > SlideSupport->ProvideMaxSlide)) {
370 if ((StartAddr + AvailableSize) != EndAddr) {
378 SlideSupport->ValidSlides[SlideSupport->ValidSlideCount++] = (UINT8)Slide;
386 SlideSupport->HasMemoryMapAnalysis = TRUE;
389 (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryMap,
390 (UINTN)AllocatedMapPages
418 IN EFI_GET_VARIABLE GetVariable,
419 IN CHAR16 *VariableName,
420 IN EFI_GUID *VendorGuid,
421 OUT UINT32 *Attributes OPTIONAL,
422 IN OUT UINTN *DataSize,
432 if ((Data == NULL) || (*DataSize <
sizeof (UINT32))) {
433 *DataSize =
sizeof (UINT32);
434 return EFI_BUFFER_TOO_SMALL;
437 Config = (UINT32 *)Data;
442 Status = GetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);
443 if (EFI_ERROR (Status)) {
444 DEBUG ((DEBUG_INFO,
"OCABC: GetVariable csr-active-config - %r\n", Status));
447 Status = EFI_SUCCESS;
448 if (Attributes != NULL) {
450 EFI_VARIABLE_BOOTSERVICE_ACCESS |
451 EFI_VARIABLE_RUNTIME_ACCESS |
452 EFI_VARIABLE_NON_VOLATILE;
459 SlideSupport->CsrActiveConfig = *Config;
460 SlideSupport->HasCsrActiveConfig = TRUE;
484 IN EFI_GET_VARIABLE GetVariable,
485 IN CHAR16 *VariableName,
486 IN EFI_GUID *VendorGuid,
487 OUT UINT32 *Attributes OPTIONAL,
488 IN OUT UINTN *DataSize,
493 UINTN StoredBootArgsSize;
495 CHAR8 SlideArgument[10];
496 UINTN SlideArgumentLength;
499 SlideArgumentLength =
ARRAY_SIZE (SlideArgument) - 1;
501 if (!SlideSupport->HasBootArgs) {
507 Status = GetVariable (
512 SlideSupport->BootArgs
514 if (EFI_ERROR (Status)) {
515 SlideSupport->BootArgs[0] =
'\0';
522 AsciiSPrint (SlideArgument,
ARRAY_SIZE (SlideArgument),
"slide=%-03d", Slide);
529 SlideSupport->BootArgs,
530 SlideArgumentLength + 1,
532 SlideArgumentLength + 1
536 SlideSupport->BootArgsSize = AsciiStrLen (SlideSupport->BootArgs);
537 SlideSupport->HasBootArgs = TRUE;
542 EFI_VARIABLE_BOOTSERVICE_ACCESS |
543 EFI_VARIABLE_RUNTIME_ACCESS |
544 EFI_VARIABLE_NON_VOLATILE;
547 if ((*DataSize >= SlideSupport->BootArgsSize) && (Data != NULL)) {
550 SlideSupport->BootArgs,
551 SlideSupport->BootArgsSize
553 Status = EFI_SUCCESS;
555 Status = EFI_BUFFER_TOO_SMALL;
558 *DataSize = SlideSupport->BootArgsSize;
590 DTInit ((VOID *)(UINTN)(*BootArgs->DeviceTreeP), BootArgs->DeviceTreeLength);
592 if (!EFI_ERROR (Status)) {
593 Status =
DTGetProperty (Chosen,
"boot-args", (VOID **)&ArgsStr, &ArgsSize);
594 if (!EFI_ERROR (Status) && (ArgsSize > 0)) {
602 SlideSupport->ValidSlideCount = 0;
603 SlideSupport->BootArgsSize = 0;
604 SecureZeroMem (SlideSupport->ValidSlides, sizeof (SlideSupport->ValidSlides));
605 SecureZeroMem (SlideSupport->BootArgs, sizeof (SlideSupport->BootArgs));
610 IN OUT UINT8 *ImageBase,
646 STATIC CONST UINTN MaxDist = 0x10;
647 STATIC CONST UINT8 SearchSeqNew[] = { 0xF6, 0xC4, 0x40, 0x75 };
648 STATIC CONST UINT8 SearchSeqNew2[] = { 0x0F, 0xBA, 0xE0, 0x0E, 0x72 };
649 STATIC CONST UINT8 SearchSeqSur[] = { 0xF6, 0xC1, 0x01, 0x75 };
650 STATIC CONST UINT8 SearchSeqSur2[] = { 0xF6, 0xC1, 0x01, 0x74 };
651 STATIC CONST UINT8 SearchSeq[] = { 0x01, 0x40, 0x00, 0x00 };
657 UINTN SearchSeqNewSize;
662 StartOff = ImageBase;
663 EndOff = StartOff + ImageSize -
sizeof (SearchSeq) - MaxDist;
670 (CONST UINT8 *)
"macOS ",
679 for (FirstOff = 0; StartOff + FirstOff <= EndOff; ++FirstOff) {
680 if (
CompareMem (StartOff + FirstOff, SearchSeqSur,
sizeof (SearchSeqSur)) == 0) {
681 DEBUG ((DEBUG_INFO,
"OCABC: Patching safe mode sur-1 at off %X\n", (UINT32)FirstOff));
682 SetMem (StartOff + FirstOff,
sizeof (SearchSeqSur) + 1, 0x90);
686 if (
CompareMem (StartOff + FirstOff, SearchSeqSur2,
sizeof (SearchSeqSur2)) == 0) {
687 DEBUG ((DEBUG_INFO,
"OCABC: Patching safe mode sur-2 at off %X\n", (UINT32)FirstOff));
688 *(StartOff + FirstOff + 3) = 0xEB;
693 DEBUG ((DEBUG_INFO,
"OCABC: Failed to find safe mode sur sequence\n"));
703 while (StartOff + FirstOff <= EndOff) {
704 if ( (StartOff + FirstOff <= EndOff - 1)
705 && (
CompareMem (StartOff + FirstOff, SearchSeqNew2,
sizeof (SearchSeqNew2)) == 0))
707 SearchSeqNewSize =
sizeof (SearchSeqNew2);
712 if (
CompareMem (StartOff + FirstOff, SearchSeqNew,
sizeof (SearchSeqNew)) == 0) {
713 SearchSeqNewSize =
sizeof (SearchSeqNew);
718 if (
CompareMem (StartOff + FirstOff, SearchSeq,
sizeof (SearchSeq)) == 0) {
725 if (StartOff + FirstOff > EndOff) {
726 DEBUG ((DEBUG_INFO,
"OCABC: Failed to find safe mode sequence\n"));
734 DEBUG ((DEBUG_INFO,
"OCABC: Patching safe mode new at off %X\n", (UINT32)FirstOff));
735 SetMem (StartOff + FirstOff, SearchSeqNewSize + 1, 0x90);
739 DEBUG ((DEBUG_INFO,
"OCABC: Found safe mode legacy p1 at off %X\n", (UINT32)FirstOff));
741 SecondOff = FirstOff +
sizeof (SearchSeq);
744 StartOff + SecondOff <= EndOff && FirstOff + MaxDist >= SecondOff &&
745 CompareMem (StartOff + SecondOff, SearchSeq,
sizeof (SearchSeq)))
750 if (FirstOff + MaxDist < SecondOff) {
751 DEBUG ((DEBUG_INFO,
"OCABC: Trying safe mode next legacy match\n"));
753 FirstOff +=
sizeof (SearchSeq);
757 DEBUG ((DEBUG_INFO,
"OCABC: Found safe mode legacy p2 at off %X\n", (UINT32)SecondOff));
758 }
while (SecondOff == 0);
760 if (SecondOff != 0) {
766 DEBUG ((DEBUG_INFO,
"OCABC: Patching safe mode legacy\n"));
767 SetMem (StartOff + FirstOff,
sizeof (SearchSeq), 0xFF);
768 SetMem (StartOff + SecondOff,
sizeof (SearchSeq), 0xFF);
775 IN EFI_GET_VARIABLE GetVariable,
776 IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL,
778 IN VOID *FilterMapContext OPTIONAL,
779 IN CHAR16 *VariableName,
780 IN EFI_GUID *VendorGuid,
781 OUT UINT32 *Attributes OPTIONAL,
782 IN OUT UINTN *DataSize,
786 BootCompat->SlideSupport.ProvideMaxSlide = BootCompat->Settings.ProvideMaxSlide;
788 if ( (VariableName != NULL) && (VendorGuid != NULL) && (DataSize != NULL)
791 if (StrCmp (VariableName, L
"csr-active-config") == 0) {
799 &BootCompat->SlideSupport,
807 }
else if ( (StrCmp (VariableName, L
"boot-args") == 0)
808 && (!BootCompat->ServiceState.AppleCustomSlide || BootCompat->Settings.AllowRelocationBlock)
810 &BootCompat->SlideSupport,
834 &BootCompat->SlideSupport,
845 return GetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);
856 SlideSupport = &BootCompat->SlideSupport;
885 SlideSupport = &BootCompat->SlideSupport;
898 return BootCompat->SlideSupport.EstimatedKernelArea;
905 return BootCompat->SlideSupport.EstimatedKernelArea;
#define CSR_ALLOW_UNRESTRICTED_NVRAM
#define ARRAY_SIZE(Array)
EFI_GUID gAppleBootVariableGuid
#define SLIDE_ERRATA_SKIP_RANGE
#define SLIDE_GRANULARITY
#define KERNEL_BASE_PADDR
#define ESTIMATED_KERNEL_SIZE
VOID AppleSlideRestore(IN OUT BOOT_COMPAT_CONTEXT *BootCompat, IN OUT OC_BOOT_ARGUMENTS *BootArgs)
STATIC EFI_STATUS GetVariableCsrActiveConfig(IN OUT SLIDE_SUPPORT_STATE *SlideSupport, IN EFI_GET_VARIABLE GetVariable, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT UINT32 *Attributes OPTIONAL, IN OUT UINTN *DataSize, OUT VOID *Data)
STATIC UINT8 GenerateSlideValue(IN SLIDE_SUPPORT_STATE *SlideSupport)
VOID AppleSlideUnlockForSafeMode(IN OUT UINT8 *ImageBase, IN UINTN ImageSize)
STATIC VOID HideSlideFromOs(IN OUT SLIDE_SUPPORT_STATE *SlideSupport, IN OUT OC_BOOT_ARGUMENTS *BootArgs)
STATIC VOID GetSlideRangeForValue(IN UINTN EstimatedKernelArea, IN BOOLEAN HasSandyOrIvy, IN UINT8 Slide, OUT UINTN *StartAddr, OUT UINTN *EndAddr)
UINTN AppleSlideGetRelocationSize(IN OUT BOOT_COMPAT_CONTEXT *BootCompat)
STATIC BOOLEAN ShouldUseCustomSlideOffset(IN OUT SLIDE_SUPPORT_STATE *SlideSupport, IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, IN OC_MEMORY_FILTER FilterMap OPTIONAL, IN VOID *FilterMapContext OPTIONAL, IN BOOLEAN HasSandyOrIvy)
STATIC BOOLEAN ShouldUseCustomSlideOffsetDecision(IN OUT SLIDE_SUPPORT_STATE *SlideSupport, IN UINT8 FallbackSlide, IN UINT64 MaxAvailableSize)
EFI_STATUS AppleSlideGetVariable(IN OUT BOOT_COMPAT_CONTEXT *BootCompat, IN EFI_GET_VARIABLE GetVariable, IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, IN OC_MEMORY_FILTER FilterMap OPTIONAL, IN VOID *FilterMapContext OPTIONAL, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT UINT32 *Attributes OPTIONAL, IN OUT UINTN *DataSize, OUT VOID *Data)
STATIC EFI_STATUS GetVariableBootArgs(IN OUT SLIDE_SUPPORT_STATE *SlideSupport, IN EFI_GET_VARIABLE GetVariable, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT UINT32 *Attributes OPTIONAL, IN OUT UINTN *DataSize, OUT VOID *Data)
VOID OcRemoveArgumentFromCmd(IN OUT CHAR8 *CommandLine, IN CONST CHAR8 *Argument)
BOOLEAN OcAppendArgumentToCmd(IN OUT OC_PICKER_CONTEXT *Context OPTIONAL, IN OUT CHAR8 *CommandLine, IN CONST CHAR8 *Argument, IN CONST UINTN ArgumentLength)
@ OcCpuGenerationIvyBridge
@ OcCpuGenerationSandyBridge
VOID * SecureZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS DTLookupEntry(IN CONST DTEntry SearchPoint, IN CONST CHAR8 *PathName, IN DTEntry *FoundEntry)
VOID DTInit(IN VOID *Base, IN UINT32 *Length)
EFI_STATUS DTGetProperty(IN CONST DTEntry Entry, IN CHAR8 *PropertyName, IN VOID **PropertyValue, IN UINT32 *PropertySize)
EFI_STATUS OcGetCurrentMemoryMapAlloc(OUT UINTN *MemoryMapSize, OUT EFI_MEMORY_DESCRIPTOR **MemoryMap, OUT UINTN *MapKey, OUT UINTN *DescriptorSize, OUT UINT32 *DescriptorVersion, IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, IN OUT EFI_PHYSICAL_ADDRESS *TopMemory OPTIONAL)
#define LAST_DESCRIPTOR_ADDR(Desc)
UINT64 OcCountRuntimePages(IN UINTN MemoryMapSize, IN EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN DescriptorSize, OUT UINTN *DescriptorCount OPTIONAL)
VOID(* OC_MEMORY_FILTER)(IN VOID *Context OPTIONAL, IN UINTN MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN DescriptorSize)
BOOLEAN FindPattern(IN CONST UINT8 *Pattern, IN CONST UINT8 *PatternMask OPTIONAL, IN CONST UINT32 PatternSize, IN CONST UINT8 *Data, IN UINT32 DataSize, IN OUT UINT32 *DataOff)
UINT64 EFIAPI GetPseudoRandomNumber64(VOID)
#define L_STR_LEN(String)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
UINT8 ValidSlides[TOTAL_SLIDE_NUM]
BOOLEAN HasCsrActiveConfig
BOOLEAN HasMemoryMapAnalysis