Skip to content

Commit

Permalink
Fixed a rare kernel panic due to use-after-free in verb code at wakin…
Browse files Browse the repository at this point in the history
…g from sleep
  • Loading branch information
vit9696 committed Apr 7, 2018
1 parent fa2b9a0 commit 7e24205
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 19 deletions.
4 changes: 2 additions & 2 deletions AppleALC.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@
MODULE_NAME = as.vit9696.AppleALC;
MODULE_START = "$(PRODUCT_NAME)_kern_start";
MODULE_STOP = "$(PRODUCT_NAME)_kern_stop";
MODULE_VERSION = 1.2.5;
MODULE_VERSION = 1.2.6;
OTHER_CFLAGS = (
"-mmmx",
"-msse",
Expand Down Expand Up @@ -567,7 +567,7 @@
MODULE_NAME = as.vit9696.AppleALC;
MODULE_START = "$(PRODUCT_NAME)_kern_start";
MODULE_STOP = "$(PRODUCT_NAME)_kern_stop";
MODULE_VERSION = 1.2.5;
MODULE_VERSION = 1.2.6;
OTHER_CFLAGS = (
"-mmmx",
"-msse",
Expand Down
23 changes: 12 additions & 11 deletions AppleALC/kern_alc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,19 @@ IOReturn AlcEnabler::performPowerChange(IOService *hdaDriver, ALCAudioDevicePowe
DBGLOG("alc", "performPowerChange %s from %d to %d in from sleep %d hdef %d detect %d",
safeString(hdaDriver->getName()), from, to, callbackAlc->receivedSleepEvent, valid, callbackAlc->hasHDAConfigDefault);
ret = callbackAlc->orgPerformPowerChange(hdaDriver, from, to, timer);
if (valid && callbackAlc->hasHDAConfigDefault == WakeVerbMode::Enable && callbackAlc->hdaCodecInstance) {
if (valid && callbackAlc->hasHDAConfigDefault == WakeVerbMode::Enable) {
if (to == ALCAudioDeviceSleep) {
callbackAlc->receivedSleepEvent = true;
} else if (callbackAlc->receivedSleepEvent &&
(to == ALCAudioDeviceIdle || to == ALCAudioDeviceActive)) {
auto forceRet = callbackAlc->orgInitializePinConfig(callbackAlc->hdaCodecInstance, ADDPR(selfInstance));
SYSLOG_COND(forceRet != kIOReturnSuccess, "alc", "force config reinitialize returned %08X", forceRet);
auto parent = OSDynamicCast(IOService, hdaDriver->getParentEntry(gIOServicePlane));
if (parent) {
DBGLOG("alc", "performPowerChange %s forcing wake verbs on %s", safeString(hdaDriver->getName()), safeString(parent->getName()));
auto forceRet = callbackAlc->orgInitializePinConfig(parent, ADDPR(selfInstance));
SYSLOG_COND(forceRet != kIOReturnSuccess, "alc", "force config reinitialize returned %08X", forceRet);
} else {
SYSLOG("alc", "cannot get hda driver parent for wake");
}
callbackAlc->receivedSleepEvent = false;
}
}
Expand All @@ -115,13 +121,8 @@ IOReturn AlcEnabler::initializePinConfig(IOService *hdaCodec, IOService *configD
IOReturn ret = kIOReturnError;
if (callbackAlc && callbackAlc->orgInitializePinConfig && configDevice) {
bool valid = isAnalogAudio(hdaCodec);
if (valid) {
// Preserve codec instance for sleep invocations
callbackAlc->hdaCodecInstance = hdaCodec;
}

DBGLOG("alc", "initializePinConfig received hda " PRIKADDR ", config " PRIKADDR " config name %s, detect %d valid %d", CASTKADDR(hdaCodec),
CASTKADDR(configDevice), configDevice ? safeString(configDevice->getName()) : "(null config)", callbackAlc->hasHDAConfigDefault, valid);
DBGLOG("alc", "initializePinConfig %s received hda " PRIKADDR ", config " PRIKADDR " config name %s, detect %d valid %d", safeString(hdaCodec->getName()),
CASTKADDR(hdaCodec), CASTKADDR(configDevice), configDevice ? safeString(configDevice->getName()) : "(null config)", callbackAlc->hasHDAConfigDefault, valid);

if (valid && callbackAlc->hasHDAConfigDefault == WakeVerbMode::Detect) {
uint32_t analogCodec = 0;
Expand Down Expand Up @@ -273,7 +274,7 @@ void AlcEnabler::processKext(KernelPatcher &patcher, size_t index, mach_vm_addre
}

if (info->platformNum > 0 || info->layoutNum > 0) {
DBGLOG("alc", "will route callbacks resource loading callbacks");
DBGLOG("alc", "will route resource loading callbacks");
progressState |= ProcessingState::CallbacksWantRouting;
}

Expand Down
5 changes: 0 additions & 5 deletions AppleALC/kern_alc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,6 @@ class AlcEnabler {
* Marks HDAConfigDefault availability in AppleALC
*/
WakeVerbMode hasHDAConfigDefault {WakeVerbMode::Detect};

/**
* AppleHDACodecGeneric instance
*/
IOService *hdaCodecInstance {nullptr};
};

#endif /* kern_alc_hpp */
5 changes: 4 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
AppleALC Changelog
==================
#### v1.2.6
- Fixed a rare kernel panic due to use-after-free in verb code at waking from sleep

#### v1.2.5
- Implemented verb execution after wake (via `WakeVerbReinit` in PinConfigs), obsoletes CodecCommander in fixed resources
- Implemented custom verbs for wake (via `WakeConfigData` in PinConfigs), `ConfigData` is used by default
Expand All @@ -13,7 +16,7 @@ AppleALC Changelog
- Added EAPD wake verbs to all ALC 221, 225, 233, 235, 236, 255, 256, 270, 271, 272, 284, 286, 288, 290, 293, 295 by Vandroiy
- Added EAPD wake verbs to some ALC 269, 275, 280, 282, 283, 292, 294, 298, 662, 663, 668, 887, 888, 889, 892, 898, 1150 by Vandroiy
- Fixed broken AFGLowPowerState, LayouID and other fields in several PinConfigs info.plist
- Fixed kernel rare kernel panics due to short incompatible HDEF controller patches affecting other code
- Fixed rare kernel panics due to short incompatible HDEF controller patches affecting other code

#### v1.2.4
- Added ALC269 layout-id 10 (toleda) for Brix by ttimasdf
Expand Down

0 comments on commit 7e24205

Please sign in to comment.