aboutsummaryrefslogtreecommitdiff
path: root/extmod/modlwip.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2019-02-18 14:23:35 +1100
committerDamien George <damien.p.george@gmail.com>2019-02-18 14:23:35 +1100
commit42c0e440b9635fb33c0b2a162f5bfe3122dce079 (patch)
tree01720d5bb8487c2a145a8cf10c03926736fd76c8 /extmod/modlwip.c
parentc65e5c88b8ec805d40a4b040a56569f8b1aa8bab (diff)
extmod/modlwip: Fix bug when polling listening socket with backlog=1.
The bug polling for readability was: if alloc==0 and tcp.item==NULL then the code would incorrectly check tcp.array[iget] which is an invalid dereference when alloc==0. This patch refactors the code to use a helper function lwip_socket_incoming_array() to return the correct pointer for the incomming connection array. Fixes issue #4511.
Diffstat (limited to 'extmod/modlwip.c')
-rw-r--r--extmod/modlwip.c41
1 files changed, 16 insertions, 25 deletions
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index 36516803f..bd952111d 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2013-2019 Damien P. George
* Copyright (c) 2015 Galen Hazelwood
* Copyright (c) 2015-2017 Paul Sokolovsky
*
@@ -308,6 +308,14 @@ static inline void poll_sockets(void) {
#endif
}
+STATIC struct tcp_pcb *volatile *lwip_socket_incoming_array(lwip_socket_obj_t *socket) {
+ if (socket->incoming.connection.alloc == 0) {
+ return &socket->incoming.connection.tcp.item;
+ } else {
+ return &socket->incoming.connection.tcp.array[0];
+ }
+}
+
/*******************************************************************************/
// Callback functions for the lwIP raw API.
@@ -381,15 +389,10 @@ STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
tcp_recv(newpcb, _lwip_tcp_recv_unaccepted);
// Search for an empty slot to store the new connection
- struct tcp_pcb *volatile *tcp_array;
- if (socket->incoming.connection.alloc == 0) {
- tcp_array = &socket->incoming.connection.tcp.item;
- } else {
- tcp_array = socket->incoming.connection.tcp.array;
- }
- if (tcp_array[socket->incoming.connection.iput] == NULL) {
+ struct tcp_pcb *volatile *slot = &lwip_socket_incoming_array(socket)[socket->incoming.connection.iput];
+ if (*slot == NULL) {
// Have an empty slot to store waiting connection
- tcp_array[socket->incoming.connection.iput] = newpcb;
+ *slot = newpcb;
if (++socket->incoming.connection.iput >= socket->incoming.connection.alloc) {
socket->incoming.connection.iput = 0;
}
@@ -782,12 +785,7 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
}
// accept incoming connection
- struct tcp_pcb *volatile *incoming_connection;
- if (socket->incoming.connection.alloc == 0) {
- incoming_connection = &socket->incoming.connection.tcp.item;
- } else {
- incoming_connection = &socket->incoming.connection.tcp.array[socket->incoming.connection.iget];
- }
+ struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(socket)[socket->incoming.connection.iget];
if (*incoming_connection == NULL) {
if (socket->timeout == 0) {
mp_raise_OSError(MP_EAGAIN);
@@ -1218,10 +1216,8 @@ STATIC mp_uint_t lwip_socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_
if (flags & MP_STREAM_POLL_RD) {
if (socket->state == STATE_LISTENING) {
// Listening TCP socket may have one or multiple connections waiting
- if ((socket->incoming.connection.alloc == 0
- && socket->incoming.connection.tcp.item != NULL)
- || socket->incoming.connection.tcp.array[socket->incoming.connection.iget] != NULL) {
- ret |= MP_STREAM_POLL_RD;
+ if (lwip_socket_incoming_array(socket)[socket->incoming.connection.iget] != NULL) {
+ ret |= MP_STREAM_POLL_RD;
}
} else {
// Otherwise there is just one slot for incoming data
@@ -1292,12 +1288,7 @@ STATIC mp_uint_t lwip_socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_
}
} else {
uint8_t alloc = socket->incoming.connection.alloc;
- struct tcp_pcb *volatile *tcp_array;
- if (alloc == 0) {
- tcp_array = &socket->incoming.connection.tcp.item;
- } else {
- tcp_array = socket->incoming.connection.tcp.array;
- }
+ struct tcp_pcb *volatile *tcp_array = lwip_socket_incoming_array(socket);
for (uint8_t i = 0; i < alloc; ++i) {
// Deregister callback and abort
if (tcp_array[i] != NULL) {