Fixed bug #44032 (LWIP_NETCONN_FULLDUPLEX: select might work on invalid/reused socket) by not allowing to reallocate a socket that has "select_waiting != 0"

(cherry picked from commit c1c470fc4c)
This commit is contained in:
sg 2017-02-09 20:41:27 +01:00 committed by goldsimon
parent 0b7bef5420
commit 01c2e43c5c

View File

@ -407,7 +407,7 @@ alloc_socket(struct netconn *newconn, int accepted)
for (i = 0; i < NUM_SOCKETS; ++i) { for (i = 0; i < NUM_SOCKETS; ++i) {
/* Protect socket array */ /* Protect socket array */
SYS_ARCH_PROTECT(lev); SYS_ARCH_PROTECT(lev);
if (!sockets[i].conn) { if (!sockets[i].conn && (sockets[i].select_waiting == 0)) {
sockets[i].conn = newconn; sockets[i].conn = newconn;
/* The socket is not yet known to anyone, so no need to protect /* The socket is not yet known to anyone, so no need to protect
after having marked it as used. */ after having marked it as used. */
@ -420,7 +420,6 @@ alloc_socket(struct netconn *newconn, int accepted)
sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
sockets[i].errevent = 0; sockets[i].errevent = 0;
sockets[i].err = 0; sockets[i].err = 0;
sockets[i].select_waiting = 0;
return i + LWIP_SOCKET_OFFSET; return i + LWIP_SOCKET_OFFSET;
} }
SYS_ARCH_UNPROTECT(lev); SYS_ARCH_UNPROTECT(lev);
@ -1490,9 +1489,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
SYS_ARCH_PROTECT(lev); SYS_ARCH_PROTECT(lev);
sock = tryget_socket(i); sock = tryget_socket(i);
if (sock != NULL) { if (sock != NULL) {
/* @todo: what if this is a new socket (reallocated?) in this case, /* for now, handle select_waiting==0... */
select_waiting-- would be wrong (a global 'sockalloc' counter,
stored per socket could help) */
LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
if (sock->select_waiting > 0) { if (sock->select_waiting > 0) {
sock->select_waiting--; sock->select_waiting--;