DNS hang when using sflt_register() on UNIX sockets
DNS hang when using sflt_register() on UNIX sockets
- Subject: DNS hang when using sflt_register() on UNIX sockets
- From: Etienne Clément <email@hidden>
- Date: Mon, 22 Sep 2014 20:54:03 -0400
Hi,
I just logged the following radar but hopefully you guys can confirm that this is really a bug in the kernel.
18420898: DNS hang when using sflt_register() on UNIX sockets
When registering a simple socket filter (i.e using sflt_register()) on UNIX sockets, mDNSResponter (on 10.9) or discoveryd (on 10.10) hang after a few requests. I have attached the all the code required to reproduce the problem and stackshot captures to the radar but from the snippets of information below, the problem seems to be a race condition in the kernel that only happens when the socket filter has a sf_data_in filter.
Steps to Reproduce:
1. Load the nke_sflt_unix_socket.kext kext using the following commands at the Terminal:
sudo cp -R <PATH TO KEXT>/nke_sflt_unix_socket/nke_sflt_unix_socket.kext /tmp
sudo chown -R root:wheel /tmp/nke_sflt_unix_socket.kext
sudo kextload /tmp/nke_sflt_unix_socket.kext
2. At the Terminal type ping google.com, if it works do a Ctrl-C to kill it and repeat step 2 until the ping command hangs.
3. At this point mDNSReponder (on 10.9) or discoveryd (on 10.10) is frozen and any DNS request will hang.
DRIVER CODE SNIPPET:
-----------------------------------
static void ho_sf_unregistered(sflt_handle handle)
{
printf("ho_sf_unregistered\n");
}
static errno_t ho_sf_attach(void **cookie, socket_t so)
{
return 0;
}
static void ho_sf_detach(void *cookie, socket_t so)
{
}
static errno_t ho_sf_unix_data_in(void *cookie, socket_t so, const struct sockaddr *from, mbuf_t *data, mbuf_t *control,sflt_data_flag_t flags)
{
printf("ho_sf_unix_data_in\n");
return 0;
}
static errno_t ho_sf_unix_data_out(void *cookie, socket_t so,
const struct sockaddr *to, mbuf_t *data, mbuf_t *control,
sflt_data_flag_t flags)
{
printf("ho_sf_unix_data_out\n");
return 0;
}
kern_return_t nke_sflt_unix_socket_start(kmod_info_t * ki, void *d)
{
printf("nke_sflt_unix_socket_start\n");
struct sflt_filter filter;
memset(&filter, 0, sizeof(filter));
filter.sf_flags = SFLT_GLOBAL;
filter.sf_name = (char*)"NAME";
filter.sf_unregistered = ho_sf_unregistered;
filter.sf_attach = ho_sf_attach;
filter.sf_detach = ho_sf_detach;
filter.sf_notify = 0;
filter.sf_data_in = ho_sf_unix_data_in;
filter.sf_data_out = ho_sf_unix_data_out;
filter.sf_connect_in = 0;
filter.sf_handle = NKE_HANDLE;
errno_t err;
err = sflt_register(&filter, AF_UNIX, SOCK_STREAM, IPPROTO_IP);
if (err) printf("sflt_register fails %d (%x)\n", err, err);
return KERN_SUCCESS;
}
kern_return_t nke_sflt_unix_socket_stop(kmod_info_t *ki, void *d)
{
printf("nke_sflt_unix_socket_stop\n");
errno_t err;
err = sflt_unregister(NKE_HANDLE);
return KERN_SUCCESS;
}
STACKSHOT SNIPPET ON 10.10 DP8:
-----------------------------------------------------
Thread ID: 0x3d4
Thread name: ""
Thread flags: 0x1 == kUser64_p
Thread state: 0x1 == TH_WAIT
Thread effective QoS: 4
Thread wait_event: 0x0
Thread voucher: 0xce3000007fff8990
Continuation: 0xffffff80007b8f20 (in kernel) + 0 (0xffffff80007b8f20)
User stack:
kevent64 (in libsystem_kernel.dylib) + 10 (0x7fff9149622e)
_dispatch_mgr_init (in libdispatch.dylib) + 0 (0x7fff8ff48a6a)
0x0000000000000000 (0x0)
Thread ID: 0x42e
Thread name: ""
Thread flags: 0x3 == kUser64_p|kKernel64_p
Thread state: 0x9 == TH_WAIT|TH_UNINT
Thread effective QoS: 5
Thread wait_event: 0x5e82e48a89091921
Thread voucher: 0x0
Kernel stack:
machine_switch_context (in kernel) + 367 (0xffffff800041a30f)
0xffffff8000352ddc (in kernel) + 1372 (0xffffff8000352ddc)
thread_block_reason (in kernel) + 175 (0xffffff800035084f)
lck_mtx_lock_wait_x86 (in kernel) + 426 (0xffffff8000417dba)
lck_mtx_lock (in kernel) + 653 (0xffffff800041278d)
unp_lock (in kernel) + 50 (0xffffff800082a782)
0xffffff800083d7d8 (in kernel) + 408 (0xffffff800083d7d8)
sbappend (in kernel) + 176 (0xffffff80008210d0)
0xffffff800082bf6b (in kernel) + 1387 (0xffffff800082bf6b)
sosend (in kernel) + 2592 (0xffffff8000817740)
0xffffff8000829654 (in kernel) + 628 (0xffffff8000829654)
sendto_nocancel (in kernel) + 187 (0xffffff800082641b)
unix_syscall64 (in kernel) + 610 (0xffffff800084dcb2)
hndl_unix_scall64 (in kernel) + 22 (0xffffff800043ac46)
User stack:
__sendto (in libsystem_kernel.dylib) + 10 (0x7fff914954e6)
0x000000010664ad82 (in discoveryd) + 280 (0x10664ad82)
0x00000001065f43a3 (in discoveryd) + 167 (0x1065f43a3)
0x0000000106671c91 (in discoveryd) + 89 (0x106671c91)
0x000000010667c7a6 (in discoveryd) + 94 (0x10667c7a6)
0x0000000106614a61 (in discoveryd) + 185 (0x106614a61)
_dispatch_call_block_and_release (in libdispatch.dylib) + 12 (0x7fff8ff4a323)
_dispatch_client_callout (in libdispatch.dylib) + 8 (0x7fff8ff45c13)
_dispatch_async_redirect_invoke (in libdispatch.dylib) + 650 (0x7fff8ff4c99e)
_dispatch_client_callout (in libdispatch.dylib) + 8 (0x7fff8ff45c13)
_dispatch_root_queue_drain (in libdispatch.dylib) + 935 (0x7fff8ff4888f)
_dispatch_worker_thread3 (in libdispatch.dylib) + 91 (0x7fff8ff56fe4)
_pthread_wqthread (in libsystem_pthread.dylib) + 729 (0x7fff8e10b6cb)
start_wqthread (in libsystem_pthread.dylib) + 13 (0x7fff8e1094a1)
0x0000000000000000 (0x0)
PID: 497
Process: ping
Start time: Mon Sep 22 22:09:22 2014
ImpDonor
Thread ID: 0x5a7a
Thread name: ""
Thread flags: 0x3 == kUser64_p|kKernel64_p
Thread state: 0x9 == TH_WAIT|TH_UNINT
Thread effective QoS: 4
Thread wait_event: 0x5e82e48a89ccb0f1
Thread voucher: 0x6576654c7265776f
Kernel stack:
machine_switch_context (in kernel) + 367 (0xffffff800041a30f)
0xffffff8000352ddc (in kernel) + 1372 (0xffffff8000352ddc)
thread_block_reason (in kernel) + 175 (0xffffff800035084f)
lck_mtx_lock_wait_x86 (in kernel) + 426 (0xffffff8000417dba)
lck_mtx_lock (in kernel) + 653 (0xffffff800041278d)
unp_lock (in kernel) + 50 (0xffffff800082a782)
0xffffff800082d20d (in kernel) + 93 (0xffffff800082d20d)
soreceive (in kernel) + 6634 (0xffffff8000819caa)
0xffffff8000829b2b (in kernel) + 459 (0xffffff8000829b2b)
recvfrom_nocancel (in kernel) + 234 (0xffffff8000826d3a)
unix_syscall64 (in kernel) + 610 (0xffffff800084dcb2)
hndl_unix_scall64 (in kernel) + 22 (0xffffff800043ac46)
User stack:
__recvfrom_nocancel (in libsystem_kernel.dylib) + 10 (0x7fff9149534e)
DNSServiceProcessResult (in libsystem_dnssd.dylib) + 294 (0x7fff8d22d036)
_mdns_search (in libsystem_info.dylib) + 1592 (0x7fff871e4c1e)
mdns_hostbyname (in libsystem_info.dylib) + 186 (0x7fff871e44e6)
search_host_byname (in libsystem_info.dylib) + 146 (0x7fff871e41a7)
gethostbyname2 (in libsystem_info.dylib) + 167 (0x7fff871f6308)
0x00000001078ff4f8 (in ping) + 2984 (0x1078ff4f8)
start (in libdyld.dylib) + 1 (0x7fff874335c9)
0x00000002 (in ping) (0x2)
Regards.
Etienne
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden