我在Mac上编写了一个网络内核扩展,代码如下:,函数proxy_tcp_unregistered,proxy_tcp_attach,proxy_tcp_detach是空函数,什么都不做
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;
}
使用shell测试,在加载约50次后,卸载(kextload和kextunload),Mac内核恐慌发生了:
*** 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
我应该怎么做才能解决这个问题,它不会一直发生。
答案 0 :(得分:1)
如果查看sflt_unregister
的文档,您会注意到两件事:
1:
取消注册套接字过滤器。这不会脱离 套接字过滤器可以连接到所有套接字 时间,它只会阻止套接字过滤器的连接 任何新的插座。
这意味着在sflt_unregister
返回后仍可以调用您的回调。在允许卸载kext之前,您需要正确清理可能仍附加到过滤器的任何套接字。
2:
成功时返回 0,否则发生错误。
如果取消注册失败,您可能不应该允许卸载kext。 (同样地,您可能甚至不应该尝试取消注册在kext启动期间最初注册失败的过滤器。)