Skip to content

Commit 7e24205

Browse files
committed
Fixed a rare kernel panic due to use-after-free in verb code at waking from sleep
1 parent fa2b9a0 commit 7e24205

File tree

4 files changed

+18
-19
lines changed

4 files changed

+18
-19
lines changed

AppleALC.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@
522522
MODULE_NAME = as.vit9696.AppleALC;
523523
MODULE_START = "$(PRODUCT_NAME)_kern_start";
524524
MODULE_STOP = "$(PRODUCT_NAME)_kern_stop";
525-
MODULE_VERSION = 1.2.5;
525+
MODULE_VERSION = 1.2.6;
526526
OTHER_CFLAGS = (
527527
"-mmmx",
528528
"-msse",
@@ -567,7 +567,7 @@
567567
MODULE_NAME = as.vit9696.AppleALC;
568568
MODULE_START = "$(PRODUCT_NAME)_kern_start";
569569
MODULE_STOP = "$(PRODUCT_NAME)_kern_stop";
570-
MODULE_VERSION = 1.2.5;
570+
MODULE_VERSION = 1.2.6;
571571
OTHER_CFLAGS = (
572572
"-mmmx",
573573
"-msse",

AppleALC/kern_alc.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,19 @@ IOReturn AlcEnabler::performPowerChange(IOService *hdaDriver, ALCAudioDevicePowe
9595
DBGLOG("alc", "performPowerChange %s from %d to %d in from sleep %d hdef %d detect %d",
9696
safeString(hdaDriver->getName()), from, to, callbackAlc->receivedSleepEvent, valid, callbackAlc->hasHDAConfigDefault);
9797
ret = callbackAlc->orgPerformPowerChange(hdaDriver, from, to, timer);
98-
if (valid && callbackAlc->hasHDAConfigDefault == WakeVerbMode::Enable && callbackAlc->hdaCodecInstance) {
98+
if (valid && callbackAlc->hasHDAConfigDefault == WakeVerbMode::Enable) {
9999
if (to == ALCAudioDeviceSleep) {
100100
callbackAlc->receivedSleepEvent = true;
101101
} else if (callbackAlc->receivedSleepEvent &&
102102
(to == ALCAudioDeviceIdle || to == ALCAudioDeviceActive)) {
103-
auto forceRet = callbackAlc->orgInitializePinConfig(callbackAlc->hdaCodecInstance, ADDPR(selfInstance));
104-
SYSLOG_COND(forceRet != kIOReturnSuccess, "alc", "force config reinitialize returned %08X", forceRet);
103+
auto parent = OSDynamicCast(IOService, hdaDriver->getParentEntry(gIOServicePlane));
104+
if (parent) {
105+
DBGLOG("alc", "performPowerChange %s forcing wake verbs on %s", safeString(hdaDriver->getName()), safeString(parent->getName()));
106+
auto forceRet = callbackAlc->orgInitializePinConfig(parent, ADDPR(selfInstance));
107+
SYSLOG_COND(forceRet != kIOReturnSuccess, "alc", "force config reinitialize returned %08X", forceRet);
108+
} else {
109+
SYSLOG("alc", "cannot get hda driver parent for wake");
110+
}
105111
callbackAlc->receivedSleepEvent = false;
106112
}
107113
}
@@ -115,13 +121,8 @@ IOReturn AlcEnabler::initializePinConfig(IOService *hdaCodec, IOService *configD
115121
IOReturn ret = kIOReturnError;
116122
if (callbackAlc && callbackAlc->orgInitializePinConfig && configDevice) {
117123
bool valid = isAnalogAudio(hdaCodec);
118-
if (valid) {
119-
// Preserve codec instance for sleep invocations
120-
callbackAlc->hdaCodecInstance = hdaCodec;
121-
}
122-
123-
DBGLOG("alc", "initializePinConfig received hda " PRIKADDR ", config " PRIKADDR " config name %s, detect %d valid %d", CASTKADDR(hdaCodec),
124-
CASTKADDR(configDevice), configDevice ? safeString(configDevice->getName()) : "(null config)", callbackAlc->hasHDAConfigDefault, valid);
124+
DBGLOG("alc", "initializePinConfig %s received hda " PRIKADDR ", config " PRIKADDR " config name %s, detect %d valid %d", safeString(hdaCodec->getName()),
125+
CASTKADDR(hdaCodec), CASTKADDR(configDevice), configDevice ? safeString(configDevice->getName()) : "(null config)", callbackAlc->hasHDAConfigDefault, valid);
125126

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

275276
if (info->platformNum > 0 || info->layoutNum > 0) {
276-
DBGLOG("alc", "will route callbacks resource loading callbacks");
277+
DBGLOG("alc", "will route resource loading callbacks");
277278
progressState |= ProcessingState::CallbacksWantRouting;
278279
}
279280

AppleALC/kern_alc.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,6 @@ class AlcEnabler {
268268
* Marks HDAConfigDefault availability in AppleALC
269269
*/
270270
WakeVerbMode hasHDAConfigDefault {WakeVerbMode::Detect};
271-
272-
/**
273-
* AppleHDACodecGeneric instance
274-
*/
275-
IOService *hdaCodecInstance {nullptr};
276271
};
277272

278273
#endif /* kern_alc_hpp */

Changelog.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
AppleALC Changelog
22
==================
3+
#### v1.2.6
4+
- Fixed a rare kernel panic due to use-after-free in verb code at waking from sleep
5+
36
#### v1.2.5
47
- Implemented verb execution after wake (via `WakeVerbReinit` in PinConfigs), obsoletes CodecCommander in fixed resources
58
- Implemented custom verbs for wake (via `WakeConfigData` in PinConfigs), `ConfigData` is used by default
@@ -13,7 +16,7 @@ AppleALC Changelog
1316
- 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
1417
- 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
1518
- Fixed broken AFGLowPowerState, LayouID and other fields in several PinConfigs info.plist
16-
- Fixed kernel rare kernel panics due to short incompatible HDEF controller patches affecting other code
19+
- Fixed rare kernel panics due to short incompatible HDEF controller patches affecting other code
1720

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

0 commit comments

Comments
 (0)