Bug #6257
Updated by Victor Julien about 1 year ago
On an inactive openvpn dev:
<pre>
# ip l show tun0
10: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 100
link/none
</pre>
Getting Suricata to shutdown fails:
<pre>
Info: runmodes: Using 2 live device(s). [RunModeSetLiveCaptureAutoFp:util-runmodes.c:143]
Info: pcap: tun0: running in 'auto' checksum mode. Detection of interface state will require 1000 packets [ReceivePcapThreadInit:source-pcap.c:522]
Info: ioctl: tun0: MTU 1500 [GetIfaceMTU:util-ioctl.c:110]
Info: pcap: tun0: snaplen set to 1524 [PcapOpenInterface:source-pcap.c:248]
Perf: ioctl: tun0: NIC offloading: RX unset TX unset [GetIfaceOffloadingLinux:util-ioctl.c:340]
Perf: ioctl: tun0: NIC offloading: SG: unset, GRO: unset, LRO: unset, TSO: unset, GSO: unset [GetIfaceOffloadingLinux:util-ioctl.c:385]
Info: pcap: tun1: running in 'auto' checksum mode. Detection of interface state will require 1000 packets [ReceivePcapThreadInit:source-pcap.c:522]
Info: ioctl: tun1: MTU 1500 [GetIfaceMTU:util-ioctl.c:110]
Info: pcap: tun1: snaplen set to 1524 [PcapOpenInterface:source-pcap.c:248]
Perf: ioctl: tun1: NIC offloading: RX unset TX unset [GetIfaceOffloadingLinux:util-ioctl.c:340]
Perf: ioctl: tun1: NIC offloading: SG: unset, GRO: unset, LRO: unset, TSO: unset, GSO: unset [GetIfaceOffloadingLinux:util-ioctl.c:385]
...
Notice: suricata: Signature(s) loaded, Detect thread(s) activated. [PostRunStartedDetectSetup:suricata.c:2540]
Notice: suricata: Signal Received. Stopping engine. [SuricataMainLoop:suricata.c:2828]
Error: threads: Engine unable to disable detect thread - "RX#01-tun0". Killing engine [TmThreadDisableReceiveThreads:tm-threads.c:1359]
</pre>
gdb shows:
<pre>
(gdb) bt
#0 0x00007ffff631199f in __GI___poll (fds=0x7fffe05dc210, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
#1 0x00007ffff75c65ca in __interceptor_poll (fds=fds@entry=0x7fffe05dc210, nfds=nfds@entry=1, timeout=-1) at ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:3844
#2 0x00007ffff6455c4a in poll (__timeout=<optimized out>, __nfds=1, __fds=0x7fffe05dc210) at /usr/include/x86_64-linux-gnu/bits/poll2.h:46
#3 pcap_wait_for_frames_mmap (handle=handle@entry=0x6180000fc080) at ./pcap-linux.c:4869
#4 0x00007ffff6455e75 in pcap_read_linux_mmap_v3 (handle=0x6180000fc080, max_packets=64, callback=0x555555b4cd36 <PcapCallbackLoop>, user=0x60e000e86fc0 "\200\300\017") at ./pcap-linux.c:5367
#5 0x0000555555b4d827 in ReceivePcapLoop (tv=0x6120000880c0, data=0x60e000e86fc0, slot=0x6060001067c0) at source-pcap.c:424
#6 0x0000555555832724 in TmThreadsSlotPktAcqLoop (td=0x6120000880c0) at tm-threads.c:316
#7 0x00007ffff70e7609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#8 0x00007ffff631e133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
</pre>
A big more debugging shows that @pcap_dispatch@ is called, but we never return from it.
If the pcap handle is set to nonblocking with @pcap_setnonblocking@ things do work, but the rest of the code isn't ready for this (100% cpu spin).
Same happens on a dummy device, so it should be easy to test.
It can be seen that @pcap_breakloop@ is called on the handle, but it is not resulting in breaking the loop.