sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and port uses deleted netbuf.

This commit is contained in:
fbernon 2008-12-10 21:36:44 +00:00
parent 6777ae2ada
commit 411cb39eb4
2 changed files with 56 additions and 51 deletions

View File

@ -56,6 +56,10 @@ HISTORY
++ Bugfixes: ++ Bugfixes:
2008-12-10 Tamas Somogyi, Frédéric Bernon
* sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and
port uses deleted netbuf.
2008-10-18 Simon Goldschmidt 2008-10-18 Simon Goldschmidt
* tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length
in tcp_parseopt in tcp_parseopt

View File

@ -530,34 +530,15 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
if (netconn_type(sock->conn) == NETCONN_TCP) { if (netconn_type(sock->conn) == NETCONN_TCP) {
len -= copylen; len -= copylen;
if ( (len <= 0) || (buf->p->flags & PBUF_FLAG_PUSH) || !sock->rcvevent) { if ( (len <= 0) || (buf->p->flags & PBUF_FLAG_PUSH) || !sock->rcvevent || ((flags & MSG_PEEK)!=0)) {
done = 1; done = 1;
} }
} else { } else {
done = 1; done = 1;
} }
/* If we don't peek the incoming message... */
if ((flags & MSG_PEEK)==0) {
/* If this is a TCP socket, check if there is data left in the
buffer. If so, it should be saved in the sock structure for next
time around. */
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 {
sock->lastdata = NULL;
sock->lastoffset = 0;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", (void*)buf));
netbuf_delete(buf);
}
} else {
done = 1;
}
} while (!done);
/* Check to see from where the data was.*/ /* Check to see from where the data was.*/
if (done) {
if (from && fromlen) { if (from && fromlen) {
struct sockaddr_in sin; struct sockaddr_in sin;
@ -575,8 +556,9 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
sin.sin_port = htons(port); sin.sin_port = htons(port);
sin.sin_addr.s_addr = addr->addr; sin.sin_addr.s_addr = addr->addr;
if (*fromlen > sizeof(sin)) if (*fromlen > sizeof(sin)) {
*fromlen = sizeof(sin); *fromlen = sizeof(sin);
}
SMEMCPY(from, &sin, *fromlen); SMEMCPY(from, &sin, *fromlen);
@ -584,7 +566,7 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
ip_addr_debug_print(SOCKETS_DEBUG, addr); ip_addr_debug_print(SOCKETS_DEBUG, addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off)); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off));
} else { } else {
#if SOCKETS_DEBUG #if SOCKETS_DEBUG
struct sockaddr_in sin; struct sockaddr_in sin;
if (netconn_type(sock->conn) == NETCONN_TCP) { if (netconn_type(sock->conn) == NETCONN_TCP) {
@ -598,8 +580,27 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
ip_addr_debug_print(SOCKETS_DEBUG, addr); ip_addr_debug_print(SOCKETS_DEBUG, addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off)); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off));
#endif /* SOCKETS_DEBUG */ #endif /* SOCKETS_DEBUG */
} }
}
/* If we don't peek the incoming message... */
if ((flags & MSG_PEEK)==0) {
/* If this is a TCP socket, check if there is data left in the
buffer. If so, it should be saved in the sock structure for next
time around. */
if ((netconn_type(sock->conn) == 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 {
sock->lastdata = NULL;
sock->lastoffset = 0;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", (void*)buf));
netbuf_delete(buf);
}
}
} while (!done);
sock_set_errno(sock, 0); sock_set_errno(sock, 0);
return off; return off;