Network Kernel Extensions case Mac Kernel Panic

237 views Asked by At

I code a Network Kernel Extensions on Mac, code as follows:, the funcation proxy_tcp_unregistered,proxy_tcp_attach,proxy_tcp_detach are empty funcation which do nothing

const static struct sflt_filter tcp_filter =
{
    PROXY_TCP_FILTER_HANDLE,
    SFLT_GLOBAL,
    BUNDLE_NAME,
    proxy_tcp_unregistered,  //do nothing
    proxy_tcp_attach,        //do nothing
    proxy_tcp_detach,        //do nothing
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
};

kern_return_t kerntest_start(kmod_info_t * ki, void *d)
{
    sflt_register(&tcp_filter, PF_INET, SOCK_STREAM, IPPROTO_TCP);
    return KERN_SUCCESS;
}

kern_return_t kerntest_stop(kmod_info_t *ki, void *d)
{
    sflt_unregister(PROXY_TCP_FILTER_HANDLE);
    return KERN_SUCCESS;
}

And use a shell to test, after about 50 times load, unload(kextload and kextunload), the Mac Kernel Panic happened:

*** Panic Report ***
panic(cpu 3 caller 0xffffff8009a065ea): Kernel trap at 0xffffff7f8c775ba0, type 14=page fault, registers:
....
Fault CR2: 0xffffff7f8c775ba0, Error code: 0x0000000000000010, Fault CPU: 0x3, PL: 0

Backtrace (CPU 3), Frame : Return Address
..... 
      Kernel Extensions in backtrace:
         xxxx.xxxx.proxy.hook(1.0)[7A521823-D1CF-353E-93CA-0345CD6F5454]@0xffffff7f8c771000->0xffffff7f8c777fff
            kmod dependency scan stopped due to missing dependency page: 0xc0ffee570a4457da

BSD process name corresponding to current thread: kernel_task

Mac OS version:
16B2555

Kernel version:
Darwin Kernel Version 16.1.0: Thu Oct 13 21:26:57 PDT 2016; root:xnu-3789.21.3~60/RELEASE_X86_64
Kernel UUID: 8941AC1C-B084-37DE-8A34-4CE638C5CFC9
Kernel slide:     0x0000000009600000
...

System uptime in nanoseconds: 28211489690166
last loaded kext at 28211416923440: com.test.kextext 1.0 (addr 0xffffff7f8c778000, size 40960)
last unloaded kext at 28211489331506: com.test.kextext  1.0 (addr 0xffffff7f8c771000, size 28672)
loaded kexts:
com.test.kextext 1.0
com.apple.filesystems.smbfs 3.1

What did i should do to deal with this, it not happend all the time.

1

There are 1 answers

1
pmdj On

If you look at the documentation for sflt_unregister, you'll notice 2 things:

1:

Unregisters a socket filter. This will not detach the socket filter from all sockets it may be attached to at the time, it will just prevent the socket filter from being attached to any new sockets.

The implication of this is that your callbacks can still be called after sflt_unregister returns. You need to properly clean up any sockets that might still be attached to your filter before you allow the kext to be unloaded.

2:

Returns: 0 on success otherwise the errno error.

You probably shouldn't allow unloading the kext if unregistering fails. (And likewise, you probably shouldn't even try to unregister a filter for which registration originally failed during kext start.)