irontec / sngrep

Ncurses SIP Messages flow viewer
GNU General Public License v3.0
1.02k stars 187 forks source link

coredump at capture.c with IPv6 #498

Open linuxmaniac opened 1 week ago

linuxmaniac commented 1 week ago

this is sngrep v1.8.1 but I think the code is the same in v1.8.2

Core was generated by `sngrep -c'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  capture_packet_reasm_ip ([capinfo=capinfo@entry](mailto:capinfo=capinfo@entry)=0x55998f8aa990, [header=header@entry](mailto:header=header@entry)=0x7f3c78754970, [packet=packet@entry](mailto:packet=packet@entry)=0x7f3c7874f900 "", [size=size@entry](mailto:size=size@entry)=0x7f3c7874f8fc, 
    [caplen=caplen@entry](mailto:caplen=caplen@entry)=0x7f3c7874f8f8) at ./src/capture.c:680
680     ./src/capture.c: No such file or directory.
[Current thread is 1 (Thread 0x7f3c787556c0 (LWP 2100393))]
(gdb) bt
#0  capture_packet_reasm_ip ([capinfo=capinfo@entry](mailto:capinfo=capinfo@entry)=0x55998f8aa990, [header=header@entry](mailto:header=header@entry)=0x7f3c78754970, [packet=packet@entry](mailto:packet=packet@entry)=0x7f3c7874f900 "", [size=size@entry](mailto:size=size@entry)=0x7f3c7874f8fc, 
    [caplen=caplen@entry](mailto:caplen=caplen@entry)=0x7f3c7874f8f8) at ./src/capture.c:680
0000001  0x000055998e317b4a in parse_packet (info=0x55998f8aa990 "\001\001", header=0x7f3c78754970, packet=0x7f3c788dc1e4 "") at ./src/capture.c:367
#2  0x00007f3c792b54f6 in ?? () from /lib/x86_64-linux-gnu/libpcap.so.0.8
0000003  0x00007f3c792b58ec in ?? () from /lib/x86_64-linux-gnu/libpcap.so.0.8
#4  0x00007f3c792bcd1d in pcap_loop () from /lib/x86_64-linux-gnu/libpcap.so.0.8
#5  0x000055998e315b3c in capture_thread (info=0x55998f8aa990) at ./src/capture.c:1069
#6  0x00007f3c79155134 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
0000007  0x00007f3c791d57dc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

(gdb) p *capinfo
$1 = {running = true, ispcap = true, link = 113, link_hl = 16 '\020', handle = 0x55998f8aa9f0, mask = 0, net = 0, infile = 0x0, device = 0x55998f8a9910 "any", ip_reasm = 0x55998f8aada0, 
  tcp_reasm = 0x55998f8aad70, capture_fn = 0x55998e315b20 <capture_thread>, capture_t = 139897695721152}
(gdb) p *header
$2 = {ts = {tv_sec = 1728299259, tv_usec = 715314}, caplen = 220, len = 220}
(gdb) p ip6f
$3 = (struct ip6_frag *) 0x0

related code: https://github.com/irontec/sngrep/blob/master/src/capture.c#L685-L687

#ifdef USE_IPV6
    if (ip_ver == 6 && ip_frag && (ip6f->ip6f_offlg & htons(0x01)) == 0) {
        pkt->ip_exp_len = ip_frag_off + ip_len - ip_hl - sizeof(struct ip6_frag);
    }
#endif

ip6f is NULL so... :bomb:

linuxmaniac commented 1 week ago

how can ip6f be NULL and ip_frag != 0 && ip_ver == 6 if we have at https://github.com/irontec/sngrep/blob/master/src/capture.c#L590-L606

#ifdef USE_IPV6
            case 6:
                ip_hl = sizeof(struct ip6_hdr);
                ip_proto = ip6->ip6_nxt;
                ip_len = ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen) + ip_hl;

                if (ip_proto == IPPROTO_FRAGMENT) {
                    ip_frag = 1;
                    ip6f = (struct ip6_frag *) (packet + link_hl + ip_hl);
                    ip_frag_off = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
                    ip_id = ntohl(ip6f->ip6f_ident);
                }

                inet_ntop(AF_INET6, &ip6->ip6_src, src.ip, sizeof(src.ip));
                inet_ntop(AF_INET6, &ip6->ip6_dst, dst.ip, sizeof(dst.ip));
                break;
#endif
Kaian commented 3 days ago

Hi!

Thanks for the report and detailed information of the offending code.

This is quite strange, becaue if ip6f has a NULL value after being assigned, it should have crashed in the next line and not reach that if. Maybe some memory overflow elsewhere between assigment and crashing line updated ip6f or ip_frag?

It would be awesome it this could be reproduced while reading a pcap file (not sure if this happens often enough)

Regards,