Fri 23 Oct 2009 02:36:59 PM UTC, original submission:
the following problems happens on my platform
lwip tree = CVS HEAD 20091023
during a TCP connect, it happens that I got null pointer dereference (pcb->unacked = 0) in tcp_in.c :559 (in fact line 560) in function tcp_process()
559: if ((flags & TCP_ACK) && (flags & TCP_SYN)
560: && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
as we can see, in tcp_process() we assume that pcb->unacked != 0
the TCP SYN packet is sent in tcp_out.c (thanks to a call to tcp_output_segment(seg, pcb); line 586)
but the problem is that pcb->unacked is set after the packet is actually sent (it is set in tcp_out.c line 596)
in my environment, it happens from time to time that the TCP SYN ACK answer arrives before the pcb->unacked is set to something not null .... hence, the null pointer dereference.
see backtrace below :
thread 1 doing the tcp connect :
--------------------------------
#0 0x84aa7528 in tcp_output (pcb=0x84dc8aac) at head/lwip/src/core/tcp_out.c:589
589 snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
(gdb) bt
#0 0x84aa7528 in tcp_output (pcb=0x84dc8aac) at head/lwip/src/core/tcp_out.c:589
#1 0x84aa3c06 in tcp_connect (pcb=0x84dc8aac, ipaddr=0x89430670, port=80, connected=0x84aaa7a0 <do_connected>) at head/lwip/src/core/tcp.c:563
#2 0x84aab53e in do_connect (msg=0x89430654) at head/lwip/src/api/api_msg.c:812
#3 0x84aa8848 in tcpip_thread (arg=<value optimized out>) at head/lwip/src/api/tcpip.c:269
as we can see, the packet has been sent, but pcb->unacked has not yet been set (it is still null here, as we have not reached tcp_out.c:596)
thread 2 : ethernet driver callback:
--------------------------------------------------
#0 0x84aa6a8c in tcp_input (p=<value optimized out>, inp=<value optimized out>) at head/lwip/src/core/tcp_in.c:559
559 if ((flags & TCP_ACK) && (flags & TCP_SYN)
(gdb) bt
#0 0x84aa6a8c in tcp_input (p=<value optimized out>, inp=<value optimized out>) at head/lwip/src/core/tcp_in.c:559
#1 0x84a9c608 in ip_input (p=0x84dfbb9c, inp=0x84e1bd20) at head/lwip/src/core/ipv4/ip.c:427
(gdb) print pcb
$1 = (struct tcp_pcb *) 0x84dc8aac
(gdb) print pcb->unacked
$2 = (struct tcp_seg *) 0x0
here we are processing the TCP SYN ACK answer, & we are already considering that pcb->unacked is != NULL
=> there is something wrong here, I would rather suggest that
|