提交 40b43134 编写于 作者: V vit9696

OcAppleBootCompatLib: Implement custom slide support

上级 89702161
......@@ -26,6 +26,7 @@ typedef struct OC_ABC_SETTINGS_ {
BOOLEAN SetupAppleMap;
///
/// Provide custom Apple KASLR slide calculation for firmwares with polluted low memory ranges.
/// This also ensures that slide= argument is never passed to the operating system.
///
BOOLEAN SetupAppleSlide;
///
......
......@@ -101,11 +101,21 @@ OcCpuCorrectFlexRatio (
@param[in] VersionEax CPUID (1) EAX value.
@return Apple Family (e.g. CPUFAMILY_UNKNOWN)
@retval Apple Family (e.g. CPUFAMILY_UNKNOWN)
**/
UINT32
OcCpuModelToAppleFamily (
IN CPUID_VERSION_INFO_EAX VersionEax
);
/**
Special Intel Sandy Bridge and Ivy Bridge detection code.
@retval TRUE when running with Sandy Bridge or Ivy Bridge CPU.
**/
BOOLEAN
OcIsSandyOrIvy (
VOID
);
#endif // OC_CPU_LIB_H_
......@@ -18,6 +18,32 @@
#include <Uefi.h>
#include <IndustryStandard/VirtualMemory.h>
/**
Reverse equivalent of NEXT_MEMORY_DESCRIPTOR.
**/
#define PREV_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
/**
Get last descriptor address.
It is assumed that the descriptor contains pages.
**/
#define LAST_DESCRIPTOR_ADDR(Desc) \
((Desc)->PhysicalStart + (EFI_PAGES_TO_SIZE ((UINTN) (Desc)->NumberOfPages) - 1))
/**
Check if area is within the specified descriptor.
It is assumed that the descriptor contains pages and AreaSize is not 0.
**/
#define AREA_WITHIN_DESCRIPTOR(Desc, Area, AreaSize) \
((Area) >= (Desc)->PhysicalStart && ((Area) + ((AreaSize) - 1)) <= LAST_DESCRIPTOR_ADDR (Desc))
/**
Reasonable default virtual memory page pool size (2 MB).
**/
#define OC_DEFAULT_VMEM_PAGE_COUNT 0x200
/**
Lock the legacy region specified to enable modification.
......@@ -138,6 +164,24 @@ AllocatePagesFromTop (
IN CHECK_ALLOCATION_RANGE CheckRange OPTIONAL
);
/**
Calculate number of runtime pages in the memory map.
@param[in] MemoryMapSize Memory map size in bytes.
@param[in] MemoryMap Memory map to inspect.
@param[in] DescriptorSize Memory map descriptor size in bytes.
@param[out] DescriptorCount Number of relevant descriptors, optional.
@retval Number of runtime pages.
**/
UINTN
CountRuntimePages (
IN UINTN MemoryMapSize,
IN EFI_MEMORY_DESCRIPTOR *MemoryMap,
IN UINTN DescriptorSize,
OUT UINTN *DescriptorCount OPTIONAL
);
/**
Return pointer to PML4 table in PageTable and PWT and PCD flags in Flags.
......@@ -180,11 +224,6 @@ typedef struct OC_VMEM_CONTEXT_ {
UINTN FreePages;
} OC_VMEM_CONTEXT;
/**
Reasonable default virtual memory page pool size (2 MB).
**/
#define OC_DEFAULT_VMEM_PAGE_COUNT 0x200
/**
Allocate EfiBootServicesData virtual memory pool from boot services
in the end of BASE_4GB of RAM. Should be called while boot services are
......
......@@ -16,9 +16,14 @@
#define BOOT_COMPAT_INTERNAL_H
#include <Uefi.h>
#include <IndustryStandard/AppleBootArgs.h>
#include <Library/OcAppleBootCompatLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcDebugLogLib.h>
#include <Library/OcMemoryLib.h>
#include <Protocol/LoadedImage.h>
#ifdef MDE_CPU_X64
......@@ -42,35 +47,42 @@
/**
Kernel __HIB segment virtual address.
**/
#define KERNEL_HIB_VADDR ((UINTN)0xFFFFFF8000100000ULL)
#define KERNEL_HIB_VADDR ((UINTN) 0xFFFFFF8000100000ULL)
/**
Kernel __TEXT segment virtual address.
**/
#define KERNEL_TEXT_VADDR ((UINTN)0xFFFFFF8000200000ULL)
#define KERNEL_TEXT_VADDR ((UINTN) 0xFFFFFF8000200000ULL)
/**
Kernel physical base address.
**/
#define KERNEL_BASE_PADDR (KERNEL_TEXT_VADDR - KERNEL_HIB_VADDR)
/**
Slide offset per slide entry
**/
#define SLIDE_GRANULARITY ((UINTN)0x200000)
#define SLIDE_GRANULARITY ((UINTN) 0x200000)
/**
Total possible number of KASLR slide offsets.
**/
#define TOTAL_SLIDE_NUM 256
#define TOTAL_SLIDE_NUM ((UINTN) 0x100)
/**
Get last descriptor address.
It is assumed that the descriptor contains pages.
Slide errate number to skip range from.
**/
#define LAST_DESCRIPTOR_ADDR(Desc) \
((Desc)->PhysicalStart + (EFI_PAGES_TO_SIZE ((UINTN) (Desc)->NumberOfPages) - 1))
#define SLIDE_ERRATA_NUM ((UINTN) 0x80)
/**
Check if area is within the specified descriptor.
It is assumed that the descriptor contains pages and AreaSize is not 0.
Sandy/Ivy skip slide range for Intel HD graphics.
**/
#define AREA_WITHIN_DESCRIPTOR(Desc, Area, AreaSize) \
((Area) >= (Desc)->PhysicalStart && ((Area) + ((AreaSize) - 1)) <= LAST_DESCRIPTOR_ADDR (Desc))
#define SLIDE_ERRATA_SKIP_RANGE ((UINTN) 0x10200000)
/**
Assume the kernel is roughly 128 MBs.
**/
#define ESTIMATED_KERNEL_SIZE ((UINTN) 0x8000000)
/**
Preserved relocation entry.
......@@ -220,6 +232,53 @@ typedef struct KERNEL_SUPPORT_STATE_ {
UINTN VmMapDescSize;
} KERNEL_SUPPORT_STATE;
/**
Apple booter KASLR slide support internal state.
**/
typedef struct SLIDE_SUPPORT_STATE_ {
///
/// Memory map analysis status determining slide usage.
///
BOOLEAN HasMemoryMapAnalysis;
///
/// TRUE if we are running on Intel Sandy or Ivy bridge.
///
BOOLEAN HasSandyOrIvy;
///
/// TRUE if CsrActiveConfig was set.
///
BOOLEAN HasCsrActiveConfig;
///
/// TRUE if BootArgs was set.
///
BOOLEAN HasBootArgs;
///
/// Read or assumed csr-arctive-config variable value.
///
UINT32 CsrActiveConfig;
///
/// Valid slides to choose from when using custom slide.
///
UINT8 ValidSlides[TOTAL_SLIDE_NUM];
///
/// Number of entries in ValidSlides.
///
UINT32 ValidSlideCount;
///
/// Apple kernel boot arguments read from boot-args variable and then
/// modified with an additional slide parameter in case custom slide is used.
///
CHAR8 BootArgs[BOOT_LINE_LENGTH];
///
/// BootArgs data size.
///
UINTN BootArgsSize;
///
/// Estimated size for kernel itself, device tree, memory map, and rt pages.
///
UINTN EstimatedKernelArea;
} SLIDE_SUPPORT_STATE;
/**
Apple Boot Compatibility context.
**/
......@@ -244,6 +303,10 @@ typedef struct BOOT_COMPAT_CONTEXT_ {
/// Apple kernel support internal state.
///
KERNEL_SUPPORT_STATE KernelState;
///
/// Apple booter KASLR slide support internal state.
///
SLIDE_SUPPORT_STATE SlideSupport;
} BOOT_COMPAT_CONTEXT;
/**
......@@ -350,4 +413,57 @@ AppleMapPrepareKernelState (
IN BOOLEAN ModeX64
);
/**
Patch boot.efi to support random and passed slide values in safe mode.
@param[in,out] ImageBase Apple booter image base.
@param[in] ImageSize Apple booter image size.
**/
VOID
AppleSlideUnlockForSafeMode (
IN OUT UINT8 *ImageBase,
IN UINTN ImageSize
);
/**
Primary custom KASLR support handler. This gets called on every
UEFI RuntimeServices GetVariable call and thus is useful to
perform KASLR slide injection through boot-args.
@param[in,out] BootCompat Boot compatibility context.
@param[in] GetVariable Original UEFI GetVariable service.
@param[in] GetMemoryMap Unmodified GetMemoryMap pointer, optional.
@param[in] VariableName GetVariable variable name argument.
@param[in] VendorGuid GetVariable vendor GUID argument.
@param[out] Attributes GetVariable attributes argument.
@param[in,out] DataSize GetVariable data size argument.
@param[out] Data GetVariable data argument.
@retval GetVariable status code.
**/
EFI_STATUS
AppleSlideGetVariable (
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
IN EFI_GET_VARIABLE GetVariable,
IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL,
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data
);
/**
Ensures that the original csr-active-config is passed to the kernel,
and removes customised slide value for security reasons.
@param[in,out] BootCompat Boot compatibility context.
@param[in,out] BootArgs Apple kernel boot arguments.
**/
VOID
AppleSlideRestore (
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
IN OUT OC_BOOT_ARGUMENTS *BootArgs
);
#endif // BOOT_COMPAT_INTERNAL_H
此差异已折叠。
......@@ -335,9 +335,9 @@ AppleMapPrepareForBooting (
OcParseBootArgs (&BA, BootArgs);
//
// FIXME: Restore the variables we tempered with to support custom slides.
// Restore the variables we tampered with to support custom slides.
//
// RestoreCustomSlideOverrides (&BA);
AppleSlideRestore (BootCompat, &BA);
MemoryMapSize = *BA.MemoryMapSize;
MemoryMap = (EFI_MEMORY_DESCRIPTOR *)(UINTN) (*BA.MemoryMap);
......@@ -401,6 +401,7 @@ AppleMapPrepareForHibernateWake (
if (BootCompat->Settings.DiscardAppleS4Map) {
//
// Route 1. Discard the new memory map here, and let XNU use what it had.
// It is unknown whether there still are any firmwares that need this.
//
Handoff->type = kIOHibernateHandoffType;
} else {
......@@ -521,7 +522,7 @@ AppleMapPrepareKernelJump (
// ImageAddress points to the first kernel segment, __HIB.
// Kernel image header is located in __TEXT, which follows __HIB.
//
ImageAddress += KERNEL_TEXT_VADDR - KERNEL_HIB_VADDR;
ImageAddress += KERNEL_BASE_PADDR;
//
// Cut higher virtual address bits.
......
......@@ -32,6 +32,7 @@
[Sources]
BootCompatInternal.h
CustomSlide.c
KernelSupport.c
OcAppleBootCompatLib.c
ServiceOverrides.c
......@@ -42,9 +43,10 @@
X64/ContextSwitchSupport.c
[Packages]
OcSupportPkg/OcSupportPkg.dec
MdePkg/MdePkg.dec
EfiPkg/EfiPkg.dec
MdePkg/MdePkg.dec
OcSupportPkg/OcSupportPkg.dec
UefiCpuPkg/UefiCpuPkg.dec
[Guids]
gAppleBootVariableGuid ## SOMETIMES_CONSUMES
......@@ -62,5 +64,8 @@
PrintLib
UefiBootServicesTableLib
UefiRuntimeServicesTableLib
OcCpuLib
OcDeviceTreeLib
OcGuardLib
OcMemoryLib
OcRngLib
......@@ -201,11 +201,10 @@ OcStartImage (
);
if (BootCompat->Settings.EnableAppleSmSlide) {
// FIXME: Implement.
//UnlockSlideSupportForSafeMode (
// (UINT8 *) AppleLoadedImage->ImageBase,
// AppleLoadedImage->ImageSize
// );
AppleSlideUnlockForSafeMode (
(UINT8 *) AppleLoadedImage->ImageBase,
AppleLoadedImage->ImageSize
);
}
if (BootCompat->Settings.SetupAppleMap) {
......@@ -493,10 +492,19 @@ OcGetVariable (
BootCompat = GetBootCompatContext ();
if (BootCompat->Settings.SetupAppleSlide) {
// FIXME: Implement
}
if (BootCompat->ServiceState.AppleBootNestedCount > 0
&& BootCompat->Settings.SetupAppleSlide) {
Status = AppleSlideGetVariable (
BootCompat,
BootCompat->ServicePtrs.GetVariable,
BootCompat->ServicePtrs.GetMemoryMap,
VariableName,
VendorGuid,
Attributes,
DataSize,
Data
);
} else {
Status = BootCompat->ServicePtrs.GetVariable (
VariableName,
VendorGuid,
......@@ -504,6 +512,7 @@ OcGetVariable (
DataSize,
Data
);
}
return Status;
}
......
......@@ -67,6 +67,11 @@ typedef PACKED struct ASM_KERNEL_JUMP_ {
#pragma pack(pop)
/**
Assembly interface to save UEFI environment state in specific way.
@param[in,out] AsmState Assembly state to update, can be preserved.
**/
VOID
EFIAPI
AsmAppleMapPlatformSaveState (
......
......@@ -34,6 +34,7 @@
#include <Library/UefiLib.h>
#include <ProcessorInfo.h>
#include <Register/Microcode.h>
#include <Register/Msr.h>
#include <Register/Msr/SandyBridgeMsr.h>
#include <Register/Msr/NehalemMsr.h>
......@@ -591,7 +592,7 @@ ScanIntelProcessor (
AppleMajorType = DetectAppleMajorType (Cpu->BrandString);
Cpu->AppleProcessorType = DetectAppleProcessorType (Cpu->Model, Cpu->Stepping, AppleMajorType);
DEBUG ((DEBUG_INFO, "Detected Apple Processor Type: %02X -> %04X\n", AppleMajorType, Cpu->AppleProcessorType));
DEBUG ((DEBUG_INFO, "OCCPU: Detected Apple Processor Type: %02X -> %04X\n", AppleMajorType, Cpu->AppleProcessorType));
if ((Cpu->Family != 0x06 || Cpu->Model < 0x0c)
&& (Cpu->Family != 0x0f || Cpu->Model < 0x03)) {
......@@ -637,7 +638,7 @@ ScanIntelProcessor (
DEBUG ((
DEBUG_INFO,
"Ratio Min %d Max %d Current %d Turbo %d %d %d %d\n",
"OCCPU: Ratio Min %d Max %d Current %d Turbo %d %d %d %d\n",
Cpu->MinBusRatio,
Cpu->MaxBusRatio,
Cpu->CurBusRatio,
......@@ -658,7 +659,7 @@ ScanIntelProcessor (
DEBUG ((
DEBUG_INFO,
"%a %a %11lld %5dMHz %u * %u / %u = %ld\n",
"OCCPU: %a %a %11lld %5dMHz %u * %u / %u = %ld\n",
"ART",
"Frequency",
Cpu->CPUFrequency,
......@@ -918,11 +919,11 @@ OcCpuScanProcessor (
}
}
DEBUG ((DEBUG_INFO, "%a %a\n", "Found", Cpu->BrandString));
DEBUG ((DEBUG_INFO, "OCCPU: %a %a\n", "Found", Cpu->BrandString));
DEBUG ((
DEBUG_INFO,
"Signature %0X Stepping %0X Model %0X Family %0X Type %0X ExtModel %0X ExtFamily %0X\n",
"OCCPU: Signature %0X Stepping %0X Model %0X Family %0X Type %0X ExtModel %0X ExtFamily %0X\n",
Cpu->Signature,
Cpu->Stepping,
Cpu->Model,
......@@ -943,7 +944,7 @@ OcCpuScanProcessor (
DEBUG ((
DEBUG_INFO,
"%a %a %11lld %5dMHz\n",
"OCCPU: %a %a %11lld %5dMHz\n",
"TSC",
"Frequency",
Cpu->TSCFrequency,
......@@ -952,7 +953,7 @@ OcCpuScanProcessor (
DEBUG ((
DEBUG_INFO,
"%a %a %11lld %5dMHz\n",
"OCCPU: %a %a %11lld %5dMHz\n",
"CPU",
"Frequency",
Cpu->CPUFrequency,
......@@ -961,7 +962,7 @@ OcCpuScanProcessor (
DEBUG ((
DEBUG_INFO,
"%a %a %11lld %5dMHz\n",
"OCCPU: %a %a %11lld %5dMHz\n",
"FSB",
"Frequency",
Cpu->FSBFrequency,
......@@ -970,7 +971,7 @@ OcCpuScanProcessor (
DEBUG ((
DEBUG_INFO,
"Pkg %u Cores %u Threads %u\n",
"OCCPU: Pkg %u Cores %u Threads %u\n",
Cpu->PackageCount,
Cpu->CoreCount,
Cpu->ThreadCount
......@@ -1056,3 +1057,40 @@ OcCpuModelToAppleFamily (
return CPUFAMILY_UNKNOWN;
}
}
BOOLEAN
OcIsSandyOrIvy (
VOID
)
{
CPU_MICROCODE_PROCESSOR_SIGNATURE Sig;
BOOLEAN SandyOrIvy;
UINT32 CpuFamily;
UINT32 CpuModel;
Sig.Uint32 = 0;
AsmCpuid (1, &Sig.Uint32, NULL, NULL, NULL);
CpuFamily = Sig.Bits.Family;
if (CpuFamily == 15) {
CpuFamily += Sig.Bits.ExtendedFamily;
}
CpuModel = Sig.Bits.Model;
if (CpuFamily == 15 || CpuFamily == 6) {
CpuModel |= Sig.Bits.ExtendedModel << 4;
}
SandyOrIvy = CpuFamily == 6 && (CpuModel == 0x2A || CpuModel == 0x3A);
DEBUG ((
DEBUG_VERBOSE,
"OCCPU: Discovered CpuFamily %d CpuModel %d SandyOrIvy %d\n",
CpuFamily,
CpuModel,
SandyOrIvy
));
return SandyOrIvy;
}
......@@ -22,12 +22,6 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
/**
* Reverse equivalent of NEXT_MEMORY_DESCRIPTOR.
*/
#define PREV_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
EFI_MEMORY_DESCRIPTOR *
GetCurrentMemoryMap (
OUT UINTN *MemoryMapSize,
......@@ -347,3 +341,39 @@ AllocatePagesFromTop (
return Status;
}
UINTN
CountRuntimePages (
IN UINTN MemoryMapSize,
IN EFI_MEMORY_DESCRIPTOR *MemoryMap,
IN UINTN DescriptorSize,
OUT UINTN *DescriptorCount OPTIONAL
)
{
UINTN DescNum;
UINTN PageNum;
UINTN NumEntries;
UINTN Index;
EFI_MEMORY_DESCRIPTOR *Desc;
DescNum = 0;
PageNum = 0;
NumEntries = MemoryMapSize / DescriptorSize;
Desc = MemoryMap;
for (Index = 0; Index < NumEntries; ++Index) {
if (Desc->Type != EfiReservedMemoryType
&& (Desc->Attribute & EFI_MEMORY_RUNTIME) != 0) {
++DescNum;
PageNum += Desc->NumberOfPages;
}
Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize);
}
if (DescriptorCount != NULL) {
*DescriptorCount = DescNum;
}
return PageNum;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册