mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
OcAppleKernelLib: Implement cacheless & mkext kext patching and quirks (#102)
This commit is contained in:
parent
9a0f1bc12c
commit
04fa1c2394
@ -275,7 +275,7 @@ typedef struct {
|
||||
//
|
||||
typedef struct {
|
||||
//
|
||||
// Comment or NULL (0 base is used then).
|
||||
// Comment or NULL.
|
||||
//
|
||||
CONST CHAR8 *Comment;
|
||||
//
|
||||
@ -329,14 +329,18 @@ typedef struct {
|
||||
//
|
||||
CONST CHAR16 *ExtensionsDirFileName;
|
||||
//
|
||||
// Injected kext list.
|
||||
// List of injected kexts.
|
||||
//
|
||||
LIST_ENTRY InjectedKexts;
|
||||
//
|
||||
// Dependency bundle list for injected kexts.
|
||||
// List of dependencies that need to be injected.
|
||||
//
|
||||
LIST_ENTRY InjectedDependencies;
|
||||
//
|
||||
// List of kext patches for built-in shipping kexts.
|
||||
//
|
||||
LIST_ENTRY PatchedKexts;
|
||||
//
|
||||
// List of built-in shipping kexts.
|
||||
//
|
||||
LIST_ENTRY BuiltInKexts;
|
||||
@ -400,8 +404,121 @@ typedef struct {
|
||||
// Array of kexts.
|
||||
//
|
||||
XML_NODE *MkextKexts;
|
||||
//
|
||||
// List of cached kexts, used for patching and blocking.
|
||||
//
|
||||
LIST_ENTRY CachedKexts;
|
||||
} MKEXT_CONTEXT;
|
||||
|
||||
//
|
||||
// Kernel quirk names.
|
||||
//
|
||||
typedef enum {
|
||||
//
|
||||
// Apply MSR E2 patches to AppleIntelCPUPowerManagement kext.
|
||||
//
|
||||
KernelQuirkAppleCpuPmCfgLock,
|
||||
//
|
||||
// Apply MSR E2 patches to XNU kernel (XCPM).
|
||||
//
|
||||
KernelQuirkAppleXcpmCfgLock,
|
||||
//
|
||||
// Apply extra MSR patches to XNU kernel (XCPM).
|
||||
//
|
||||
KernelQuirkAppleXcpmExtraMsrs,
|
||||
//
|
||||
// Apply max MSR_IA32_PERF_CONTROL patches to XNU kernel (XCPM).
|
||||
//
|
||||
KernelQuirkAppleXcpmForceBoost,
|
||||
//
|
||||
// Apply custom AppleSMBIOS kext GUID patch for Custom UpdateSMBIOSMode.
|
||||
//
|
||||
KernelQuirkCustomSmbiosGuid1,
|
||||
KernelQuirkCustomSmbiosGuid2,
|
||||
//
|
||||
// Apply VT-d disabling patches to IOPCIFamily kext to disable IOMapper in macOS.
|
||||
//
|
||||
KernelQuirkDisableIoMapper,
|
||||
//
|
||||
// Disable AppleRTC checksum writing.
|
||||
//
|
||||
KernelQuirkDisableRtcChecksum,
|
||||
//
|
||||
// Apply dummy power management patches to AppleIntelCpuPowerManagement in macOS.
|
||||
//
|
||||
KernelQuirkDummyPowerManagement,
|
||||
//
|
||||
// Apply icon type patches to IOAHCIPort kext to force internal disk icons.
|
||||
//
|
||||
KernelQuirkExternalDiskIcons,
|
||||
//
|
||||
// Apply PCI bar size patches to IOPCIFamily kext for compatibility with select configuration.
|
||||
//
|
||||
KernelQuirkIncreasePciBarSize,
|
||||
//
|
||||
// Disable LAPIC interrupt kernel panic on AP cores.
|
||||
//
|
||||
KernelQuirkLapicKernelPanic,
|
||||
//
|
||||
// Apply kernel patches to remove kext dumping in the panic log.
|
||||
//
|
||||
KernelQuirkPanicNoKextDump,
|
||||
//
|
||||
// Disable power state change timeout kernel panic (10.15+).
|
||||
//
|
||||
KernelQuirkPowerTimeoutKernelPanic,
|
||||
//
|
||||
// Apply vendor patches to IOAHCIFamily kext to enable native features for third-party drives,
|
||||
// such as TRIM on SSDs or hibernation support on 10.15.
|
||||
//
|
||||
KernelQuirkThirdPartyDrives,
|
||||
//
|
||||
// Apply port limit patches to AppleUSBXHCI and AppleUSBXHCIPCI kexts.
|
||||
//
|
||||
KernelQuirkXhciPortLimit1,
|
||||
KernelQuirkXhciPortLimit2,
|
||||
KernelQuirkXhciPortLimit3,
|
||||
|
||||
KernelQuirkMax
|
||||
} KERNEL_QUIRK_NAME;
|
||||
|
||||
//
|
||||
// Kernel quirk patch function.
|
||||
//
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(KERNEL_QUIRK_PATCH_FUNCTION)(
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
);
|
||||
|
||||
//
|
||||
// Kernel quirk.
|
||||
//
|
||||
typedef struct {
|
||||
//
|
||||
// Target bundle ID. NULL for kernel.
|
||||
//
|
||||
CONST CHAR8 *BundleId;
|
||||
//
|
||||
// Quirk patch function.
|
||||
//
|
||||
KERNEL_QUIRK_PATCH_FUNCTION *PatchFunction;
|
||||
} KERNEL_QUIRK;
|
||||
|
||||
/**
|
||||
Applies the specified quirk.
|
||||
|
||||
@param[in] Name KERNEL_QUIRK_NAME specifying the quirk name.
|
||||
@param[in,out] Patcher PATCHER_CONTEXT instance.
|
||||
|
||||
@returns EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
KernelQuirkApply (
|
||||
IN KERNEL_QUIRK_NAME Name,
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
);
|
||||
|
||||
/**
|
||||
Read Apple kernel for target architecture (possibly decompressing)
|
||||
into pool allocated buffer.
|
||||
@ -587,6 +704,36 @@ PrelinkedInjectKext (
|
||||
IN UINT32 ExecutableSize OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Apply kext patch to prelinked.
|
||||
|
||||
@param[in,out] Context Prelinked context.
|
||||
@param[in] BundleId Kext bundle ID.
|
||||
@param[in] Patch Patch to apply.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PrelinkedContextApplyPatch (
|
||||
IN OUT PRELINKED_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId,
|
||||
IN PATCHER_GENERIC_PATCH *Patch
|
||||
);
|
||||
|
||||
/**
|
||||
Apply kext quirk to prelinked.
|
||||
|
||||
@param[in,out] Context Prelinked context.
|
||||
@param[in] Quirk Kext quirk to apply.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PrelinkedContextApplyQuirk (
|
||||
IN OUT PRELINKED_CONTEXT *Context,
|
||||
IN KERNEL_QUIRK_NAME Quirk
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
KcRebuildMachHeader (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
@ -681,6 +828,22 @@ PatcherInitContextFromPrelinked (
|
||||
IN CONST CHAR8 *Name
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize patcher from mkext context for kext patching.
|
||||
|
||||
@param[in,out] Context Patcher context.
|
||||
@param[in,out] Mkext Mkext context.
|
||||
@param[in] Name Kext bundle identifier.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatcherInitContextFromMkext(
|
||||
IN OUT PATCHER_CONTEXT *Context,
|
||||
IN OUT MKEXT_CONTEXT *Mkext,
|
||||
IN CONST CHAR8 *Name
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize patcher from buffer for e.g. kernel patching.
|
||||
|
||||
@ -739,127 +902,6 @@ PatcherBlockKext (
|
||||
IN OUT PATCHER_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply MSR E2 patches to AppleIntelCPUPowerManagement kext.
|
||||
|
||||
@param Context Prelinked kernel context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchAppleCpuPmCfgLock (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply MSR E2 patches to XNU kernel (XCPM).
|
||||
|
||||
@param Patcher Patcher context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchAppleXcpmCfgLock (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
);
|
||||
|
||||
/**
|
||||
Apply extra MSR patches to XNU kernel (XCPM).
|
||||
|
||||
@param Patcher Patcher context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchAppleXcpmExtraMsrs (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
);
|
||||
|
||||
/**
|
||||
Apply max MSR_IA32_PERF_CONTROL patches to XNU kernel (XCPM).
|
||||
|
||||
@param Patcher Patcher context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchAppleXcpmForceBoost (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
);
|
||||
|
||||
/**
|
||||
Apply port limit patches to AppleUSBXHCI and AppleUSBXHCIPCI kexts.
|
||||
|
||||
@param Context Prelinked kernel context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchUsbXhciPortLimit (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply vendor patches to IOAHCIFamily kext to enable native features for third-party drives,
|
||||
such as TRIM on SSDs or hibernation support on 10.15.
|
||||
|
||||
@param Context Prelinked kernel context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchThirdPartyDriveSupport (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply icon type patches to IOAHCIPort kext to force internal disk icons.
|
||||
|
||||
@param Context Prelinked kernel context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchForceInternalDiskIcons (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply VT-d disabling patches to IOPCIFamily kext to disable IOMapper in macOS.
|
||||
|
||||
@param Context Prelinked kernel context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchAppleIoMapperSupport (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply dummy power management patches to AppleIntelCpuPowerManagement in macOS.
|
||||
|
||||
@param Context Prelinked kernel context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchDummyPowerManagement (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply PCI bar size patches to IOPCIFamily kext for compatibility with select configuration.
|
||||
|
||||
@param Context Prelinked kernel context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchIncreasePciBarSize (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply modification to CPUID 1.
|
||||
|
||||
@ -878,66 +920,6 @@ PatchKernelCpuId (
|
||||
IN UINT32 *DataMask
|
||||
);
|
||||
|
||||
/**
|
||||
Apply custom AppleSMBIOS kext GUID patch for Custom UpdateSMBIOSMode.
|
||||
|
||||
@param Context Prelinked kernel context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchCustomSmbiosGuid (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Apply kernel patches to remove kext dumping in the panic log.
|
||||
|
||||
@param Patcher Patcher context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchPanicKextDump (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
);
|
||||
|
||||
/**
|
||||
Disable LAPIC interrupt kernel panic on AP cores.
|
||||
|
||||
@param Patcher Patcher context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchLapicKernelPanic (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
);
|
||||
|
||||
/**
|
||||
Disable power state change timeout kernel panic (10.15+).
|
||||
|
||||
@param Patcher Patcher context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchPowerStateTimeout (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
);
|
||||
|
||||
/**
|
||||
Disable AppleRTC checksum writing.
|
||||
|
||||
@param Context Patcher context.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
PatchAppleRtcChecksum (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Initializes cacheless context for later modification.
|
||||
Must be freed with CachelessContextFree on success.
|
||||
@ -987,6 +969,36 @@ CachelessContextAddKext (
|
||||
IN UINT32 ExecutableSize OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Add patch to cacheless context to be applied later on.
|
||||
|
||||
@param[in,out] Context Cacheless context.
|
||||
@param[in] BundleId Kext bundle ID.
|
||||
@param[in] Patch Patch to apply.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
CachelessContextAddPatch (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId,
|
||||
IN PATCHER_GENERIC_PATCH *Patch
|
||||
);
|
||||
|
||||
/**
|
||||
Add kernel quirk to cacheless context to be applied later on.
|
||||
|
||||
@param[in,out] Context Cacheless context.
|
||||
@param[in] Quirk Quirk to apply.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
CachelessContextAddQuirk (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
IN KERNEL_QUIRK_NAME Quirk
|
||||
);
|
||||
|
||||
/**
|
||||
Creates virtual directory overlay EFI_FILE_PROTOCOL from cacheless context.
|
||||
|
||||
@ -1151,6 +1163,36 @@ MkextInjectKext (
|
||||
IN UINT32 ExecutableSize OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Apply kext patch to mkext.
|
||||
|
||||
@param[in,out] Context Mkext context.
|
||||
@param[in] BundleId Kext bundle ID.
|
||||
@param[in] Patch Patch to apply.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
MkextContextApplyPatch (
|
||||
IN OUT MKEXT_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId,
|
||||
IN PATCHER_GENERIC_PATCH *Patch
|
||||
);
|
||||
|
||||
/**
|
||||
Apply kext quirk to mkext.
|
||||
|
||||
@param[in,out] Context Mkext context.
|
||||
@param[in] Quirk Kext quirk to apply.
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
MkextContextApplyQuirk (
|
||||
IN OUT MKEXT_CONTEXT *Context,
|
||||
IN KERNEL_QUIRK_NAME Quirk
|
||||
);
|
||||
|
||||
/**
|
||||
Refresh plist and checksum after kext
|
||||
injection and/or patching.
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include <Library/OcVirtualFsLib.h>
|
||||
|
||||
#include "CachelessInternal.h"
|
||||
#include "PrelinkedInternal.h"
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
@ -46,6 +47,9 @@ FreeBuiltInKext (
|
||||
if (BuiltinKext->BinaryFileName != NULL) {
|
||||
FreePool (BuiltinKext->BinaryFileName);
|
||||
}
|
||||
if (BuiltinKext->BinaryPath != NULL) {
|
||||
FreePool (BuiltinKext->BinaryPath);
|
||||
}
|
||||
|
||||
while (!IsListEmpty (&BuiltinKext->Dependencies)) {
|
||||
KextLink = GetFirstNode (&BuiltinKext->Dependencies);
|
||||
@ -298,6 +302,9 @@ ScanExtensions (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Create plist path.
|
||||
//
|
||||
Status = OcUnicodeSafeSPrint (
|
||||
TmpPath,
|
||||
sizeof (TmpPath),
|
||||
@ -323,13 +330,44 @@ ScanExtensions (
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Create binary path. If plist is in root of kext, binary is also there.
|
||||
//
|
||||
if (BuiltinKext->BinaryFileName != NULL) {
|
||||
Status = OcUnicodeSafeSPrint (
|
||||
TmpPath,
|
||||
sizeof (TmpPath),
|
||||
L"%s\\%s\\%s%s",
|
||||
FilePath,
|
||||
FileInfo->FileName,
|
||||
UseContents ? L"Contents\\MacOS\\" : L"\\",
|
||||
BuiltinKext->BinaryFileName
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreeBuiltInKext (BuiltinKext);
|
||||
FileKext->Close (FileKext);
|
||||
File->SetPosition (File, 0);
|
||||
FreePool (FileInfo);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
BuiltinKext->BinaryPath = AllocateCopyPool (StrSize (TmpPath), TmpPath);
|
||||
if (BuiltinKext->BinaryPath == NULL) {
|
||||
FreeBuiltInKext (BuiltinKext);
|
||||
FileKext->Close (FileKext);
|
||||
File->SetPosition (File, 0);
|
||||
FreePool (FileInfo);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
InsertTailList (&Context->BuiltInKexts, &BuiltinKext->Link);
|
||||
DEBUG ((
|
||||
DEBUG_VERBOSE,
|
||||
"OCAK: Discovered bundle %a %s %s %u\n",
|
||||
BuiltinKext->BundleId,
|
||||
BuiltinKext->BinaryFileName,
|
||||
BuiltinKext->PlistPath,
|
||||
BuiltinKext->BinaryPath,
|
||||
BuiltinKext->OSBundleRequiredValue
|
||||
));
|
||||
|
||||
@ -376,6 +414,30 @@ ScanExtensions (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
PATCHED_KEXT*
|
||||
LookupPatchedKextForBundleId (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId
|
||||
)
|
||||
{
|
||||
PATCHED_KEXT *PatchedKext;
|
||||
LIST_ENTRY *KextLink;
|
||||
|
||||
KextLink = GetFirstNode (&Context->PatchedKexts);
|
||||
while (!IsNull (&Context->PatchedKexts, KextLink)) {
|
||||
PatchedKext = GET_PATCHED_KEXT_FROM_LINK (KextLink);
|
||||
|
||||
if (AsciiStrCmp (BundleId, PatchedKext->BundleId) == 0) {
|
||||
return PatchedKext;
|
||||
}
|
||||
|
||||
KextLink = GetNextNode (&Context->PatchedKexts, KextLink);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC
|
||||
BUILTIN_KEXT*
|
||||
LookupBuiltinKextForBundleId (
|
||||
@ -424,6 +486,31 @@ LookupBuiltinKextForPlistPath (
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC
|
||||
BUILTIN_KEXT*
|
||||
LookupBuiltinKextForBinaryPath (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
IN CONST CHAR16 *BinaryPath
|
||||
)
|
||||
{
|
||||
BUILTIN_KEXT *BuiltinKext;
|
||||
LIST_ENTRY *KextLink;
|
||||
|
||||
KextLink = GetFirstNode (&Context->BuiltInKexts);
|
||||
while (!IsNull (&Context->BuiltInKexts, KextLink)) {
|
||||
BuiltinKext = GET_BUILTIN_KEXT_FROM_LINK (KextLink);
|
||||
|
||||
if (BuiltinKext->BinaryPath != NULL
|
||||
&& StrCmp (BinaryPath, BuiltinKext->BinaryPath) == 0) {
|
||||
return BuiltinKext;
|
||||
}
|
||||
|
||||
KextLink = GetNextNode (&Context->BuiltInKexts, KextLink);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
ScanDependencies (
|
||||
@ -492,6 +579,72 @@ ScanDependencies (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalAddKextPatch (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId,
|
||||
IN PATCHER_GENERIC_PATCH *Patch OPTIONAL,
|
||||
IN KERNEL_QUIRK_NAME QuirkName
|
||||
)
|
||||
{
|
||||
PATCHED_KEXT *PatchedKext;
|
||||
KEXT_PATCH *KextPatch;
|
||||
KERNEL_QUIRK *KernelQuirk;
|
||||
|
||||
if (Patch == NULL) {
|
||||
KernelQuirk = &gKernelQuirks[QuirkName];
|
||||
ASSERT (KernelQuirk->BundleId != NULL);
|
||||
|
||||
BundleId = KernelQuirk->BundleId;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if bundle is already present. If not, add to list.
|
||||
//
|
||||
PatchedKext = LookupPatchedKextForBundleId (Context, BundleId);
|
||||
if (PatchedKext == NULL) {
|
||||
PatchedKext = AllocateZeroPool (sizeof (*PatchedKext));
|
||||
if (PatchedKext == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
PatchedKext->Signature = PATCHED_KEXT_SIGNATURE;
|
||||
PatchedKext->BundleId = AllocateCopyPool (AsciiStrSize (BundleId), BundleId);
|
||||
if (PatchedKext->BundleId == NULL) {
|
||||
FreePool (PatchedKext);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
InitializeListHead (&PatchedKext->Patches);
|
||||
|
||||
InsertTailList (&Context->PatchedKexts, &PatchedKext->Link);
|
||||
}
|
||||
|
||||
//
|
||||
// Add new patch.
|
||||
//
|
||||
KextPatch = AllocateZeroPool (sizeof (*KextPatch));
|
||||
if (KextPatch == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
KextPatch->Signature = KEXT_PATCH_SIGNATURE;
|
||||
|
||||
if (Patch != NULL) {
|
||||
CopyMem (&KextPatch->Patch, Patch, sizeof (KextPatch->Patch));
|
||||
|
||||
} else {
|
||||
//
|
||||
// Apply quirk if no Patch.
|
||||
//
|
||||
KextPatch->ApplyQuirk = TRUE;
|
||||
KextPatch->QuirkName = QuirkName;
|
||||
}
|
||||
|
||||
InsertTailList (&PatchedKext->Patches, &KextPatch->Link);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
CachelessContextInit (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
@ -510,6 +663,7 @@ CachelessContextInit (
|
||||
|
||||
InitializeListHead (&Context->InjectedKexts);
|
||||
InitializeListHead (&Context->InjectedDependencies);
|
||||
InitializeListHead (&Context->PatchedKexts);
|
||||
InitializeListHead (&Context->BuiltInKexts);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@ -520,9 +674,12 @@ CachelessContextFree (
|
||||
IN OUT CACHELESS_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
CACHELESS_KEXT *CachelessKext;
|
||||
BUILTIN_KEXT *BuiltinKext;
|
||||
LIST_ENTRY *KextLink;
|
||||
CACHELESS_KEXT *CachelessKext;
|
||||
PATCHED_KEXT *PatchedKext;
|
||||
KEXT_PATCH *KextPatch;
|
||||
BUILTIN_KEXT *BuiltinKext;
|
||||
LIST_ENTRY *KextLink;
|
||||
LIST_ENTRY *PatchLink;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
|
||||
@ -543,6 +700,22 @@ CachelessContextFree (
|
||||
FreePool (CachelessKext);
|
||||
}
|
||||
|
||||
while (!IsListEmpty (&Context->PatchedKexts)) {
|
||||
KextLink = GetFirstNode (&Context->PatchedKexts);
|
||||
PatchedKext = GET_PATCHED_KEXT_FROM_LINK (KextLink);
|
||||
RemoveEntryList (KextLink);
|
||||
|
||||
while (!IsListEmpty (&PatchedKext->Patches)) {
|
||||
PatchLink = GetFirstNode (&PatchedKext->Patches);
|
||||
KextPatch = GET_KEXT_PATCH_FROM_LINK (PatchLink);
|
||||
RemoveEntryList (PatchLink);
|
||||
|
||||
FreePool (KextPatch);
|
||||
}
|
||||
|
||||
FreePool (PatchedKext);
|
||||
}
|
||||
|
||||
while (!IsListEmpty (&Context->BuiltInKexts)) {
|
||||
KextLink = GetFirstNode (&Context->BuiltInKexts);
|
||||
BuiltinKext = GET_BUILTIN_KEXT_FROM_LINK (KextLink);
|
||||
@ -759,6 +932,31 @@ CachelessContextAddKext (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
CachelessContextAddPatch (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId,
|
||||
IN PATCHER_GENERIC_PATCH *Patch
|
||||
)
|
||||
{
|
||||
ASSERT (Context != NULL);
|
||||
ASSERT (BundleId != NULL);
|
||||
ASSERT (Patch != NULL);
|
||||
|
||||
return InternalAddKextPatch (Context, BundleId, Patch, 0);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
CachelessContextAddQuirk (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
IN KERNEL_QUIRK_NAME Quirk
|
||||
)
|
||||
{
|
||||
ASSERT (Context != NULL);
|
||||
|
||||
return InternalAddKextPatch (Context, NULL, NULL, Quirk);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
CachelessContextOverlayExtensionsDir (
|
||||
IN OUT CACHELESS_CONTEXT *Context,
|
||||
@ -1012,12 +1210,17 @@ CachelessContextHookBuiltin (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_TIME ModificationTime;
|
||||
BUILTIN_KEXT *BuiltinKext;
|
||||
KEXT_PATCH *KextPatch;
|
||||
PATCHED_KEXT *PatchedKext;
|
||||
DEPEND_KEXT *DependKext;
|
||||
LIST_ENTRY *KextLink;
|
||||
|
||||
CHAR8 *InfoPlist;
|
||||
UINT32 InfoPlistSize;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
VOID *Buffer;
|
||||
UINT32 BufferSize;
|
||||
XML_DOCUMENT *InfoPlistDocument;
|
||||
XML_NODE *InfoPlistRoot;
|
||||
XML_NODE *InfoPlistValue;
|
||||
@ -1048,6 +1251,31 @@ CachelessContextHookBuiltin (
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure all kexts to be patched will be loaded.
|
||||
//
|
||||
KextLink = GetFirstNode (&Context->PatchedKexts);
|
||||
while (!IsNull (&Context->PatchedKexts, KextLink)) {
|
||||
PatchedKext = GET_PATCHED_KEXT_FROM_LINK (KextLink);
|
||||
|
||||
BuiltinKext = LookupBuiltinKextForBundleId (Context, PatchedKext->BundleId);
|
||||
if (BuiltinKext == NULL) {
|
||||
//
|
||||
// Kext is not present, skip.
|
||||
//
|
||||
DEBUG ((DEBUG_WARN, "OCAK: Attempted to patch non-existent kext %a\n", PatchedKext->BundleId));
|
||||
|
||||
} else {
|
||||
BuiltinKext->PatchKext = TRUE;
|
||||
Status = ScanDependencies (Context, PatchedKext->BundleId);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
KextLink = GetNextNode (&Context->PatchedKexts, KextLink);
|
||||
}
|
||||
|
||||
//
|
||||
// Scan dependencies, adding any others besides ones being injected.
|
||||
//
|
||||
@ -1066,31 +1294,31 @@ CachelessContextHookBuiltin (
|
||||
}
|
||||
|
||||
//
|
||||
// Info.plist.
|
||||
// Try to get Info.plist.
|
||||
//
|
||||
if (OcUnicodeEndsWith (FileName, L"Info.plist")) {
|
||||
BuiltinKext = LookupBuiltinKextForPlistPath (Context, FileName);
|
||||
if (BuiltinKext != NULL && BuiltinKext->PatchValidOSBundleRequired) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Processing patches for %s\n", FileName));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Processing plist patches for %s\n", FileName));
|
||||
|
||||
//
|
||||
// Open Info.plist
|
||||
//
|
||||
Status = AllocateCopyFileData (File, (UINT8**)&InfoPlist, &InfoPlistSize);
|
||||
Status = AllocateCopyFileData (File, (UINT8 **) &Buffer, &BufferSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
InfoPlistDocument = XmlDocumentParse (InfoPlist, InfoPlistSize, FALSE);
|
||||
InfoPlistDocument = XmlDocumentParse (Buffer, BufferSize, FALSE);
|
||||
if (InfoPlistDocument == NULL) {
|
||||
FreePool (InfoPlist);
|
||||
FreePool (Buffer);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
InfoPlistRoot = PlistNodeCast (PlistDocumentRoot (InfoPlistDocument), PLIST_NODE_TYPE_DICT);
|
||||
if (InfoPlistRoot == NULL) {
|
||||
XmlDocumentFree (InfoPlistDocument);
|
||||
FreePool (InfoPlist);
|
||||
FreePool (Buffer);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@ -1117,7 +1345,7 @@ CachelessContextHookBuiltin (
|
||||
Failed |= XmlNodeAppend (InfoPlistRoot, "string", NULL, OS_BUNDLE_REQUIRED_ROOT) == NULL;
|
||||
if (Failed) {
|
||||
XmlDocumentFree (InfoPlistDocument);
|
||||
FreePool (InfoPlist);
|
||||
FreePool (Buffer);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
@ -1128,29 +1356,102 @@ CachelessContextHookBuiltin (
|
||||
NewPlistData = XmlDocumentExport (InfoPlistDocument, &NewPlistDataSize, 0, TRUE);
|
||||
if (NewPlistData == NULL) {
|
||||
XmlDocumentFree (InfoPlistDocument);
|
||||
FreePool (InfoPlist);
|
||||
FreePool (Buffer);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
XmlDocumentFree (InfoPlistDocument);
|
||||
FreePool (InfoPlist);
|
||||
FreePool (Buffer);
|
||||
|
||||
//
|
||||
// Virtualize newly created Info.plist.
|
||||
//
|
||||
Status = CreateVirtualFileFileNameCopy (FileName, NewPlistData, NewPlistDataSize, NULL, VirtualFile);
|
||||
Status = GetFileModificationTime (File, &ModificationTime);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ZeroMem (&ModificationTime, sizeof (ModificationTime));
|
||||
}
|
||||
|
||||
Status = CreateVirtualFileFileNameCopy (FileName, NewPlistData, NewPlistDataSize, &ModificationTime, VirtualFile);
|
||||
if (EFI_ERROR (Status)) {
|
||||
*VirtualFile = NULL;
|
||||
FreePool (NewPlistData);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Try to get binary for built-in kext.
|
||||
//
|
||||
BuiltinKext = LookupBuiltinKextForBinaryPath (Context, FileName);
|
||||
if (BuiltinKext != NULL && BuiltinKext->PatchKext) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Processing binary patches for %s\n", FileName));
|
||||
|
||||
PatchedKext = LookupPatchedKextForBundleId (Context, BuiltinKext->BundleId);
|
||||
if (PatchedKext == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = AllocateCopyFileData (File, (UINT8 **) &Buffer, &BufferSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = PatcherInitContextFromBuffer (&Patcher, Buffer, BufferSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply patches.
|
||||
//
|
||||
KextLink = GetFirstNode (&PatchedKext->Patches);
|
||||
while (!IsNull (&PatchedKext->Patches, KextLink)) {
|
||||
KextPatch = GET_KEXT_PATCH_FROM_LINK (KextLink);
|
||||
|
||||
if (KextPatch->ApplyQuirk) {
|
||||
Status = KernelQuirkApply (KextPatch->QuirkName, &Patcher);
|
||||
DEBUG ((
|
||||
EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO,
|
||||
"OCAK: Kernel quirk result for %a (%u) - %r\n",
|
||||
PatchedKext->BundleId,
|
||||
KextPatch->QuirkName,
|
||||
Status
|
||||
));
|
||||
} else {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &KextPatch->Patch);
|
||||
DEBUG ((
|
||||
EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO,
|
||||
"OCAK: Kext patcher result for %a (%a) - %r\n",
|
||||
PatchedKext->BundleId,
|
||||
KextPatch->Patch.Comment,
|
||||
Status
|
||||
));
|
||||
}
|
||||
|
||||
KextLink = GetNextNode (&PatchedKext->Patches, KextLink);
|
||||
}
|
||||
|
||||
//
|
||||
// Virtualize patched binary.
|
||||
//
|
||||
Status = GetFileModificationTime (File, &ModificationTime);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ZeroMem (&ModificationTime, sizeof (ModificationTime));
|
||||
}
|
||||
|
||||
Status = CreateVirtualFileFileNameCopy (FileName, Buffer, BufferSize, &ModificationTime, VirtualFile);
|
||||
if (EFI_ERROR (Status)) {
|
||||
*VirtualFile = NULL;
|
||||
FreePool (Buffer);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: hook binaries for patches here.
|
||||
// No file hooked.
|
||||
//
|
||||
|
||||
*VirtualFile = NULL;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
@ -89,6 +89,54 @@ typedef struct {
|
||||
CHAR16 *BinaryFileName;
|
||||
} CACHELESS_KEXT;
|
||||
|
||||
//
|
||||
// Kext patch.
|
||||
//
|
||||
typedef struct {
|
||||
//
|
||||
// Signature.
|
||||
//
|
||||
UINT32 Signature;
|
||||
//
|
||||
// Link for global list (PATCHED_BUILTIN_KEXT -> Patches).
|
||||
//
|
||||
LIST_ENTRY Link;
|
||||
//
|
||||
// Generic patch.
|
||||
//
|
||||
PATCHER_GENERIC_PATCH Patch;
|
||||
//
|
||||
// Apply Quirk instead of Patch.
|
||||
//
|
||||
BOOLEAN ApplyQuirk;
|
||||
//
|
||||
// Kernel quirk to apply.
|
||||
//
|
||||
KERNEL_QUIRK_NAME QuirkName;
|
||||
} KEXT_PATCH;
|
||||
|
||||
//
|
||||
// Built-in kext in SLE requiring patches.
|
||||
//
|
||||
typedef struct {
|
||||
//
|
||||
// Signature.
|
||||
//
|
||||
UINT32 Signature;
|
||||
//
|
||||
// Link for global list (CACHELESS_CONTEXT -> PatchedKexts).
|
||||
//
|
||||
LIST_ENTRY Link;
|
||||
//
|
||||
// Bundle ID.
|
||||
//
|
||||
CHAR8 *BundleId;
|
||||
//
|
||||
// List of patches to apply.
|
||||
//
|
||||
LIST_ENTRY Patches;
|
||||
} PATCHED_KEXT;
|
||||
|
||||
//
|
||||
// Built-in kexts in SLE.
|
||||
//
|
||||
@ -114,6 +162,10 @@ typedef struct {
|
||||
//
|
||||
CHAR16 *BinaryFileName;
|
||||
//
|
||||
// Binary file path.
|
||||
//
|
||||
CHAR16 *BinaryPath;
|
||||
//
|
||||
// Dependencies.
|
||||
//
|
||||
LIST_ENTRY Dependencies;
|
||||
@ -167,13 +219,49 @@ typedef struct {
|
||||
CACHELESS_KEXT_SIGNATURE \
|
||||
))
|
||||
|
||||
//
|
||||
// KEXT_PATCH signature for list identification.
|
||||
//
|
||||
#define KEXT_PATCH_SIGNATURE SIGNATURE_32 ('K', 'x', 't', 'P')
|
||||
|
||||
/**
|
||||
Gets the next element in Patches list of KEXT_PATCH.
|
||||
|
||||
@param[in] This The current ListEntry.
|
||||
**/
|
||||
#define GET_KEXT_PATCH_FROM_LINK(This) \
|
||||
(CR ( \
|
||||
(This), \
|
||||
KEXT_PATCH, \
|
||||
Link, \
|
||||
KEXT_PATCH_SIGNATURE \
|
||||
))
|
||||
|
||||
//
|
||||
// PATCHED_KEXT signature for list identification.
|
||||
//
|
||||
#define PATCHED_KEXT_SIGNATURE SIGNATURE_32 ('S', 'l', 'e', 'P')
|
||||
|
||||
/**
|
||||
Gets the next element in PatchedKexts list of PATCHED_KEXT.
|
||||
|
||||
@param[in] This The current ListEntry.
|
||||
**/
|
||||
#define GET_PATCHED_KEXT_FROM_LINK(This) \
|
||||
(CR ( \
|
||||
(This), \
|
||||
PATCHED_KEXT, \
|
||||
Link, \
|
||||
PATCHED_KEXT_SIGNATURE \
|
||||
))
|
||||
|
||||
//
|
||||
// BUILTIN_KEXT signature for list identification.
|
||||
//
|
||||
#define BUILTIN_KEXT_SIGNATURE SIGNATURE_32 ('S', 'l', 'e', 'B')
|
||||
|
||||
/**
|
||||
Gets the next element in BuiltInKexts list of CACHELESS_KEXT.
|
||||
Gets the next element in BuiltInKexts list of BUILTIN_KEXT.
|
||||
|
||||
@param[in] This The current ListEntry.
|
||||
**/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/** @file
|
||||
Commonly used kext patches.
|
||||
Commonly used kext and kernel patches.
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
@ -96,38 +96,27 @@ mAppleIntelCPUPowerManagementPatch2 = {
|
||||
.Skip = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchAppleCpuPmCfgLock (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status2;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.driver.AppleIntelCPUPowerManagement"
|
||||
);
|
||||
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mAppleIntelCPUPowerManagementPatch);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mAppleIntelCPUPowerManagementPatch);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch v1 success com.apple.driver.AppleIntelCPUPowerManagement\n"));
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch v1 success com.apple.driver.AppleIntelCPUPowerManagement\n"));
|
||||
}
|
||||
|
||||
Status2 = PatcherApplyGenericPatch (&Patcher, &mAppleIntelCPUPowerManagementPatch2);
|
||||
if (!EFI_ERROR (Status2)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch v2 success com.apple.driver.AppleIntelCPUPowerManagement\n"));
|
||||
}
|
||||
Status2 = PatcherApplyGenericPatch (Patcher, &mAppleIntelCPUPowerManagementPatch2);
|
||||
if (!EFI_ERROR (Status2)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch v2 success com.apple.driver.AppleIntelCPUPowerManagement\n"));
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status) && EFI_ERROR (Status2)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patches com.apple.driver.AppleIntelCPUPowerManagement - %r/%r\n", Status, Status2));
|
||||
}
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.AppleIntelCPUPowerManagement - %r\n", Status));
|
||||
Status2 = Status;
|
||||
if (EFI_ERROR (Status) && EFI_ERROR (Status2)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patches com.apple.driver.AppleIntelCPUPowerManagement - %r/%r\n", Status, Status2));
|
||||
}
|
||||
|
||||
//
|
||||
@ -207,9 +196,10 @@ mXcpmCfgLockDbgPatch = {
|
||||
.Limit = 4096
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchAppleXcpmCfgLock (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -330,9 +320,10 @@ mMiscPwrMgmtDbgPatch = {
|
||||
.Limit = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchAppleXcpmExtraMsrs (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -449,9 +440,10 @@ mPerfCtrlMax[] = {
|
||||
0xC3 ///< ret
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchAppleXcpmForceBoost (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
UINT8 *Start;
|
||||
@ -587,35 +579,36 @@ mRemoveUsbLimitIoP1Patch = {
|
||||
.Limit = 4096
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchUsbXhciPortLimit (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
PatchUsbXhciPortLimit1 (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// On 10.14.4 and newer IOUSBHostFamily also needs limit removal.
|
||||
// Thanks to ydeng discovering this.
|
||||
//
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.iokit.IOUSBHostFamily"
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitIoP1Patch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply P1 patch com.apple.iokit.IOUSBHostFamily - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOUSBHostFamily\n"));
|
||||
}
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mRemoveUsbLimitIoP1Patch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply P1 patch com.apple.iokit.IOUSBHostFamily - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.iokit.IOUSBHostFamily - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOUSBHostFamily\n"));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchUsbXhciPortLimit2 (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// TODO: Implement some locationID hack in IOUSBHFamily.
|
||||
// The location ID is a 32 bit number which is unique among all USB devices in the system,
|
||||
@ -637,47 +630,36 @@ PatchUsbXhciPortLimit (
|
||||
//
|
||||
// C~F are filled as many times as many USB Hubs are there on the port.
|
||||
//
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.driver.usb.AppleUSBXHCI"
|
||||
);
|
||||
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mRemoveUsbLimitV2Patch);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitV2Patch);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// We do not need to patch com.apple.driver.usb.AppleUSBXHCI if this patch was successful.
|
||||
// Only legacy systems require com.apple.driver.usb.AppleUSBXHCI to be patched.
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.usb.AppleUSBXHCI\n"));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.usb.AppleUSBXHCI - %r\n", Status));
|
||||
//
|
||||
// We do not need to patch com.apple.driver.usb.AppleUSBXHCI if this patch was successful.
|
||||
// Only legacy systems require com.apple.driver.usb.AppleUSBXHCI to be patched.
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.usb.AppleUSBXHCI\n"));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.usb.AppleUSBXHCI - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.usb.AppleUSBXHCI - %r\n", Status));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchUsbXhciPortLimit3 (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// If we are here, we are on legacy 10.13 or below, try the oldest patch.
|
||||
//
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.driver.usb.AppleUSBXHCIPCI"
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitV1Patch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.usb.AppleUSBXHCIPCI\n"));
|
||||
}
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mRemoveUsbLimitV1Patch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.usb.AppleUSBXHCIPCI\n"));
|
||||
}
|
||||
|
||||
return Status;
|
||||
@ -735,37 +717,27 @@ mIOAHCIBlockStoragePatchV2 = {
|
||||
.Skip = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchThirdPartyDriveSupport (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.iokit.IOAHCIBlockStorage"
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mIOAHCIBlockStoragePatchV1);
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mIOAHCIBlockStoragePatchV1);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOAHCIBlockStorage V1 - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOAHCIBlockStorage V1\n"));
|
||||
}
|
||||
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mIOAHCIBlockStoragePatchV2);
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mIOAHCIBlockStoragePatchV2);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOAHCIBlockStorage V2 - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOAHCIBlockStorage V2\n"));
|
||||
}
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.iokit.IOAHCIBlockStorage - %r\n", Status));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -785,40 +757,30 @@ mIOAHCIPortPatchReplace[] = {
|
||||
STATIC
|
||||
PATCHER_GENERIC_PATCH
|
||||
mIOAHCIPortPatch = {
|
||||
.Comment = DEBUG_POINTER ("IOAHCIPort"),
|
||||
.Base = NULL,
|
||||
.Find = mIOAHCIPortPatchFind,
|
||||
.Mask = NULL,
|
||||
.Replace = mIOAHCIPortPatchReplace,
|
||||
.ReplaceMask = NULL,
|
||||
.Size = sizeof (mIOAHCIPortPatchFind),
|
||||
.Count = 1,
|
||||
.Skip = 0
|
||||
.Comment = DEBUG_POINTER ("IOAHCIPort"),
|
||||
.Base = NULL,
|
||||
.Find = mIOAHCIPortPatchFind,
|
||||
.Mask = NULL,
|
||||
.Replace = mIOAHCIPortPatchReplace,
|
||||
.ReplaceMask = NULL,
|
||||
.Size = sizeof (mIOAHCIPortPatchFind),
|
||||
.Count = 1,
|
||||
.Skip = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchForceInternalDiskIcons (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.driver.AppleAHCIPort"
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mIOAHCIPortPatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.AppleAHCIPort - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.AppleAHCIPort\n"));
|
||||
}
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mIOAHCIPortPatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.AppleAHCIPort - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.AppleAHCIPort - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.AppleAHCIPort\n"));
|
||||
}
|
||||
|
||||
return Status;
|
||||
@ -850,29 +812,19 @@ mAppleIoMapperPatch = {
|
||||
.Skip = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchAppleIoMapperSupport (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.iokit.IOPCIFamily"
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mAppleIoMapperPatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOPCIFamily AppleIoMapper - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOPCIFamily AppleIoMapper\n"));
|
||||
}
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mAppleIoMapperPatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOPCIFamily AppleIoMapper - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.iokit.IOPCIFamily for AppleIoMapper - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOPCIFamily AppleIoMapper\n"));
|
||||
}
|
||||
|
||||
return Status;
|
||||
@ -898,29 +850,19 @@ mAppleDummyCpuPmPatch = {
|
||||
.Skip = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchDummyPowerManagement (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.driver.AppleIntelCPUPowerManagement"
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mAppleDummyCpuPmPatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch dummy AppleIntelCPUPowerManagement - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success dummy AppleIntelCPUPowerManagement\n"));
|
||||
}
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mAppleDummyCpuPmPatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch dummy AppleIntelCPUPowerManagement - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find AppleIntelCPUPowerManagement for dummy - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success dummy AppleIntelCPUPowerManagement\n"));
|
||||
}
|
||||
|
||||
return Status;
|
||||
@ -953,34 +895,25 @@ mIncreasePciBarSizePatch = {
|
||||
.Limit = EFI_PAGE_SIZE
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchIncreasePciBarSize (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.iokit.IOPCIFamily"
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mIncreasePciBarSizePatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOPCIFamily IncreasePciBarSize - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOPCIFamily IncreasePciBarSize\n"));
|
||||
}
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mIncreasePciBarSizePatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOPCIFamily IncreasePciBarSize - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.iokit.IOPCIFamily for IncreasePciBarSize - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOPCIFamily IncreasePciBarSize\n"));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
CONST UINT8
|
||||
mKernelCpuIdFindRelNew[] = {
|
||||
@ -1027,6 +960,8 @@ mKernelCpuidFindMcRel[] = {
|
||||
cpu->cpuid_cpufamily = 0xAAAAAAAA;
|
||||
return 0xAAAAAAAA;
|
||||
**/
|
||||
|
||||
|
||||
STATIC
|
||||
CONST UINT8
|
||||
mKernelCpuidReplaceDbg[] = {
|
||||
@ -1454,48 +1389,30 @@ mCustomSmbiosGuidPatchReplace[] = {
|
||||
STATIC
|
||||
PATCHER_GENERIC_PATCH
|
||||
mCustomSmbiosGuidPatch = {
|
||||
.Comment = DEBUG_POINTER ("CustomSmbiosGuid"),
|
||||
.Base = NULL,
|
||||
.Find = mCustomSmbiosGuidPatchFind,
|
||||
.Mask = NULL,
|
||||
.Replace = mCustomSmbiosGuidPatchReplace,
|
||||
.ReplaceMask = NULL,
|
||||
.Size = sizeof (mCustomSmbiosGuidPatchFind),
|
||||
.Count = 1,
|
||||
.Skip = 0
|
||||
.Comment = DEBUG_POINTER ("CustomSmbiosGuid"),
|
||||
.Base = NULL,
|
||||
.Find = mCustomSmbiosGuidPatchFind,
|
||||
.Mask = NULL,
|
||||
.Replace = mCustomSmbiosGuidPatchReplace,
|
||||
.ReplaceMask = NULL,
|
||||
.Size = sizeof (mCustomSmbiosGuidPatchFind),
|
||||
.Count = 1,
|
||||
.Skip = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchCustomSmbiosGuid (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
UINT32 Index;
|
||||
|
||||
STATIC CONST CHAR8 *Kexts[] = {
|
||||
"com.apple.driver.AppleSMBIOS",
|
||||
"com.apple.driver.AppleACPIPlatform"
|
||||
};
|
||||
|
||||
for (Index = 0; Index < ARRAY_SIZE (Kexts); ++Index) {
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
Kexts[Index]
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mCustomSmbiosGuidPatch);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: SMBIOS Patch success %a\n", Kexts[Index]));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply SMBIOS patch %a - %r\n", Kexts[Index], Status));
|
||||
}
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find SMBIOS kext %a - %r\n", Kexts[Index], Status));
|
||||
}
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mCustomSmbiosGuidPatch);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: SMBIOS Patch success\n"));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply SMBIOS patch - %r\n", Status));
|
||||
}
|
||||
|
||||
return Status;
|
||||
@ -1527,9 +1444,10 @@ mPanicKextDumpPatch = {
|
||||
.Skip = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchPanicKextDump (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -1676,9 +1594,10 @@ mLapicKernelPanicMasterPatch = {
|
||||
.Limit = 4096
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchLapicKernelPanic (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -1744,9 +1663,10 @@ mPowerStateTimeoutPanicMasterPatch = {
|
||||
.Limit = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchPowerStateTimeout (
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -1806,30 +1726,55 @@ mAppleRtcChecksumPatch = {
|
||||
.Limit = 0
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PatchAppleRtcChecksum (
|
||||
IN OUT PRELINKED_CONTEXT *Context
|
||||
IN PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
"com.apple.driver.AppleRTC"
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &mAppleRtcChecksumPatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.AppleRTC DisableRtcChecksum - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.AppleRTC DisableRtcChecksum\n"));
|
||||
}
|
||||
Status = PatcherApplyGenericPatch (Patcher, &mAppleRtcChecksumPatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.AppleRTC DisableRtcChecksum - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.AppleRTC for DisableRtcChecksum - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.AppleRTC DisableRtcChecksum\n"));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Quirks table.
|
||||
//
|
||||
KERNEL_QUIRK gKernelQuirks[] = {
|
||||
[KernelQuirkAppleCpuPmCfgLock] = { "com.apple.driver.AppleIntelCPUPowerManagement", PatchAppleCpuPmCfgLock },
|
||||
[KernelQuirkAppleXcpmCfgLock] = { NULL, PatchAppleXcpmCfgLock },
|
||||
[KernelQuirkAppleXcpmExtraMsrs] = { NULL, PatchAppleXcpmExtraMsrs },
|
||||
[KernelQuirkAppleXcpmForceBoost] = { NULL, PatchAppleXcpmForceBoost },
|
||||
[KernelQuirkCustomSmbiosGuid1] = { "com.apple.driver.AppleSMBIOS", PatchCustomSmbiosGuid },
|
||||
[KernelQuirkCustomSmbiosGuid2] = { "com.apple.driver.AppleACPIPlatform", PatchCustomSmbiosGuid },
|
||||
[KernelQuirkDisableIoMapper] = { "com.apple.iokit.IOPCIFamily", PatchAppleIoMapperSupport },
|
||||
[KernelQuirkDisableRtcChecksum] = { "com.apple.driver.AppleRTC", PatchAppleRtcChecksum },
|
||||
[KernelQuirkDummyPowerManagement] = { "com.apple.driver.AppleIntelCPUPowerManagement", PatchDummyPowerManagement },
|
||||
[KernelQuirkExternalDiskIcons] = { "com.apple.driver.AppleAHCIPort", PatchForceInternalDiskIcons },
|
||||
[KernelQuirkIncreasePciBarSize] = { "com.apple.iokit.IOPCIFamily", PatchIncreasePciBarSize },
|
||||
[KernelQuirkLapicKernelPanic] = { NULL, PatchLapicKernelPanic },
|
||||
[KernelQuirkPanicNoKextDump] = { NULL, PatchPanicKextDump },
|
||||
[KernelQuirkPowerTimeoutKernelPanic] = { NULL, PatchPowerStateTimeout },
|
||||
[KernelQuirkThirdPartyDrives] = { "com.apple.iokit.IOAHCIBlockStorage", PatchThirdPartyDriveSupport },
|
||||
[KernelQuirkXhciPortLimit1] = { "com.apple.iokit.IOUSBHostFamily", PatchUsbXhciPortLimit1 },
|
||||
[KernelQuirkXhciPortLimit2] = { "com.apple.driver.usb.AppleUSBXHCI", PatchUsbXhciPortLimit2 },
|
||||
[KernelQuirkXhciPortLimit3] = { "com.apple.driver.usb.AppleUSBXHCIPCI", PatchUsbXhciPortLimit3 },
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
KernelQuirkApply (
|
||||
IN KERNEL_QUIRK_NAME Name,
|
||||
IN OUT PATCHER_CONTEXT *Patcher
|
||||
)
|
||||
{
|
||||
ASSERT (Patcher != NULL);
|
||||
|
||||
return gKernelQuirks[Name].PatchFunction (Patcher);
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <Library/OcMiscLib.h>
|
||||
#include <Library/OcXmlLib.h>
|
||||
|
||||
#include "MkextInternal.h"
|
||||
#include "PrelinkedInternal.h"
|
||||
|
||||
EFI_STATUS
|
||||
@ -44,6 +45,23 @@ PatcherInitContextFromPrelinked (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PatcherInitContextFromMkext(
|
||||
IN OUT PATCHER_CONTEXT *Context,
|
||||
IN OUT MKEXT_CONTEXT *Mkext,
|
||||
IN CONST CHAR8 *Name
|
||||
)
|
||||
{
|
||||
MKEXT_KEXT *Kext;
|
||||
|
||||
Kext = InternalCachedMkextKext (Mkext, Name);
|
||||
if (Kext == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return PatcherInitContextFromBuffer (Context, &Mkext->Mkext[Kext->BinaryOffset], Kext->BinarySize);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PatcherInitContextFromBuffer (
|
||||
IN OUT PATCHER_CONTEXT *Context,
|
||||
|
||||
@ -15,18 +15,16 @@
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <IndustryStandard/AppleFatBinaryImage.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/OcAppleKernelLib.h>
|
||||
#include <Library/OcCompressionLib.h>
|
||||
#include <Library/OcFileLib.h>
|
||||
#include <Library/OcGuardLib.h>
|
||||
#include <Library/OcStringLib.h>
|
||||
|
||||
#include "MkextInternal.h"
|
||||
#include "PrelinkedInternal.h"
|
||||
|
||||
//
|
||||
@ -82,6 +80,7 @@ BOOLEAN
|
||||
ParseMkextV2Plist (
|
||||
IN MKEXT_V2_HEADER *Mkext,
|
||||
OUT UINT8 **Plist,
|
||||
OUT UINT32 *PlistSize,
|
||||
OUT XML_DOCUMENT **PlistDoc,
|
||||
OUT XML_NODE **PlistBundles
|
||||
)
|
||||
@ -169,6 +168,7 @@ ParseMkextV2Plist (
|
||||
|
||||
if (AsciiStrCmp (BundleArrayKey, MKEXT_INFO_DICTIONARIES_KEY) == 0) {
|
||||
*Plist = PlistBuffer;
|
||||
*PlistSize = PlistFullSize;
|
||||
*PlistDoc = PlistXml;
|
||||
*PlistBundles = PlistBundleArray;
|
||||
|
||||
@ -213,16 +213,249 @@ UpdateMkextV2Plist (
|
||||
return 0;
|
||||
}
|
||||
|
||||
MkextBuffer = (UINT8*)Mkext;
|
||||
MkextBuffer = (UINT8 *) Mkext;
|
||||
CopyMem (&MkextBuffer[Offset], ExportedInfo, ExportedInfoSize);
|
||||
FreePool (ExportedInfo);
|
||||
|
||||
Mkext->PlistOffset = SwapBytes32 (Offset);
|
||||
Mkext->PlistFullSize = SwapBytes32 (ExportedInfoSize);
|
||||
Mkext->PlistCompressedSize = 0;
|
||||
Mkext->PlistOffset = SwapBytes32 (Offset);
|
||||
Mkext->PlistFullSize = SwapBytes32 (ExportedInfoSize);
|
||||
Mkext->PlistCompressedSize = 0;
|
||||
return ExportedInfoSize;
|
||||
}
|
||||
|
||||
MKEXT_KEXT *
|
||||
InternalCachedMkextKext (
|
||||
IN OUT MKEXT_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId
|
||||
)
|
||||
{
|
||||
MKEXT_HEADER_ANY *MkextHeader;
|
||||
MKEXT_V2_FILE_ENTRY *MkextV2FileEntry;
|
||||
|
||||
MKEXT_KEXT *MkextKext;
|
||||
LIST_ENTRY *KextLink;
|
||||
UINT32 Index;
|
||||
UINT32 PlistOffsetSize;
|
||||
UINT32 BinOffsetSize;
|
||||
BOOLEAN IsKextMatch;
|
||||
|
||||
UINT32 PlistOffset;
|
||||
UINT32 PlistSize;
|
||||
CHAR8 *PlistBuffer;
|
||||
XML_DOCUMENT *PlistXml;
|
||||
XML_NODE *PlistRoot;
|
||||
|
||||
UINT32 PlistBundlesCount;
|
||||
XML_NODE *PlistBundle;
|
||||
UINT32 PlistBundleIndex;
|
||||
UINT32 PlistBundleCount;
|
||||
CONST CHAR8 *PlistBundleKey;
|
||||
XML_NODE *PlistBundleKeyValue;
|
||||
|
||||
CONST CHAR8 *KextBundleId;
|
||||
UINT32 KextBinOffset;
|
||||
UINT32 KextBinSize;
|
||||
|
||||
MkextHeader = Context->MkextHeader;
|
||||
|
||||
//
|
||||
// Try to get cached kext.
|
||||
//
|
||||
KextLink = GetFirstNode (&Context->CachedKexts);
|
||||
while (!IsNull (&Context->CachedKexts, KextLink)) {
|
||||
MkextKext = GET_MKEXT_KEXT_FROM_LINK (KextLink);
|
||||
|
||||
if (AsciiStrCmp (BundleId, MkextKext->BundleId) == 0) {
|
||||
return MkextKext;
|
||||
}
|
||||
|
||||
KextLink = GetNextNode (&Context->CachedKexts, KextLink);
|
||||
}
|
||||
|
||||
//
|
||||
// Search mkext and add kext to cache.
|
||||
//
|
||||
IsKextMatch = FALSE;
|
||||
|
||||
//
|
||||
// Mkext v1.
|
||||
//
|
||||
if (Context->MkextVersion == MKEXT_VERSION_V1) {
|
||||
for (Index = 0; Index < Context->NumKexts; Index++) {
|
||||
//
|
||||
// Do not cache binaryless or compressed kexts.
|
||||
//
|
||||
if (MkextHeader->V1.Kexts[Index].Plist.CompressedSize != 0
|
||||
|| MkextHeader->V1.Kexts[Index].Binary.CompressedSize != 0
|
||||
|| MkextHeader->V1.Kexts[Index].Binary.Offset == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PlistOffset = SwapBytes32 (MkextHeader->V1.Kexts[Index].Plist.Offset);
|
||||
PlistSize = SwapBytes32 (MkextHeader->V1.Kexts[Index].Plist.FullSize);
|
||||
KextBinOffset = SwapBytes32 (MkextHeader->V1.Kexts[Index].Binary.Offset);
|
||||
KextBinSize = SwapBytes32 (MkextHeader->V1.Kexts[Index].Binary.FullSize);
|
||||
|
||||
//
|
||||
// Verify plist and binary are within bounds.
|
||||
//
|
||||
if (OcOverflowAddU32 (PlistOffset, PlistSize, &PlistOffsetSize)
|
||||
|| PlistOffsetSize > Context->MkextSize
|
||||
|| OcOverflowAddU32 (KextBinOffset, KextBinSize, &BinOffsetSize)
|
||||
|| BinOffsetSize > Context->MkextSize) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PlistBuffer = AllocateCopyPool (PlistSize, &Context->Mkext[PlistOffset]);
|
||||
if (PlistBuffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PlistXml = XmlDocumentParse (PlistBuffer, PlistSize, FALSE);
|
||||
if (PlistXml == NULL) {
|
||||
FreePool (PlistBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PlistRoot = PlistNodeCast (PlistDocumentRoot (PlistXml), PLIST_NODE_TYPE_DICT);
|
||||
if (PlistRoot == NULL) {
|
||||
XmlDocumentFree (PlistXml);
|
||||
FreePool (PlistBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KextBundleId = NULL;
|
||||
PlistBundleCount = PlistDictChildren (PlistRoot);
|
||||
for (PlistBundleIndex = 0; PlistBundleIndex < PlistBundleCount; PlistBundleIndex++) {
|
||||
PlistBundleKey = PlistKeyValue (PlistDictChild (PlistRoot, PlistBundleIndex, &PlistBundleKeyValue));
|
||||
if (PlistBundleKey == NULL || PlistBundleKeyValue == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AsciiStrCmp (PlistBundleKey, INFO_BUNDLE_IDENTIFIER_KEY) == 0) {
|
||||
KextBundleId = XmlNodeContent (PlistBundleKeyValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IsKextMatch = KextBundleId != NULL && AsciiStrCmp (KextBundleId, BundleId) == 0;
|
||||
XmlDocumentFree (PlistXml);
|
||||
FreePool (PlistBuffer);
|
||||
|
||||
if (IsKextMatch && KextBinOffset > 0 && KextBinSize > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bundle was not found, or invalid.
|
||||
//
|
||||
if (!IsKextMatch) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Mkext v2.
|
||||
//
|
||||
} else if (Context->MkextVersion == MKEXT_VERSION_V2) {
|
||||
KextBundleId = NULL;
|
||||
KextBinOffset = 0;
|
||||
|
||||
//
|
||||
// Enumerate bundle dicts.
|
||||
//
|
||||
PlistBundlesCount = XmlNodeChildren (Context->MkextKexts);
|
||||
for (Index = 0; Index < PlistBundlesCount; Index++) {
|
||||
PlistBundle = PlistNodeCast (XmlNodeChild (Context->MkextKexts, Index), PLIST_NODE_TYPE_DICT);
|
||||
if (PlistBundle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PlistBundleCount = PlistDictChildren (PlistBundle);
|
||||
for (PlistBundleIndex = 0; PlistBundleIndex < PlistBundleCount; PlistBundleIndex++) {
|
||||
PlistBundleKey = PlistKeyValue (PlistDictChild (PlistBundle, PlistBundleIndex, &PlistBundleKeyValue));
|
||||
if (PlistBundleKey == NULL || PlistBundleKeyValue == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AsciiStrCmp (PlistBundleKey, INFO_BUNDLE_IDENTIFIER_KEY) == 0) {
|
||||
KextBundleId = XmlNodeContent (PlistBundleKeyValue);
|
||||
}
|
||||
|
||||
if (AsciiStrCmp (PlistBundleKey, MKEXT_EXECUTABLE_KEY) == 0) {
|
||||
//
|
||||
// Ensure binary offset is before plist offset.
|
||||
//
|
||||
if (!PlistIntegerValue (PlistBundleKeyValue, &KextBinOffset, sizeof (KextBinOffset), TRUE)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (KextBundleId != NULL
|
||||
&& AsciiStrCmp (KextBundleId, BundleId) == 0
|
||||
&& KextBinOffset > 0
|
||||
&& KextBinOffset < Context->MkextSize - sizeof (MKEXT_V2_FILE_ENTRY)) {
|
||||
IsKextMatch = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
KextBundleId = NULL;
|
||||
KextBinOffset = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Bundle was not found, or invalid.
|
||||
//
|
||||
if (!IsKextMatch) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Parse v2 binary header.
|
||||
// We cannot support compressed binaries.
|
||||
//
|
||||
MkextV2FileEntry = (MKEXT_V2_FILE_ENTRY *) &Context->Mkext[KextBinOffset];
|
||||
if (MkextV2FileEntry->CompressedSize != 0) {
|
||||
return NULL;
|
||||
}
|
||||
KextBinOffset += OFFSET_OF (MKEXT_V2_FILE_ENTRY, Data);
|
||||
KextBinSize = SwapBytes32 (MkextV2FileEntry->FullSize);
|
||||
|
||||
//
|
||||
// Ensure binary is within mkext bounds.
|
||||
//
|
||||
if (OcOverflowAddU32 (KextBinOffset, KextBinSize, &BinOffsetSize)
|
||||
|| BinOffsetSize > Context->MkextSize) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Unsupported version.
|
||||
//
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MkextKext = AllocateZeroPool (sizeof (*MkextKext));
|
||||
if (MkextKext == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MkextKext->Signature = MKEXT_KEXT_SIGNATURE;
|
||||
MkextKext->BinaryOffset = KextBinOffset;
|
||||
MkextKext->BinarySize = KextBinSize;
|
||||
MkextKext->BundleId = AllocateCopyPool (AsciiStrSize (BundleId), BundleId);
|
||||
if (MkextKext->BundleId == NULL) {
|
||||
FreePool (MkextKext);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InsertTailList (&Context->CachedKexts, &MkextKext->Link);
|
||||
|
||||
return MkextKext;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
MkextDecompress (
|
||||
IN CONST UINT8 *Buffer,
|
||||
@ -296,6 +529,8 @@ MkextDecompress (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
MkextHeaderOut = NULL;
|
||||
|
||||
//
|
||||
// Mkext v1.
|
||||
//
|
||||
@ -367,7 +602,7 @@ MkextDecompress (
|
||||
|| DecompressLZSS (
|
||||
&OutBuffer[CurrentOffset],
|
||||
PlistFullSize,
|
||||
&((UINT8*)Buffer)[PlistOffset],
|
||||
&((UINT8 *) Buffer)[PlistOffset],
|
||||
PlistCompSize
|
||||
) != PlistFullSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@ -396,7 +631,7 @@ MkextDecompress (
|
||||
|| DecompressLZSS (
|
||||
&OutBuffer[CurrentOffset],
|
||||
BinFullSize,
|
||||
&((UINT8*)Buffer)[BinOffset],
|
||||
&((UINT8 *) Buffer)[BinOffset],
|
||||
BinCompSize
|
||||
) != BinFullSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@ -460,7 +695,7 @@ MkextDecompress (
|
||||
MkextHeaderOut = (MKEXT_HEADER_ANY *) OutBuffer;
|
||||
}
|
||||
|
||||
if (!ParseMkextV2Plist (&MkextHeader->V2, &PlistBuffer, &PlistXml, &PlistBundles)) {
|
||||
if (!ParseMkextV2Plist (&MkextHeader->V2, &PlistBuffer, &PlistFullSize, &PlistXml, &PlistBundles)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@ -689,18 +924,14 @@ MkextContextInit (
|
||||
UINT8 *PlistBuffer;
|
||||
XML_DOCUMENT *PlistXml;
|
||||
UINT32 PlistOffset;
|
||||
UINT32 PlistFullSize;
|
||||
XML_NODE *PlistBundles;
|
||||
UINT32 PlistBundlesCount;
|
||||
XML_NODE *PlistBundle;
|
||||
UINT32 PlistBundleIndex;
|
||||
UINT32 PlistBundleCount;
|
||||
CONST CHAR8 *PlistBundleKey;
|
||||
XML_NODE *BundleExecutable;
|
||||
UINT32 BinOffset;
|
||||
|
||||
//
|
||||
// Assumptions:
|
||||
// Kexts are fully decompressed and aligned to 8 bytes with plist (for v2) at end of mkext.
|
||||
// Kexts are aligned to 8 bytes.
|
||||
// Patching or blocking requires kexts to be decompressed.
|
||||
// Plist (for v2) is at end of mkext.
|
||||
// Mkext is big-endian per XNU requirements.
|
||||
//
|
||||
|
||||
@ -754,9 +985,6 @@ MkextContextInit (
|
||||
StartingOffset = 0;
|
||||
for (Index = 0; Index < NumKexts; Index++) {
|
||||
CurrentOffset = SwapBytes32 (MkextHeader->V1.Kexts[Index].Plist.Offset);
|
||||
if (MkextHeader->V1.Kexts[Index].Plist.CompressedSize != 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
if (StartingOffset == 0 || CurrentOffset < StartingOffset) {
|
||||
StartingOffset = CurrentOffset;
|
||||
}
|
||||
@ -766,9 +994,6 @@ MkextContextInit (
|
||||
//
|
||||
if (MkextHeader->V1.Kexts[Index].Binary.FullSize > 0) {
|
||||
CurrentOffset = SwapBytes32 (MkextHeader->V1.Kexts[Index].Binary.Offset);
|
||||
if (MkextHeader->V1.Kexts[Index].Binary.CompressedSize != 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
if (CurrentOffset < StartingOffset) {
|
||||
StartingOffset = CurrentOffset;
|
||||
}
|
||||
@ -791,43 +1016,14 @@ MkextContextInit (
|
||||
//
|
||||
} else if (MkextVersion == MKEXT_VERSION_V2) {
|
||||
if (MkextSize < sizeof (MKEXT_V2_HEADER)
|
||||
|| !ParseMkextV2Plist (&MkextHeader->V2, &PlistBuffer, &PlistXml, &PlistBundles)) {
|
||||
|| !ParseMkextV2Plist (&MkextHeader->V2, &PlistBuffer, &PlistFullSize, &PlistXml, &PlistBundles)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
PlistOffset = SwapBytes32 (MkextHeader->V2.PlistOffset);
|
||||
|
||||
//
|
||||
// Enumerate bundle dicts.
|
||||
//
|
||||
PlistBundlesCount = XmlNodeChildren (PlistBundles);
|
||||
for (Index = 0; Index < PlistBundlesCount; Index++) {
|
||||
PlistBundle = PlistNodeCast (XmlNodeChild (PlistBundles, Index), PLIST_NODE_TYPE_DICT);
|
||||
if (PlistBundle == NULL) {
|
||||
XmlDocumentFree (PlistXml);
|
||||
FreePool (PlistBuffer);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
PlistBundleCount = PlistDictChildren (PlistBundle);
|
||||
for (PlistBundleIndex = 0; PlistBundleIndex < PlistBundleCount; PlistBundleIndex++) {
|
||||
PlistBundleKey = PlistKeyValue (PlistDictChild (PlistBundle, PlistBundleIndex, &BundleExecutable));
|
||||
if (PlistBundleKey == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AsciiStrCmp (PlistBundleKey, MKEXT_EXECUTABLE_KEY) == 0) {
|
||||
//
|
||||
// Ensure binary offset is before plist offset.
|
||||
//
|
||||
if (!PlistIntegerValue (BundleExecutable, &BinOffset, sizeof (BinOffset), TRUE)
|
||||
|| BinOffset == 0
|
||||
|| BinOffset >= PlistOffset) {
|
||||
XmlDocumentFree (PlistXml);
|
||||
FreePool (PlistBuffer);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OcOverflowAddU32 (PlistOffset, PlistFullSize, &Tmp)
|
||||
|| Tmp != MkextSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
@ -845,6 +1041,7 @@ MkextContextInit (
|
||||
Context->MkextVersion = MkextVersion;
|
||||
Context->Is64Bit = Is64Bit;
|
||||
Context->NumKexts = NumKexts;
|
||||
InitializeListHead (&Context->CachedKexts);
|
||||
|
||||
if (MkextVersion == MKEXT_VERSION_V1) {
|
||||
Context->NumMaxKexts = NumMaxKexts;
|
||||
@ -863,8 +1060,20 @@ MkextContextFree (
|
||||
IN OUT MKEXT_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
MKEXT_KEXT *MkextKext;
|
||||
LIST_ENTRY *KextLink;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
|
||||
while (!IsListEmpty (&Context->CachedKexts)) {
|
||||
KextLink = GetFirstNode (&Context->CachedKexts);
|
||||
MkextKext = GET_MKEXT_KEXT_FROM_LINK (KextLink);
|
||||
RemoveEntryList (KextLink);
|
||||
|
||||
FreePool (MkextKext->BundleId);
|
||||
FreePool (MkextKext);
|
||||
}
|
||||
|
||||
if (Context->MkextInfoDocument != NULL) {
|
||||
XmlDocumentFree (Context->MkextInfoDocument);
|
||||
}
|
||||
@ -949,6 +1158,8 @@ MkextInjectKext (
|
||||
ASSERT (InfoPlist != NULL);
|
||||
ASSERT (InfoPlistSize > 0);
|
||||
|
||||
BinOffset = 0;
|
||||
|
||||
//
|
||||
// Mkext v1.
|
||||
//
|
||||
@ -1131,6 +1342,53 @@ MkextInjectKext (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
MkextContextApplyPatch (
|
||||
IN OUT MKEXT_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId,
|
||||
IN PATCHER_GENERIC_PATCH *Patch
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
ASSERT (BundleId != NULL);
|
||||
ASSERT (Patch != NULL);
|
||||
|
||||
Status = PatcherInitContextFromMkext (&Patcher, Context, BundleId);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find %a - %r\n", BundleId, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
return PatcherApplyGenericPatch (&Patcher, Patch);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
MkextContextApplyQuirk (
|
||||
IN OUT MKEXT_CONTEXT *Context,
|
||||
IN KERNEL_QUIRK_NAME Quirk
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
KERNEL_QUIRK *KernelQuirk;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
|
||||
KernelQuirk = &gKernelQuirks[Quirk];
|
||||
ASSERT (KernelQuirk->BundleId != NULL);
|
||||
|
||||
Status = PatcherInitContextFromMkext (&Patcher, Context, KernelQuirk->BundleId);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find %a - %r\n", KernelQuirk->BundleId, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
return KernelQuirk->PatchFunction (&Patcher);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
MkextInjectPatchComplete (
|
||||
IN OUT MKEXT_CONTEXT *Context
|
||||
|
||||
72
Library/OcAppleKernelLib/MkextInternal.h
Normal file
72
Library/OcAppleKernelLib/MkextInternal.h
Normal file
@ -0,0 +1,72 @@
|
||||
/** @file
|
||||
Mkext support.
|
||||
|
||||
Copyright (c) 2020, Goldfish64. All rights reserved.
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef MKEXT_INTERNAL_H
|
||||
#define MKEXT_INTERNAL_H
|
||||
|
||||
#include <Library/OcAppleKernelLib.h>
|
||||
|
||||
//
|
||||
// Cached mkext kext.
|
||||
//
|
||||
typedef struct {
|
||||
//
|
||||
// Signature.
|
||||
//
|
||||
UINT32 Signature;
|
||||
//
|
||||
// Link for global list (MKEXT_CONTEXT -> CachedKexts).
|
||||
//
|
||||
LIST_ENTRY Link;
|
||||
//
|
||||
// Kext bundle ID.
|
||||
//
|
||||
CHAR8 *BundleId;
|
||||
//
|
||||
// Offset of binary in mkext.
|
||||
//
|
||||
UINT32 BinaryOffset;
|
||||
//
|
||||
// Size of binary in mkext.
|
||||
//
|
||||
UINT32 BinarySize;
|
||||
} MKEXT_KEXT;
|
||||
|
||||
//
|
||||
// MKEXT_KEXT signature for list identification.
|
||||
//
|
||||
#define MKEXT_KEXT_SIGNATURE SIGNATURE_32 ('M', 'k', 'x', 'T')
|
||||
|
||||
/**
|
||||
Gets the next element in CachedKexts list of MKEXT_KEXT.
|
||||
|
||||
@param[in] This The current ListEntry.
|
||||
**/
|
||||
#define GET_MKEXT_KEXT_FROM_LINK(This) \
|
||||
(CR ( \
|
||||
(This), \
|
||||
MKEXT_KEXT, \
|
||||
Link, \
|
||||
MKEXT_KEXT_SIGNATURE \
|
||||
))
|
||||
|
||||
|
||||
MKEXT_KEXT *
|
||||
InternalCachedMkextKext (
|
||||
IN OUT MKEXT_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId
|
||||
);
|
||||
|
||||
#endif // MKEXT_INTERNAL_H
|
||||
@ -1134,3 +1134,50 @@ PrelinkedInjectKext (
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PrelinkedContextApplyPatch (
|
||||
IN OUT PRELINKED_CONTEXT *Context,
|
||||
IN CONST CHAR8 *BundleId,
|
||||
IN PATCHER_GENERIC_PATCH *Patch
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
ASSERT (BundleId != NULL);
|
||||
ASSERT (Patch != NULL);
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (&Patcher, Context, BundleId);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find %a - %r\n", BundleId, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
return PatcherApplyGenericPatch (&Patcher, Patch);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PrelinkedContextApplyQuirk (
|
||||
IN OUT PRELINKED_CONTEXT *Context,
|
||||
IN KERNEL_QUIRK_NAME Quirk
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
KERNEL_QUIRK *KernelQuirk;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
|
||||
KernelQuirk = &gKernelQuirks[Quirk];
|
||||
ASSERT (KernelQuirk->BundleId != NULL);
|
||||
|
||||
Status = PatcherInitContextFromPrelinked (&Patcher, Context, KernelQuirk->BundleId);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Failed to find %a - %r\n", KernelQuirk->BundleId, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
return KernelQuirk->PatchFunction (&Patcher);
|
||||
}
|
||||
|
||||
@ -32,6 +32,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
#define KEXT_OFFSET_STR_LEN 24
|
||||
|
||||
//
|
||||
// Kernel quirks array.
|
||||
//
|
||||
extern KERNEL_QUIRK gKernelQuirks[];
|
||||
|
||||
typedef struct PRELINKED_KEXT_ PRELINKED_KEXT;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -221,18 +221,48 @@ OcKernelLoadKextsAndReserve (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
OcKernelApplyQuirk (
|
||||
IN KERNEL_QUIRK_NAME Quirk,
|
||||
IN KERNEL_CACHE_TYPE CacheType,
|
||||
IN OUT VOID *Context,
|
||||
IN OUT PATCHER_CONTEXT *KernelPatcher
|
||||
)
|
||||
{
|
||||
//
|
||||
// Apply kernel quirks to kernel, kext patches to context.
|
||||
//
|
||||
if (Context == NULL) {
|
||||
ASSERT (KernelPatcher != NULL);
|
||||
|
||||
return KernelQuirkApply (Quirk, KernelPatcher);
|
||||
} else {
|
||||
if (CacheType == CacheTypeCacheless) {
|
||||
return CachelessContextAddQuirk ((CACHELESS_CONTEXT *) Context, Quirk);
|
||||
} else if (CacheType == CacheTypeMkext) {
|
||||
return MkextContextApplyQuirk ((MKEXT_CONTEXT *) Context, Quirk);
|
||||
} else if (CacheType == CacheTypePrelinked) {
|
||||
return PrelinkedContextApplyQuirk ((PRELINKED_CONTEXT *) Context, Quirk);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
OcKernelApplyPatches (
|
||||
IN OC_GLOBAL_CONFIG *Config,
|
||||
IN UINT32 DarwinVersion,
|
||||
IN PRELINKED_CONTEXT *Context,
|
||||
IN KERNEL_CACHE_TYPE CacheType,
|
||||
IN VOID *Context,
|
||||
IN OUT UINT8 *Kernel,
|
||||
IN UINT32 Size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PATCHER_CONTEXT Patcher;
|
||||
PATCHER_CONTEXT KernelPatcher;
|
||||
UINT32 Index;
|
||||
PATCHER_GENERIC_PATCH Patch;
|
||||
OC_KERNEL_PATCH_ENTRY *UserPatch;
|
||||
@ -248,7 +278,7 @@ OcKernelApplyPatches (
|
||||
ASSERT (Kernel != NULL);
|
||||
|
||||
Status = PatcherInitContextFromBuffer (
|
||||
&Patcher,
|
||||
&KernelPatcher,
|
||||
Kernel,
|
||||
Size
|
||||
);
|
||||
@ -285,21 +315,6 @@ OcKernelApplyPatches (
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsKernelPatch) {
|
||||
Status = PatcherInitContextFromPrelinked (
|
||||
&Patcher,
|
||||
Context,
|
||||
Target
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN, "OC: Kernel patcher %a (%a) init failure - %r\n", Target, Comment, Status));
|
||||
continue;
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OC: Kernel patcher %a (%a) init succeed\n", Target, Comment));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Ignore patch if:
|
||||
// - There is nothing to replace.
|
||||
@ -344,7 +359,18 @@ OcKernelApplyPatches (
|
||||
Patch.Skip = UserPatch->Skip;
|
||||
Patch.Limit = UserPatch->Limit;
|
||||
|
||||
Status = PatcherApplyGenericPatch (&Patcher, &Patch);
|
||||
if (IsKernelPatch) {
|
||||
Status = PatcherApplyGenericPatch (&KernelPatcher, &Patch);
|
||||
} else {
|
||||
if (CacheType == CacheTypeCacheless) {
|
||||
Status = CachelessContextAddPatch ((CACHELESS_CONTEXT *) Context, Target, &Patch);
|
||||
} else if (CacheType == CacheTypeMkext) {
|
||||
Status = MkextContextApplyPatch ((MKEXT_CONTEXT *) Context, Target, &Patch);
|
||||
} else if (CacheType == CacheTypePrelinked) {
|
||||
Status = PrelinkedContextApplyPatch ((PRELINKED_CONTEXT *) Context, Target, &Patch);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO,
|
||||
"OC: Kernel patcher result %u for %a (%a) - %r\n",
|
||||
@ -357,55 +383,58 @@ OcKernelApplyPatches (
|
||||
|
||||
if (!IsKernelPatch) {
|
||||
if (Config->Kernel.Quirks.AppleCpuPmCfgLock) {
|
||||
PatchAppleCpuPmCfgLock (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkAppleCpuPmCfgLock, CacheType, Context, NULL);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.ExternalDiskIcons) {
|
||||
PatchForceInternalDiskIcons (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkExternalDiskIcons, CacheType, Context, NULL);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.ThirdPartyDrives) {
|
||||
PatchThirdPartyDriveSupport (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkThirdPartyDrives, CacheType, Context, NULL);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.XhciPortLimit) {
|
||||
PatchUsbXhciPortLimit (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkXhciPortLimit1, CacheType, Context, NULL);
|
||||
OcKernelApplyQuirk (KernelQuirkXhciPortLimit2, CacheType, Context, NULL);
|
||||
OcKernelApplyQuirk (KernelQuirkXhciPortLimit3, CacheType, Context, NULL);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.DisableIoMapper) {
|
||||
PatchAppleIoMapperSupport (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkDisableIoMapper, CacheType, Context, NULL);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.DisableRtcChecksum) {
|
||||
PatchAppleRtcChecksum (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkDisableRtcChecksum, CacheType, Context, NULL);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.IncreasePciBarSize) {
|
||||
PatchIncreasePciBarSize (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkIncreasePciBarSize, CacheType, Context, NULL);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.CustomSmbiosGuid) {
|
||||
PatchCustomSmbiosGuid (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkCustomSmbiosGuid1, CacheType, Context, NULL);
|
||||
OcKernelApplyQuirk (KernelQuirkCustomSmbiosGuid2, CacheType, Context, NULL);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.DummyPowerManagement) {
|
||||
PatchDummyPowerManagement (Context);
|
||||
OcKernelApplyQuirk (KernelQuirkDummyPowerManagement, CacheType, Context, NULL);
|
||||
}
|
||||
} else {
|
||||
if (Config->Kernel.Quirks.AppleXcpmCfgLock) {
|
||||
PatchAppleXcpmCfgLock (&Patcher);
|
||||
OcKernelApplyQuirk (KernelQuirkAppleXcpmCfgLock, CacheType, NULL, &KernelPatcher);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.AppleXcpmExtraMsrs) {
|
||||
PatchAppleXcpmExtraMsrs (&Patcher);
|
||||
OcKernelApplyQuirk (KernelQuirkAppleXcpmExtraMsrs, CacheType, NULL, &KernelPatcher);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.AppleXcpmForceBoost) {
|
||||
PatchAppleXcpmForceBoost (&Patcher);
|
||||
OcKernelApplyQuirk (KernelQuirkAppleXcpmForceBoost, CacheType, NULL, &KernelPatcher);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.PanicNoKextDump) {
|
||||
PatchPanicKextDump (&Patcher);
|
||||
OcKernelApplyQuirk (KernelQuirkPanicNoKextDump, CacheType, NULL, &KernelPatcher);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Emulate.Cpuid1Data[0] != 0
|
||||
@ -413,7 +442,7 @@ OcKernelApplyPatches (
|
||||
|| Config->Kernel.Emulate.Cpuid1Data[2] != 0
|
||||
|| Config->Kernel.Emulate.Cpuid1Data[3] != 0) {
|
||||
PatchKernelCpuId (
|
||||
&Patcher,
|
||||
&KernelPatcher,
|
||||
mOcCpuInfo,
|
||||
Config->Kernel.Emulate.Cpuid1Data,
|
||||
Config->Kernel.Emulate.Cpuid1Mask
|
||||
@ -421,11 +450,11 @@ OcKernelApplyPatches (
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.LapicKernelPanic) {
|
||||
PatchLapicKernelPanic (&Patcher);
|
||||
OcKernelApplyQuirk (KernelQuirkLapicKernelPanic, CacheType, NULL, &KernelPatcher);
|
||||
}
|
||||
|
||||
if (Config->Kernel.Quirks.PowerTimeoutKernelPanic) {
|
||||
PatchPowerStateTimeout (&Patcher);
|
||||
OcKernelApplyQuirk (KernelQuirkPowerTimeoutKernelPanic, CacheType, NULL, &KernelPatcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -522,7 +551,7 @@ OcKernelProcessPrelinked (
|
||||
Status = PrelinkedContextInit (&Context, Kernel, *KernelSize, AllocatedSize);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
OcKernelApplyPatches (Config, DarwinVersion, &Context, NULL, 0);
|
||||
OcKernelApplyPatches (Config, DarwinVersion, CacheTypePrelinked, &Context, NULL, 0);
|
||||
|
||||
OcKernelBlockKexts (Config, DarwinVersion, &Context);
|
||||
|
||||
@ -640,6 +669,8 @@ OcKernelProcessMkext (
|
||||
return Status;
|
||||
}
|
||||
|
||||
OcKernelApplyPatches (Config, DarwinVersion, CacheTypeMkext, &Context, NULL, 0);
|
||||
|
||||
for (Index = 0; Index < Config->Kernel.Add.Count; ++Index) {
|
||||
Kext = Config->Kernel.Add.Values[Index];
|
||||
|
||||
@ -768,6 +799,11 @@ OcKernelInitCacheless (
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Process patches and blocks.
|
||||
//
|
||||
OcKernelApplyPatches (Config, DarwinVersion, CacheTypeCacheless, Context, NULL, 0);
|
||||
|
||||
return CachelessContextOverlayExtensionsDir (Context, File);
|
||||
}
|
||||
|
||||
@ -884,7 +920,7 @@ OcKernelFileOpen (
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
mOcDarwinVersion = OcKernelReadDarwinVersion (Kernel, KernelSize);
|
||||
OcKernelApplyPatches (mOcConfiguration, mOcDarwinVersion, NULL, Kernel, KernelSize);
|
||||
OcKernelApplyPatches (mOcConfiguration, mOcDarwinVersion, 0, NULL, Kernel, KernelSize);
|
||||
|
||||
PrelinkedStatus = OcKernelProcessPrelinked (
|
||||
mOcConfiguration,
|
||||
|
||||
@ -12,15 +12,29 @@ OBJS = $(PROJECT).o \
|
||||
KxldState.o \
|
||||
PrelinkedKext.o \
|
||||
PrelinkedContext.o \
|
||||
MkextContext.o \
|
||||
MkextReader.o \
|
||||
Vtables.o \
|
||||
Link.o \
|
||||
KernelReader.o \
|
||||
KernelCollection.o \
|
||||
DataPatcher.o \
|
||||
lzss.o \
|
||||
lzvn.o
|
||||
lzvn.o \
|
||||
adler32.o \
|
||||
compress.o \
|
||||
crc32.o \
|
||||
deflate.o \
|
||||
infback.o \
|
||||
inffast.o \
|
||||
inflate.o \
|
||||
inftrees.o \
|
||||
trees.o \
|
||||
uncompr.o \
|
||||
zlib_uefi.o
|
||||
VPATH = ../../Library/OcAppleKernelLib:$\
|
||||
../../Library/OcMiscLib:$\
|
||||
../../Library/OcCompressionLib/lzss:$\
|
||||
../../Library/OcCompressionLib/lzvn
|
||||
../../Library/OcCompressionLib/lzvn:$\
|
||||
../../Library/OcCompressionLib/zlib
|
||||
include ../../User/Makefile
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user