From 4b00ad2c1cd2112d14d9f5543e8b80415aca9aea Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sun, 23 Aug 2020 00:25:52 +0300 Subject: [PATCH] OcAppleKernelLib: Improve error checking for kernel quirks (part 1) --- Docs/Configuration.tex | 15 +++ Library/OcAppleKernelLib/CommonPatches.c | 79 +++++++++++- Utilities/TestKextInject/KextInject.c | 145 +++++++++++++++++++++++ 3 files changed, 233 insertions(+), 6 deletions(-) diff --git a/Docs/Configuration.tex b/Docs/Configuration.tex index cbbe7f2b..d0746dab 100755 --- a/Docs/Configuration.tex +++ b/Docs/Configuration.tex @@ -2042,6 +2042,7 @@ blocking. \texttt{AppleCpuPmCfgLock}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: FIXME\\ \textbf{Description}: Disables \texttt{PKG\_CST\_CONFIG\_CONTROL} (\texttt{0xE2}) MSR modification in AppleIntelCPUPowerManagement.kext, commonly causing early kernel panic, when it is locked from writing. @@ -2081,6 +2082,7 @@ blocking. \texttt{AppleXcpmCfgLock}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.8 (not required for older)\\ \textbf{Description}: Disables \texttt{PKG\_CST\_CONFIG\_CONTROL} (\texttt{0xE2}) MSR modification in XNU kernel, commonly causing early kernel panic, when it is locked from writing (XCPM power management). @@ -2092,6 +2094,7 @@ blocking. \texttt{AppleXcpmExtraMsrs}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.8 (not required for older)\\ \textbf{Description}: Disables multiple MSR access critical for select CPUs, which have no native XCPM support. @@ -2106,6 +2109,7 @@ blocking. \texttt{AppleXcpmForceBoost}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.8 (not required for older)\\ \textbf{Description}: Forces maximum performance in XCPM mode. This patch writes \texttt{0xFF00} to \texttt{MSR\_IA32\_PERF\_CONTROL} (\texttt{0x199}), @@ -2119,6 +2123,7 @@ blocking. \texttt{CustomSMBIOSGuid}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.6 (64-bit)\\ \textbf{Description}: Performs GUID patching for \texttt{UpdateSMBIOSMode} \texttt{Custom} mode. Usually relevant for Dell laptops. @@ -2126,6 +2131,7 @@ blocking. \texttt{DisableIoMapper}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.8 (not required for older)\\ \textbf{Description}: Disables \texttt{IOMapper} support in XNU (VT-d), which may conflict with the firmware implementation. @@ -2137,6 +2143,7 @@ blocking. \texttt{DisableRtcChecksum}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.6 (64-bit)\\ \textbf{Description}: Disables primary checksum (\texttt{0x58}-\texttt{0x59}) writing in AppleRTC. @@ -2152,6 +2159,7 @@ blocking. \texttt{DummyPowerManagement}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.6 (64-bit)\\ \textbf{Description}: Disables \texttt{AppleIntelCpuPowerManagement}. \emph{Note}: This option is a preferred alternative to @@ -2162,6 +2170,7 @@ blocking. \texttt{ExternalDiskIcons}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.6 (64-bit)\\ \textbf{Description}: Apply icon type patches to AppleAHCIPort.kext to force internal disk icons for all AHCI disks. @@ -2172,6 +2181,7 @@ blocking. \texttt{IncreasePciBarSize}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: FIXME\\ \textbf{Description}: Increases 32-bit PCI bar size in IOPCIFamily from 1 to 4 GBs. \emph{Note}: This option should be avoided whenever possible. In general the necessity @@ -2181,12 +2191,14 @@ blocking. \texttt{LapicKernelPanic}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: FIXME\\ \textbf{Description}: Disables kernel panic on LAPIC interrupts. \item \texttt{PanicNoKextDump}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.13 (not required for older)\\ \textbf{Description}: Prevent kernel from printing kext dump in the panic log preventing from observing panic details. Affects 10.13 and above. @@ -2194,6 +2206,7 @@ blocking. \texttt{PowerTimeoutKernelPanic}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.15 (not required for older)\\ \textbf{Description}: Disables kernel panic on setPowerState timeout. An additional security measure was added to macOS Catalina (10.15) causing @@ -2206,6 +2219,7 @@ blocking. \texttt{ThirdPartyDrives}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: 10.6 (not required for older)\\ \textbf{Description}: Apply vendor patches to IOAHCIBlockStorage.kext to enable native features for third-party drives, such as TRIM on SSDs or hibernation support on 10.15 and newer. @@ -2220,6 +2234,7 @@ blocking. \texttt{XhciPortLimit}\\ \textbf{Type}: \texttt{plist\ boolean}\\ \textbf{Failsafe}: \texttt{false}\\ + \textbf{Requirement}: FIXME\\ \textbf{Description}: Patch various kexts (AppleUSBXHCI.kext, AppleUSBXHCIPCI.kext, IOUSBHostFamily.kext) to remove USB port count limit of 15 ports. diff --git a/Library/OcAppleKernelLib/CommonPatches.c b/Library/OcAppleKernelLib/CommonPatches.c index c367c13c..87313f82 100644 --- a/Library/OcAppleKernelLib/CommonPatches.c +++ b/Library/OcAppleKernelLib/CommonPatches.c @@ -210,6 +210,11 @@ PatchAppleXcpmCfgLock ( UINT32 Replacements; + if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_MOUNTAIN_LION_MIN, 0)) { + DEBUG ((DEBUG_INFO, "OCAK: Skipping XcpmCfgLock on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + Last = (XCPM_MSR_RECORD *) ((UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext) + MachoGetFileSize (&Patcher->MachContext) - sizeof (XCPM_MSR_RECORD)); @@ -334,6 +339,11 @@ PatchAppleXcpmExtraMsrs ( XCPM_MSR_RECORD *Last; UINT32 Replacements; + if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_MOUNTAIN_LION_MIN, 0)) { + DEBUG ((DEBUG_INFO, "OCAK: Skipping XcpmExtraMsrs on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + Last = (XCPM_MSR_RECORD *) ((UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext) + MachoGetFileSize (&Patcher->MachContext) - sizeof (XCPM_MSR_RECORD)); @@ -454,6 +464,11 @@ PatchAppleXcpmForceBoost ( UINT8 *Last; UINT8 *Current; + if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_MOUNTAIN_LION_MIN, 0)) { + DEBUG ((DEBUG_INFO, "OCAK: Skipping XcpmForceBoost on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + Start = (UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext); Last = Start + MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE*2; Start += EFI_PAGE_SIZE; @@ -657,6 +672,15 @@ PatchUsbXhciPortLimit2 ( DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.usb.AppleUSBXHCI - %r\n", Status)); } + // + // TODO: Check when the patch changed actually. + // + if (EFI_ERROR (Status) + && OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_HIGH_SIERRA_MIN, KERNEL_VERSION_HIGH_SIERRA_MAX)) { + DEBUG ((DEBUG_INFO, "OCAK: Assuming success for AppleUSBXHCI on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + return Status; } @@ -669,6 +693,11 @@ PatchUsbXhciPortLimit3 ( { EFI_STATUS Status; + if (!OcMatchDarwinVersion (KernelVersion, 0, KERNEL_VERSION_HIGH_SIERRA_MAX)) { + DEBUG ((DEBUG_INFO, "OCAK: Skipping legacy port patch AppleUSBXHCIPCI on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + // // If we are here, we are on legacy 10.13 or below, try the oldest patch. // @@ -679,6 +708,15 @@ PatchUsbXhciPortLimit3 ( DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.usb.AppleUSBXHCIPCI\n")); } + // + // TODO: Check when the patch changed actually. + // + if (EFI_ERROR (Status) + && OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_HIGH_SIERRA_MIN, KERNEL_VERSION_HIGH_SIERRA_MAX)) { + DEBUG ((DEBUG_INFO, "OCAK: Assuming success for AppleUSBXHCIPCI on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + return Status; } @@ -743,19 +781,33 @@ PatchThirdPartyDriveSupport ( { EFI_STATUS Status; - 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, &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")); + } + if (OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_CATALINA_MIN, 0)) { 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: Skipping IOAHCIBlockStorage V2 on %u\n", KernelVersion)); + } + + // + // This started to be required on 10.6.7 or so. + // We cannot trust which minor SnowLeo version is this, just let it pass. + // + if (EFI_ERROR (Status) + && OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_SNOW_LEOPARD_MIN, KERNEL_VERSION_SNOW_LEOPARD_MAX)) { + DEBUG ((DEBUG_INFO, "OCAK: Assuming success for IOAHCIBlockStorage on %u\n", KernelVersion)); + return EFI_SUCCESS; + } return Status; } @@ -840,6 +892,11 @@ PatchAppleIoMapperSupport ( { EFI_STATUS Status; + if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_MOUNTAIN_LION_MIN, 0)) { + DEBUG ((DEBUG_INFO, "OCAK: Skipping AppleIoMapper patch on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + Status = PatcherApplyGenericPatch (Patcher, &mAppleIoMapperPatch); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOPCIFamily AppleIoMapper - %r\n", Status)); @@ -1505,6 +1562,11 @@ PatchPanicKextDump ( UINT8 *Record; UINT8 *Last; + if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_HIGH_SIERRA_MIN, 0)) { + DEBUG ((DEBUG_INFO, "OCAK: Skipping XcpmCfgLock on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + Last = ((UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext) + MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE); @@ -1724,6 +1786,11 @@ PatchPowerStateTimeout ( { EFI_STATUS Status; + if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_CATALINA_MIN, 0)) { + DEBUG ((DEBUG_INFO, "OCAK: Skipping power state patch on %u\n", KernelVersion)); + return EFI_SUCCESS; + } + Status = PatcherApplyGenericPatch (Patcher, &mPowerStateTimeoutPanicMasterPatch); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "OCAK: Failed to apply power state patch - %r\n", Status)); diff --git a/Utilities/TestKextInject/KextInject.c b/Utilities/TestKextInject/KextInject.c index 71f020b0..ae432cfd 100644 --- a/Utilities/TestKextInject/KextInject.c +++ b/Utilities/TestKextInject/KextInject.c @@ -283,6 +283,102 @@ ApplyKextPatches ( DEBUG ((DEBUG_WARN, "[FAIL] Failed to find com.apple.iokit.IOHIDFamily - %r\n", Status)); FailedToProcess = TRUE; } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkAppleCpuPmCfgLock, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkAppleCpuPmCfgLock - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkAppleCpuPmCfgLock\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkExternalDiskIcons, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkExternalDiskIcons - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkExternalDiskIcons\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkThirdPartyDrives, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkThirdPartyDrives - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkThirdPartyDrives\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkDisableIoMapper, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkDisableIoMapper - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkDisableIoMapper\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkDisableRtcChecksum, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkDisableRtcChecksum - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkDisableRtcChecksum\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkIncreasePciBarSize, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkIncreasePciBarSize - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkIncreasePciBarSize\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkDummyPowerManagement, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkDummyPowerManagement - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkDummyPowerManagement\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkXhciPortLimit1, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkXhciPortLimit1 - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkXhciPortLimit1\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkXhciPortLimit2, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkXhciPortLimit2 - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkXhciPortLimit2\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkXhciPortLimit3, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkXhciPortLimit3 - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkXhciPortLimit3\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkCustomSmbiosGuid1, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkCustomSmbiosGuid1 - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkCustomSmbiosGuid1\n")); + } + + Status = PrelinkedContextApplyQuirk (Context, KernelQuirkCustomSmbiosGuid2, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply KernelQuirkCustomSmbiosGuid2 - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] Success KernelQuirkCustomSmbiosGuid2\n")); + } } VOID @@ -326,6 +422,55 @@ ApplyKernelPatches ( } else { DEBUG ((DEBUG_WARN, "[OK] CPUID kernel patch\n")); } + + Status = KernelApplyQuirk (KernelQuirkAppleXcpmCfgLock, &Patcher, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] KernelQuirkAppleXcpmCfgLock - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] KernelQuirkAppleXcpmCfgLock patch\n")); + } + + Status = KernelApplyQuirk (KernelQuirkAppleXcpmExtraMsrs, &Patcher, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] KernelQuirkAppleXcpmExtraMsrs - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] KernelQuirkAppleXcpmExtraMsrs patch\n")); + } + + Status = KernelApplyQuirk (KernelQuirkAppleXcpmForceBoost, &Patcher, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] KernelQuirkAppleXcpmForceBoost - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] KernelQuirkAppleXcpmForceBoost patch\n")); + } + + Status = KernelApplyQuirk (KernelQuirkPanicNoKextDump, &Patcher, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] KernelQuirkPanicNoKextDump - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] KernelQuirkPanicNoKextDump patch\n")); + } + + Status = KernelApplyQuirk (KernelQuirkLapicKernelPanic, &Patcher, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] KernelQuirkLapicKernelPanic - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] KernelQuirkLapicKernelPanic patch\n")); + } + + + Status = KernelApplyQuirk (KernelQuirkPowerTimeoutKernelPanic, &Patcher, KernelVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "[FAIL] KernelQuirkPowerTimeoutKernelPanic - %r\n", Status)); + FailedToProcess = TRUE; + } else { + DEBUG ((DEBUG_WARN, "[OK] KernelQuirkPowerTimeoutKernelPanic patch\n")); + } } else { DEBUG ((DEBUG_WARN, "Failed to find kernel - %r\n", Status)); FailedToProcess = TRUE; -- GitLab