lwip-devel
[Top][All Lists]
Advanced

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

[lwip-devel] [bug #25051] lwip_recvfrom problem with udp: fromaddr and p


From: Tamas Somogyi
Subject: [lwip-devel] [bug #25051] lwip_recvfrom problem with udp: fromaddr and port uses deleted netbuf
Date: Tue, 09 Dec 2008 14:13:48 +0000
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4

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

                 Summary: lwip_recvfrom problem with udp: fromaddr and port
uses deleted netbuf
                 Project: lwIP - A Lightweight TCP/IP stack
            Submitted by: tsomogyi
            Submitted on: Tue 09 Dec 2008 14:13:47 GMT
                Category: sockets
                Severity: 3 - Normal
              Item Group: Faulty Behaviour
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
         Planned Release: 
            lwIP version: CVS Head

    _______________________________________________________

Details:

At the end of lwip_recvfrom, input address/port is extracted by "addr =
netbuf_fromaddr(buf)" for UDP sockets. But "buf" can already be disposed by
"netbuf_delete(buf);" in the do-while loop.

So if other threads (re-)use that buffer before the address has been copied
to "sin", then it will contain inapropriate data. This is often the case in my
application: I'm getting invalid address/port data 3-6 times/hour.

I fixed the problem by saving the address/port info before deleting netbuf:


lwip_recvfrom(...
//INSERTION-->
  struct ip_addr      saved_addr = { 0 };
  u16_t               saved_port = 0;
//<--INSERTION
  ...
      if ((sock->conn->type == NETCONN_TCP) && (buflen - copylen > 0)) {
        sock->lastdata = buf;
        sock->lastoffset += copylen;
        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now
netbuf=%p\n", (void*)buf));
      } else {
//INSERTION-->
        /* save addr before deleting buf */
        if (from && fromlen) {
          addr = netbuf_fromaddr(buf);
          if (addr) {
            saved_addr = *addr;
          }
          saved_port = netbuf_fromport(buf);
        }
        /* delete buf */
//<--INSERTION
        sock->lastdata = NULL;
        sock->lastoffset = 0;
        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n",
(void*)buf));
        netbuf_delete(buf);
//INSERTION-->
        buf = NULL;
//<--INSERTION
      }
  ...
  /* Check to see from where the data was.*/
  if (from && fromlen) {
    struct sockaddr_in sin;

    if (netconn_type(sock->conn) == NETCONN_TCP) {
      addr = (struct ip_addr*)&(sin.sin_addr.s_addr);
      netconn_getaddr(sock->conn, addr, &port, 0);
    } else {
//CHANGE-->
      if (buf) {
        addr = netbuf_fromaddr(buf);
        port = netbuf_fromport(buf);
      } else {
        addr = &saved_addr;
        port = saved_port;
      }
//<--CHANGE
    }
  ...
  and the same change in #if SOCKETS_DEBUG section
  ...
}


This is just a quick fix also proving that the root of the problem is here.
However it might be possible to give more sophisticated fix (e.g. if I knew
that buf would _always_ be disposed in the loop or when to set "done" to 1 or
using "mem" instead of "buf", etc.).




    _______________________________________________________

Reply to this item at:

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

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





reply via email to

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