Fixed bug #51990: Calling select() from different threads with MPU enabled triggers memory protection fault

Signed-off-by: goldsimon <goldsimon@gmx.de>
This commit is contained in:
David Lockyer
2017-09-12 21:19:54 +02:00
committed by goldsimon
parent 445eef2b0e
commit 72a00ca79c
5 changed files with 78 additions and 54 deletions

View File

@@ -488,6 +488,15 @@
#define MEMP_NUM_NETCONN 4
#endif
/**
* MEMP_NUM_SELECT_CB: the number of struct lwip_select_cb.
* (Only needed if you have LWIP_MPU_COMPATIBLE==1 and use the socket API.
* In that case, you need one per thread calling lwip_select.)
*/
#if !defined MEMP_NUM_SELECT_CB || defined __DOXYGEN__
#define MEMP_NUM_SELECT_CB 4
#endif
/**
* MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
* for callback/timeout API communication.

View File

@@ -78,6 +78,9 @@ LWIP_MEMPOOL(DNS_API_MSG, MEMP_NUM_DNS_API_MSG, sizeof(struct dns_api_msg
#if LWIP_SOCKET && !LWIP_TCPIP_CORE_LOCKING
LWIP_MEMPOOL(SOCKET_SETGETSOCKOPT_DATA, MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA, sizeof(struct lwip_setgetsockopt_data), "SOCKET_SETGETSOCKOPT_DATA")
#endif
#if LWIP_SOCKET && LWIP_SOCKET_SELECT
LWIP_MEMPOOL(SELECT_CB, MEMP_NUM_SELECT_CB, sizeof(struct lwip_select_cb), "SELECT_CB")
#endif /* LWIP_SOCKET && LWIP_SOCKET_SELECT */
#if LWIP_NETIF_API
LWIP_MEMPOOL(NETIFAPI_MSG, MEMP_NUM_NETIFAPI_MSG, sizeof(struct netifapi_msg), "NETIFAPI_MSG")
#endif

View File

@@ -43,6 +43,7 @@
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#ifdef __cplusplus
extern "C" {
@@ -132,6 +133,32 @@ struct lwip_setgetsockopt_data {
struct lwip_sock* lwip_socket_dbg_get_socket(int fd);
#if LWIP_NETCONN_SEM_PER_THREAD
#define SELECT_SEM_T sys_sem_t*
#define SELECT_SEM_PTR(sem) (sem)
#else /* LWIP_NETCONN_SEM_PER_THREAD */
#define SELECT_SEM_T sys_sem_t
#define SELECT_SEM_PTR(sem) (&(sem))
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
/** Description for a task waiting in select */
struct lwip_select_cb {
/** Pointer to the next waiting task */
struct lwip_select_cb *next;
/** Pointer to the previous waiting task */
struct lwip_select_cb *prev;
/** readset passed to select */
fd_set *readset;
/** writeset passed to select */
fd_set *writeset;
/** unimplemented: exceptset passed to select */
fd_set *exceptset;
/** don't signal the same semaphore twice: set to 1 when signalled */
int sem_signalled;
/** semaphore to wake up a task waiting for select */
SELECT_SEM_T sem;
};
#endif /* LWIP_SOCKET */
#endif /* LWIP_HDR_SOCKETS_PRIV_H */

View File

@@ -55,12 +55,13 @@ struct netif;
#if LWIP_MPU_COMPATIBLE
#define API_VAR_REF(name) (*(name))
#define API_VAR_DECLARE(type, name) type * name
#define API_VAR_ALLOC(type, pool, name, errorval) do { \
#define API_VAR_ALLOC_EXT(type, pool, name, errorblock) do { \
name = (type *)memp_malloc(pool); \
if (name == NULL) { \
return errorval; \
errorblock; \
} \
} while(0)
#define API_VAR_ALLOC(type, pool, name, errorval) API_VAR_ALLOC_EXT(type, pool, name, return errorval)
#define API_VAR_ALLOC_POOL(type, pool, name, errorval) do { \
name = (type *)LWIP_MEMPOOL_ALLOC(pool); \
if (name == NULL) { \
@@ -81,6 +82,7 @@ struct netif;
#else /* LWIP_MPU_COMPATIBLE */
#define API_VAR_REF(name) name
#define API_VAR_DECLARE(type, name) type name
#define API_VAR_ALLOC_EXT(type, pool, name, errorblock)
#define API_VAR_ALLOC(type, pool, name, errorval)
#define API_VAR_ALLOC_POOL(type, pool, name, errorval)
#define API_VAR_FREE(pool, name)