extmod/modlwip: Deregister all lwIP callbacks when closing a socket.

Otherwise they may be called on a socket that no longer exists.

For example, if the GC calls the finaliser on the socket and then reuses
its heap memory, the "callback" entry of the old socket may contain invalid
data.  If lwIP then calls the TCP callback the code may try to call the
user callback object which is now invalid.  The lwIP callbacks must be
deregistered during the closing of the socket, before all the pcb pointers
are set to NULL.
This commit is contained in:
Damien George 2018-07-20 12:59:24 +10:00
parent 055ee18919
commit 4a2051eec7
1 changed files with 6 additions and 0 deletions

View File

@ -1202,6 +1202,10 @@ STATIC mp_uint_t lwip_socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_
if (socket->pcb.tcp == NULL) {
return 0;
}
// Deregister callback (pcb.tcp is set to NULL below so must deregister now)
tcp_recv(socket->pcb.tcp, NULL);
switch (socket->type) {
case MOD_NETWORK_SOCK_STREAM: {
if (socket->pcb.tcp->state == LISTEN) {
@ -1222,6 +1226,8 @@ STATIC mp_uint_t lwip_socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_
if (!socket_is_listener) {
pbuf_free(socket->incoming.pbuf);
} else {
// Deregister callback and abort
tcp_poll(socket->incoming.connection, NULL, 0);
tcp_abort(socket->incoming.connection);
}
socket->incoming.pbuf = NULL;