Actions
Bug #6257
openpcap: hang at shutdown for some interfaces
Affected Versions:
Effort:
Difficulty:
Label:
Description
On an inactive openvpn dev:
# 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
Getting Suricata to shutdown fails:
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]
gdb shows:
(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
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.
Actions