lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [bug #19167] tcp timeout handler can cause crash being invo


From: Dmitry Potapov
Subject: [lwip-devel] [bug #19167] tcp timeout handler can cause crash being invoked by sys_sem_wait()
Date: Wed, 28 Feb 2007 00:20:47 +0000
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.10) Gecko/20070216 Firefox/1.5.0.10

URL:
  <http://savannah.nongnu.org/bugs/?19167>

                 Summary: tcp timeout handler can cause crash being invoked
by sys_sem_wait()
                 Project: lwIP - A Lightweight TCP/IP stack
            Submitted by: dpotapov
            Submitted on: Wednesday 02/28/2007 at 00:20
                Category: TCP
                Severity: 3 - Normal
              Item Group: Crash Error
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any

    _______________________________________________________

Details:

lwIP core is not re-entrable, so it is used inside one devoted thread.
However, it uses memory allocation functions:

mem_free, mem_realloc,  mem_malloc, mem_malloc, memp_malloc, memp_free

Because these functions can be called from different threads, they are
protected by a semaphore (when SYS_LIGHTWEIGHT_PROT is 0). The implementation
of these functions uses sys_sem_wait() to acquire the lock. sys_sem_wait() is
built on the top of sys_arch_sem_wait, but, in addition to the latter, it can
invoke timeout handlers!

These memory functions are called from too many functions to have the full of
list, but here are some of most commonly used:

pbuf_alloc, pbuf_realloc, pbuf_free, raw_remove, raw_new, sys_timeout,
sys_untimeout, tcp_seg_free, ...

Thus inside of any of those functions, timeout handler can be invoked.

tcpip_tcp_timer (one of functions invoked on timeout) performs many different
operations. Here is some functions that can be called during its work:

tcpip_tcp_timer
 tcp_tmr
   tcp_fasttmr
     tcp_ack_now
       forevery pcb in tcp_active_pcbs
          tcp_output
   tcp_slowtmr acts on all tcp_active_pcbs
      forevery pcb in tcp_active_pcbs
      {
        tcp_rexmit_rto
          tcp_output
        tcp_abort
          tcp_segs_free
        tcp_keepalive
        tcp_output
        tcp_pcb_purge
          tcp_segs_free
      }

Basically, any pcb in the tcp_active_pcbs can change its status and some
lists are freed, etc... Because, this timeout handler can be invoked in too
many places and too many cases, it is not humanly possible to analyze all
consequences of timeout handler being invoked at unsuitable time. So, I will
give only one example:

In the tcp_process() in tcp_in.c, you can see the following lines:
      tcp_pcb_purge(pcb);
      TCP_RMV(&tcp_active_pcbs, pcb);

Obviously, that pcb is inside of the tcp_active_pcbs when tcp_pcb_purge is
called. Now tcp_pcb_purge() calls to tcp_segs_free(), which calls to
tcp_seg_free(), which calls to memp_free(), which can invoke timeout handler,
which can call tcp_pcb_purge for the same pcb, which results that the same
memory is freed twice, which means memory corruption.


Solution:
~~~~~~~~~
Replace all calls to sys_sem_wait(mutex) inside of memp.c with
sys_arch_sem_wait(mutex,0), so no timeout handler can be invoked.

I believe, the same thing should be done with sys_sem_wait(mem_sem) in mem.c






    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?19167>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.nongnu.org/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]