Advisories

Affected Software

macOS BigSur 11.0 - 11.2.3

Severity of the bug

High

Description of the vulnerability

smbfs is a kext driver which handles SMB connection between the user and SMB Server. This vulnerability occurs in smbfs, which allows attacker can escalate from user permission into root privilege.

Technical Details

smbfs kext was implemented with chardev device styles. User can interact with smbfs kext via ioctl syscall to do some task.

smbfs only load when the user first connects to the SMB server. After that, the attacker can easily load it with user privilege via NetFSMountURLSync from NetFS Framework.

From user-mode, the user can initialize a connection to the SMB server via SMBIOC_NEGOTIATE

	switch (cmd) {
		case SMBIOC_FIND_SESSION:
		case SMBIOC_NEGOTIATE:
		{
			int searchOnly = (cmd == SMBIOC_FIND_SESSION) ? TRUE : FALSE;
			struct smbioc_negotiate * vspec = (struct smbioc_negotiate *)data;
			
			/* protect against anyone else playing with the smb dev structure */
			lck_rw_lock_exclusive(&sdp->sd_rwlock);

            /* free global lock now since we now have sd_rwlock */
            lck_rw_unlock_shared(dev_rw_lck);

            /* Make sure the version matches */
			if (vspec->ioc_version != SMB_IOC_STRUCT_VERSION) {
				error = EINVAL;
			} else if (sdp->sd_session || sdp->sd_share) {
				error = EISCONN;
			} else {
				error = smb_usr_negotiate(vspec, context, sdp, searchOnly);				
			}
            
			lck_rw_unlock_exclusive(&sdp->sd_rwlock);
			break;
		}

From there, SMBIOC_NEGOTIATE will take user input and then pass it into smb_usr_negotiate. This function will first validate the user input and copy some user-mode pointer into the kernel-mode buffer. This is to prevent TOCTOU bug class and then call smb_sm_negotiate to connect to the SMB server.

int smb_sm_negotiate(struct smbioc_negotiate *session_spec,
                     vfs_context_t context, struct smb_session **sessionpp,
                     struct smb_dev *sdp, int searchOnly, uint32_t *matched_dns)
{
	//...
        
		error = smb_sm_lookupint(saddr,
                                 session_spec->ioc_ssn.ioc_owner,
                                 session_spec->ioc_user,
                                 session_spec->ioc_userflags,
                                 dns_name,
                                 matched_dns,
                                 session_spec->ioc_extra_flags,
                                 &sessionp);
	
	//...
		
	if ((error == 0) || (searchOnly)) {
		SMB_FREE(saddr, M_SMBDATA);
		saddr = NULL;
		session_spec->ioc_extra_flags |= SMB_SHARING_SESSION;
	} else {
		/* NetBIOS connections require a local address */
		if (saddr->sa_family == AF_NETBIOS) {
			laddr = smb_memdupin(session_spec->ioc_kern_laddr, session_spec->ioc_laddr_len);
			if (laddr == NULL) {
				SMB_FREE(saddr, M_SMBDATA);
				saddr = NULL;
				return ENOMEM;
			}
		}
		/* If smb_session_create fails it will clean up saddr and laddr */
		error = smb_session_create(session_spec, saddr, laddr, context, &sessionp);
		//...
	}
}

smb_sm_negotiate will lookup session_spec->ioc_user from user mode to check if session exists or not. If not, this function will call smb_session_create, which creates a new session object that handles all packages sent or received between client and server.

static int smb_session_create(struct smbioc_negotiate *session_spec, 
						 struct sockaddr *saddr, struct sockaddr *laddr,
						 vfs_context_t context, struct smb_session **sessionpp)
{
	//...

    if (!error)
		error = smb_iod_create(sessionp);
	if (error) {
		smb_session_put(sessionp, context);
		return error;
	}

	//...
}

smb_session_create is also creating a sub struct called iod. This struct is managing to send or receive message between client and server. smb_iod_create will init some iod struct field and then start two kernel threads smb_iod_thread and smb_iod_lease_thread.

int
smb_iod_create(struct smb_session *sessionp)
{
	struct smbiod	*iod;
	SMB_MALLOC(iod, struct smbiod *, sizeof(*iod), M_SMBIOD, M_WAITOK | M_ZERO);
	//...
	iod->iod_session = sessionp;
	//...

	result = kernel_thread_start((thread_continue_t)smb_iod_thread, iod, &thread);

	//...

	result = kernel_thread_start((thread_continue_t)smb_iod_lease_thread, iod, &thread);
}

smb_iod_thread is a workqueue event that receives an event from kernel_task and executes this event. This thread actually does network task with SMB server via event queue by calling function smb_session_negotiate from kernel_task. smb_session_negotiate will wait until smb_iod_thread return the result of SMBIOD_EV_NEGOTIATE

int smb_session_negotiate(struct smb_session *sessionp, vfs_context_t context)
{
	return smb_iod_request(sessionp->session_iod,
			       SMBIOD_EV_NEGOTIATE | SMBIOD_EV_SYNC, context);
}

Returning to smb_iod_thread thread SMBIOD_EV_NEGOTIATE starts another thread smb_iod_read_thread which a worker receives packages from SMB Server.

static int
smb_iod_negotiate(struct smbiod *iod, vfs_context_t user_context)
{
	//...

	error = SMB_TRAN_CREATE(sessionp);
	if (error) {
		goto errorOut;
	}

	/*
     * Start up read thread if not already running
     */
    SMB_IOD_FLAGSLOCK(iod);
    if (!(iod->iod_flags & SMBIOD_READ_THREAD_RUNNING)) {
        SMBIODEBUG("Starting read thread \n");
        result = kernel_thread_start((thread_continue_t)smb_iod_read_thread,
                                     iod, &thread);
        if (result != KERN_SUCCESS) {
            // ..
            goto errorOut;
        }
        else {
            thread_deallocate(thread);
        }
    }
    SMB_IOD_FLAGSUNLOCK(iod);

	...

	error = SMB_TRAN_CONNECT(sessionp, sessionp->session_saddr);
	if (error == 0) {
		iod->iod_state = SMBIOD_ST_TRANACTIVE;
		SMBIODEBUG("tconnect\n");

        /* Wake up the read thread */
        smb_iod_wakeup(iod);

        error = smb_smb_negotiate(sessionp, user_context, FALSE, iod->iod_context);
	}
	if (error) {
		goto errorOut;
	}
	iod->iod_state = SMBIOD_ST_NEGOACTIVE;
	SMBIODEBUG("completed\n");
	smb_iod_invrq(iod);
	return 0;

errorOut:
	smb_iod_dead(iod, 0);
	return error;
}

smb_iod_thread starts smb_iod_read_thread then begin to connect to SMB Server. If the connection was ok, it would wake up smb_iod_read_thread from the thread queue to begin receiving data from the SMB server and parse it via smb_smb_negotiate. Otherwise, smb_iod_dead will signal smb_iod_read_thread to stop.

static void
smb_iod_closetran(struct smbiod *iod, int from_read_thread)
{
	//...
	SMB_IOD_FLAGSLOCK(iod);
	for (;;) {
		if (!(iod->iod_flags & SMBIOD_READ_THREAD_RUNNING)) {
			SMB_IOD_FLAGSUNLOCK(iod);
			break;
		}

		/* Tell read thread to exit */
		iod->iod_flags |= SMBIOD_READ_THREAD_STOP;
		wakeup(&(iod->iod_flags));

		msleep(iod, SMB_IOD_FLAGSLOCKPTR(iod), PWAIT,
				"iod-wait-read-exit", 0);
	}

	/* This will free the tcp transport! */
	SMB_TRAN_DONE(sessionp);
}

After that, smb_iod_thread return the error code to kernel_task. Back to function smb_sm_negotiate after receiving error code from smb_iod_thread

int smb_sm_negotiate(struct smbioc_negotiate *session_spec,
                     vfs_context_t context, struct smb_session **sessionpp,
                     struct smb_dev *sdp, int searchOnly, uint32_t *matched_dns)
{
	//...
		if (error == 0) {
			/* Flags used to cancel the connection */
			sessionp->connect_flag = &sdp->sd_flags;
			error = smb_session_negotiate(sessionp, context); // signal smb_iod_thread to negotiate with server
			sessionp->connect_flag = NULL;
			if (error) /* Remove the lock and reference */
				smb_session_put(sessionp, context);
		}
	//...
}

If the connection failed, smb_sm_negotiate would trigger smb_session_put, which call smb_session_free to destroy the session

static void smb_session_free(struct smb_connobj *cp)
{
	struct smb_session *sessionp = (struct smb_session*)cp;
	
	smb_gss_rel_cred(sessionp);
    
	if (sessionp->session_iod)
		smb_iod_destroy(sessionp->session_iod);
	sessionp->session_iod = NULL;

	//...
}

Because the session is freed, iod will also be freed by smb_iod_destroy. Before free iod struct, smb_iod_destroy will signal and wait again until smb_iod_read_thread stop.

int
smb_iod_destroy(struct smbiod *iod)
{
	//...
	struct lease_rq *lease_rqp, *tmp_lease_rqp;
	smb_iod_request(iod, SMBIOD_EV_SHUTDOWN, NULL);

    /* Make sure the tcp transport was freed */
    smb_iod_closetran(iod, 0);

	/*
     * Tell read thread to exit
     */
    SMB_IOD_FLAGSLOCK(iod);
    for (;;) {
        if (!(iod->iod_flags & SMBIOD_READ_THREAD_RUNNING)) {
            SMB_IOD_FLAGSUNLOCK(iod);
            break;
        }

        /* Tell read thread to exit */
        iod->iod_flags |= SMBIOD_READ_THREAD_STOP;
        wakeup(&(iod->iod_flags));

        msleep(iod, SMB_IOD_FLAGSLOCKPTR(iod), PWAIT,
               "iod-read-exit", 0);
    }
	//...
	SMB_FREE(iod, M_SMBIOD);
}

Summarizing the flow of NEGOTIATE in smbfs.kext, the flow of the program will follow this diagram below.

            +------------------------------------------+                        +-------------------------------+
            |                                          |                        |                               |
            |                                          |                        |                               |
            |  ioctl(fd,SMBIOC_NEGOTIATE, &data)       |                        |SMB Server                     |
            |                                          |                        |                               |
            |                                          |                        |                               |
            +-----------------+------------------------+    USER MODE           +--------^----------------------+
                              |                                                          |
            ------------------+----------------------------------------------------------|
                              |                             KERNEL MODE                  |
  +---------+-----------------+------------------------+-+                               |
  |         +-----------------v------------------------+ |                               |
  |         | smb_usr_negotiate                        | |                               |
  |         |                                          | |                               |
  |         |                                          | |                               |
  |         |                                          | |                               |
  |         |                                          | |         +---------------+<----+     +-------------------+
  |         +-----------------+------------------------+ |         |               |           |                   |
  |                           |                          |         | smb_iod_thread|  start    |smb_iod_read_thread|
  |kernel_task                v                          |         |               +---------->|                   |
  |         +------------------------------------------+ |         |               |           |                   |
  |         |                                          | | start   |               |           |                   |
  |         | smb_sm_negotiate                        -+-+-------->|               |           |                   |
  |         |                                          | |         |               |           |                   |
  |         |                                          | |         |if connect     |signal kill|                   |
  |         +-+---------^-----+------------------------+ |         | failed        +---------->|                   |
  |           |         |     |                          |         |               |           |                   |
  |           |         |     |                          |         |               |           |                   |
  |           |         |     |    signal NEGOTIATE EVENT|         |               |           |                   |
  |           |         |     +--------------------------+-------->|               |           |                   |
  |           |         |                                |         +----+----------+           +-----^-------------+
  |           |         |      return error code         |              |                            |
  |           |         +--------------------------------+--------------+                            |
  |           |                                          |                                           |
  |           |                                          |                                           |
  |           +---------> if error destroy iod, signal---+-------------------------------------------+
  |                          kill smb_iod_read_thread    |
  +------------------------------------------------------+

The Vulnerability

The vulnerability occurs in smb_iod_thread when handling NEGOTIATE EVENT from kernel_task. If we look carefully at this function:

static int
smb_iod_negotiate(struct smbiod *iod, vfs_context_t user_context)
{
	//...

	error = SMB_TRAN_CREATE(sessionp);
	if (error) {
		goto errorOut;
	}

	/*
     * Start up read thread if not already running
     */
    SMB_IOD_FLAGSLOCK(iod);
    if (!(iod->iod_flags & SMBIOD_READ_THREAD_RUNNING)) {
        SMBIODEBUG("Starting read thread \n");
        result = kernel_thread_start((thread_continue_t)smb_iod_read_thread,
                                     iod, &thread);
        if (result != KERN_SUCCESS) {
            // ..
            goto errorOut;
        }
        else {
            thread_deallocate(thread);
        }
    }
    SMB_IOD_FLAGSUNLOCK(iod);

	...

	error = SMB_TRAN_CONNECT(sessionp, sessionp->session_saddr);
	if (error == 0) {
		iod->iod_state = SMBIOD_ST_TRANACTIVE;
		SMBIODEBUG("tconnect\n");

        /* Wake up the read thread */
        smb_iod_wakeup(iod);

        error = smb_smb_negotiate(sessionp, user_context, FALSE, iod->iod_context);
	}
	if (error) {
		goto errorOut;
	}
	iod->iod_state = SMBIOD_ST_NEGOACTIVE;
	SMBIODEBUG("completed\n");
	smb_iod_invrq(iod);
	return 0;

errorOut:
	smb_iod_dead(iod, 0);
	return error;
}

When function kernel_thread_start is called, this function does not actually start smb_iod_read_thread immediately. It will push this thread into the thread queue and wait for kernel scheduling to start this thread. If attacker input an invalid IP address or port, SMB_TRAN_CONNECT will failed, then smb_iod_thread signal to destroy smb_iod_read_thread. Returning to the kernel_task signal and waiting for the smb_iod_read_thread thread is actually killed and finally free iod` struct.

If an attacker can abuse thread scheduling by creating a lot of highest priority thread which make smb_iod_read_thread suspend for a while and pass an invalid smb server IP, the flow will not trigger smb_iod_wakeup which force kernel execute smb_iod_read_thread as soon as possible. Later the check for smb_iod_read_thread is actually killed on smb_iod_thread and kernel_task are easily bypassed. Due to the flag, SMBIOD_READ_THREAD_RUNNING was not set because the kernel scheduling did not start smb_iod_read_thread.

Proof of Concept

  1. We have two poc which proof this vulnerabilty.
  • smbfs_uaf.c this PoC works stably on macOS guest on VMWare fusion 4 cores / 8 gb ram
  • smbfs_uaf_mbp.c this PoC works on Macbook Pro 15 inch 2018.
  1. Step to reproduces PoC on VMWare Fusion:
  • Boot macOS kernel development on VMware Fusion and attach kernel into lldb debugger.
  • Compile smbfs_uaf.c by command: clang -framework CoreFoundation -framework NetFS smbfs_uaf.c -o smbfs_uaf -g
  • Setup an smbfs server same network with macOS VM.
  • Execute command : ./smbfs_uaf <smb server>, if smbfs was not loaded, it will popup a window just click cancel to continue the exploit.
  • lldb will have a high probability crash following this output below, which show that attacker can easily gain RIP control if they know some kernel address.
-----------------------------------------------------------------------------------------------------------------------[regs]
  RAX: 0x0000000000000000  RBX: 0xFFFFFF9356495F04  RBP: 0xFFFFFFB060C3BFA0  RSP: 0xFFFFFFB060C3BEF0  o d I t s Z a P c
  RDI: 0x0000000000000001  RSI: 0xFFFFFF869FEC2058  RDX: 0xFFFFFF800BE11FC0  RCX: 0xFFFFFF800B5804B0
  RIP: 0xFFFFFF7FAC2AEAAE  R8 : 0x0000000000000000  R9 : 0x0000000000989680  R10: 0xFFFFFFA02D1CDDE0
  R11: 0xFFFFFF869FEC2000  R12: 0x0000000000000000  R13: 0x4141414141414141  R14: 0xFFFFFFB060C3BF68
  R15: 0xFFFFFF9356495F00
  CS : 0008  GS : BE10000  FS : FFFF0000
-----------------------------------------------------------------------------------------------------------------------[code]
smb_iod_read_thread @ //System/Library/Extensions/smbfs.kext/Contents/MacOS/smbfs:
->  0xffffff7fac2aeaae (0x35aae): 49 8b 85 e8 00 00 00  mov    rax, qword ptr [r13 + 0xe8]
    0xffffff7fac2aeab5 (0x35ab5): 4c 89 ef              mov    rdi, r13
    0xffffff7fac2aeab8 (0x35ab8): 4c 89 f6              mov    rsi, r14
    0xffffff7fac2aeabb (0x35abb): ff 50 38              call   qword ptr [rax + 0x38]
    0xffffff7fac2aeabe (0x35abe): 85 c0                 test   eax, eax
    0xffffff7fac2aeac0 (0x35ac0): 0f 85 be 05 00 00     jne    0xffffff7fac2af084 ; <+1731>
    0xffffff7fac2aeac6 (0x35ac6): 48 83 7d c8 00        cmp    qword ptr [rbp - 0x38], 0x0
    0xffffff7fac2aeacb (0x35acb): 74 5e                 je     0xffffff7fac2aeb2b ; <+362>
-----------------------------------------------------------------------------------------------------------------------------

Process 1 stopped
* thread #1, stop reason = EXC_BAD_INSTRUCTION (code=13, subcode=0x0)
    frame #0: 0xffffff7fac2aeaae smbfs`smb_iod_read_thread + 237
Target 0: (kernel.development) stopped.
(lldbinit) bt
* thread #1, stop reason = EXC_BAD_INSTRUCTION (code=13, subcode=0x0)
  * frame #0: 0xffffff7fac2aeaae smbfs`smb_iod_read_thread + 237
    frame #1: 0xffffff800af0013e kernel.development`call_continuation + 46
  1. Step to reproduces PoC on Macbook Pro 15 inch 2018 :
  • Compile smbfs_uaf.c by command: clang -framework CoreFoundation -framework NetFS smbfs_uaf_mbp.c -o smbfs_uaf_mbp -g
  • Setup an smbfs server same network with macOS VM.
  • Execute command : ./smbfs_uaf_mbp <smb server>, if smbfs was not loaded, it will popup a window just click cancel to continue the exploit.
  • macOS kernel have a high probability crash at following output
panic(cpu 11 caller 0xffffff801cbee1e6): Kernel trap at 0xffffff7fbdcb1aae, type 13=general protection, registers:
CR0: 0x000000008001003b, CR2: 0x00007fc91093fe08, CR3: 0x0000000030b63000, CR4: 0x00000000003626e0
RAX: 0x0000000000000000, RBX: 0xffffff93a075ff04, RCX: 0xffffff801d05b5b0, RDX: 0xffffff801d815a00
RSP: 0xffffffa12d473ef0, RBP: 0xffffffa12d473fa0, RSI: 0xffffff86e819d8e0, RDI: 0x0000000000000000
R8:  0x0000000000000013, R9:  0x0000000000989680, R10: 0xffffffa0a3d68000, R11: 0xffffff86e819d890
R12: 0x0000000000000000, R13: 0x4343434343434343, R14: 0xffffffa12d473f68, R15: 0xffffff93a075ff00
RFL: 0x0000000000010246, RIP: 0xffffff7fbdcb1aae, CS:  0x0000000000000008, SS:  0x0000000000000010
Fault CR2: 0x00007fc91093fe08, Error code: 0x0000000000000000, Fault CPU: 0xb, PL: 0, VF: 0

Backtrace (CPU 11), Frame : Return Address
0xffffff801c95b9e0 : 0xffffff801cabab4d 
0xffffff801c95ba30 : 0xffffff801cbfd7e3 
0xffffff801c95ba70 : 0xffffff801cbede1a 
0xffffff801c95bac0 : 0xffffff801ca5fa2f 
0xffffff801c95bae0 : 0xffffff801caba3ed 
0xffffff801c95bc00 : 0xffffff801caba6d8 
0xffffff801c95bc70 : 0xffffff801d2bef9a 
0xffffff801c95bce0 : 0xffffff801cbee1e6 
0xffffff801c95be60 : 0xffffff801cbedecd 
0xffffff801c95beb0 : 0xffffff801ca5fa2f 
0xffffff801c95bed0 : 0xffffff7fbdcb1aae 
0xffffffa12d473fa0 : 0xffffff801ca5f13e 
      Kernel Extensions in backtrace:
         com.apple.filesystems.smbfs(3.4.1)[25B4D36D-9E80-3737-A383-5C00EC04C221]@0xffffff7fbdc7c000->0xffffff7fbdce5fff
            dependency: com.apple.kec.corecrypto(11.1)[E009770B-BAFB-3BF9-B176-D6B4CC96DF5F]@0xffffff801fbec000->0xffffff801fc7cfff
            dependency: com.apple.kext.triggers(1.0)[D4AC084E-97BE-37BC-BEB5-BE9A4BD1705D]@0xffffff7fbdcea000->0xffffff7fbdcecfff

Process name corresponding to current thread: kernel_task
Boot args: kcsuffix=

Mac OS version:
20D91

Kernel version:
Darwin Kernel Version 20.3.0: Thu Jan 21 00:07:06 PST 2021; root:xnu-7195.81.3~1/RELEASE_X86_64
Kernel UUID: C86236B2-4976-3542-80CA-74A6B8B4BA03
KernelCache slide: 0x000000001c800000
KernelCache base:  0xffffff801ca00000
Kernel slide:      0x000000001c810000
Kernel text base:  0xffffff801ca10000
__HIB  text base: 0xffffff801c900000
System model name: MacBookPro15,1 (Mac-937A206F2EE63C01)
System shutdown begun: NO
Hibernation exit count: 0

System uptime in nanoseconds: 102707373779
Last Sleep:           absolute           base_tsc          base_nano
  Uptime  : 0x00000017e9d62953
  Sleep   : 0x0000000000000000 0x0000000000000000 0x0000000000000000
  Wake    : 0x0000000000000000 0x00000005ab865b20 0x0000000000000000
last started kext at 56789308960: @filesystems.smbfs	3.4.1 (addr 0xffffff7fbdc7c000, size 434176)
loaded kexts:
@filesystems.smbfs	3.4.1
>AGPM	119
>!APlatformEnabler	2.7.0d0
>X86PlatformShim	1.0.0
>!ATopCaseHIDEventDriver	4030.5
>!AHIDALSService	1
@filesystems.autofs	3.0
@fileutil	20.036.15
@kext.AMDFramebuffer	4.0.2
@kext.AMDRadeonX4000	4.0.2
@kext.AMDRadeonServiceManager	4.0.2
>!AGraphicsDevicePolicy	6.2.2
@AGDCPluginDisplayMetrics	6.2.2
>pmtelemetry	1
>!AUpstreamUserClient	3.6.8
|IOUserEthernet	1.0.1
>usb.!UUserHCI	1
|IO!BSerialManager	8.0.3d9
>!ABridgeAudio!C	100.2
>AGDCBacklightControl	6.2.2
@Dont_Steal_Mac_OS_X	7.0.0
>!AHV	1
>BridgeAudioCommunication	100.2
>!ABacklight	180.3
>!ADiskImages2	1
>!AMCCSControl	1.14
@kext.AMD9500!C	4.0.2
>!AGFXHDA	100.1.431
>!AFIVRDriver	4.1.0
>!A!ISlowAdaptiveClocking	4.0.0
>!A!IKBLGraphics	16.0.1
>ACPI_SMC_PlatformPlugin	1.0.0
>!AAVEBridge	6.1
>!AThunderboltIP	4.0.3
>!AMuxControl2	6.2.2
>!A!ICFLGraphicsFramebuffer	16.0.1
>!A!IPCHPMC	2.0.1
>BCMWLANFirmware4378.Hashstore	1
>BCMWLANFirmware4377.Hashstore	1
>BCMWLANFirmware4364.Hashstore	1
>BCMWLANFirmware4355.Hashstore	1
>!AFileSystemDriver	3.0.1
@filesystems.tmpfs	1
@filesystems.hfs.kext	556.60.1
@BootCache	40
@!AFSCompression.!AFSCompressionTypeZlib	1.0.0
@!AFSCompression.!AFSCompressionTypeDataless	1.0.0d1
>!ABCMWLANBusInterfacePCIeMac	1
@filesystems.apfs	1677.81.1
@private.KextAudit	1.0
>!ASmartBatteryManager	161.0.0
>!AACPIButtons	6.1
>!ASMBIOS	2.1
>!AACPIEC	6.1
>!AAPIC	1.7
@!ASystemPolicy	2.0.0
@nke.applicationfirewall	310
|IOKitRegistryCompatibility	1
|EndpointSecurity	1
>!AHIDKeyboard	223
>!AActuatorDriver	4400.28
>!AMultitouchDriver	4400.28
>!AInputDeviceSupport	4400.35
>!AHS!BDriver	4030.5
>IO!BHIDDriver	8.0.3d9
@kext.triggers	1.0
@kext.AMDRadeonX4100HWLibs	1.0
@kext.AMDRadeonX4000HWServices	4.0.2
|IOAVB!F	930.1
|IO!BHost!CUARTTransport	8.0.3d9
|IO!BHost!CTransport	8.0.3d9
>!ABacklightExpert	1.1.0
>!A!ILpssUARTv1	3.0.60
>!A!ILpssUARTCommon	3.0.60
>!AOnboardSerial	1.0
>!ASMBus!C	1.0.18d1
@kext.AMDSupport	4.0.2
@!AGPUWrangler	6.2.2
@plugin.IOgPTPPlugin	900.11
|IOEthernetAVB!C	1.1.0
>!AHDA!C	283.15
|IOHDA!F	283.15
|IOAudio!F	300.6.1
@vecLib.kext	1.2.0
>!ASMBusPCI	1.0.14d1
|IOSlowAdaptiveClocking!F	1.0.0
>IOPlatformPluginLegacy	1.0.0
|IONDRVSupport	585
>X86PlatformPlugin	1.0.0
>!AGraphicsControl	6.2.2
|IOAccelerator!F2	439.52
@!AGraphicsDeviceControl	6.2.2
|IOGraphics!F	585
>!AThunderboltEDMSink	5.0.3
>!AThunderboltDPOutAdapter	8.1.4
>IOPlatformPlugin!F	6.0.0d8
>usb.IOUSBHostHIDDevice	1.2
>usb.cdc.ecm	5.0.0
>usb.cdc.ncm	5.0.0
>usb.cdc	5.0.0
>usb.networking	5.0.0
>usb.!UHostCompositeDevice	1.2
>!AThunderboltPCIDownAdapter	4.1.1
>!AThunderboltDPInAdapter	8.1.4
>!AThunderboltDPAdapter!F	8.1.4
>!AHPM	3.4.4
>!A!ILpssI2C!C	3.0.60
>!A!ILpssI2C	3.0.60
>!A!ILpssDmac	3.0.60
>!ABSDKextStarter	3
|IOSurface	289.3
@filesystems.hfs.encodings.kext	1
>!ABCMWLANCoreMac	1.0.0
|IOSerial!F	11
|IO80211!FV2	1200.12.2b1
|IOSkywalk!F	1
>mDNSOffloadUserClient	1.0.1b8
>IOImageLoader	1.0.0
>corecapture	1.0.4
>!AXsanScheme	3
>!AThunderboltNHI	7.2.8
|IOThunderbolt!F	9.3.2
>usb.!UVHCIBCE	1.2
>usb.!UVHCICommonBCE	1.0
>usb.!UVHCI	1.2
>usb.!UVHCICommon	1.0
>!AEffaceableNOR	1.0
|IOBufferCopy!C	1.1.0
|IOBufferCopyEngine!F	1
|IONVMe!F	2.1.0
>usb.!UHostPacketFilter	1.0
|IOUSB!F	900.4.2
>usb.!UXHCIPCI	1.2
>usb.!UXHCI	1.2
>!AEFINVRAM	2.1
>!AEFIRuntime	2.1
>!ASMCRTC	1.0
|IOSMBus!F	1.1
|IOHID!F	2.0.0
$!AImage4	3.0.0
|IOTimeSync!F	900.11
|IONetworking!F	3.4
>DiskImages	493.0.0
|IO!B!F	8.0.3d9
|IOReport!F	47
|IO!BPacketLogger	8.0.3d9
$quarantine	4
$sandbox	300.0
@kext.!AMatch	1.0.0d1
|CoreAnalytics!F	1
>!ASSE	1.0
>!AKeyStore	2
>!UTDM	511.60.2
|IOUSBMass!SDriver	184.40.6
|IOSCSIBlockCommandsDevice	436.40.6
|IO!S!F	2.1
|IOSCSIArchitectureModel!F	436.40.6
>!AMobileFileIntegrity	1.0.5
@kext.CoreTrust	1
>!AFDEKeyStore	28.30
>!AEffaceable!S	1.0
>!ACredentialManager	1.0
>KernelRelayHost	1
|IOUSBHost!F	1.2
>!UHostMergeProperties	1.2
>usb.!UCommon	1.0
>!ABusPower!C	1.0
>!ASEPManager	1.0.1
>IOSlaveProcessor	1
>!AACPIPlatform	6.1
>!ASMC	3.1.9
|IOPCI!F	2.9
|IOACPI!F	1.4
>watchdog	1
@kec.pthread	1
@kec.corecrypto	11.1
@kec.Libm	1

Timeline

  • 2021-03-05 Reported to Vendor
  • 2021-10-20 Vendor assign CVE

Credit

Discovered by Peter Nguyễn Vũ Hoàng