mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 05:55:46 +08:00
udp:add tls cleanup protection to protect udp_callback info in psock_udp_recvfrom
Signed-off-by: wangchen <wangchen41@xiaomi.com>
This commit is contained in:
@@ -179,6 +179,14 @@ struct udp_wrbuffer_s
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct udp_callback_s
|
||||||
|
{
|
||||||
|
FAR struct net_driver_s *dev;
|
||||||
|
FAR struct udp_conn_s *conn;
|
||||||
|
FAR struct devif_callback_s *udp_cb;
|
||||||
|
FAR sem_t *sem;
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -727,6 +735,19 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn,
|
|||||||
uint16_t udp_callback(FAR struct net_driver_s *dev,
|
uint16_t udp_callback(FAR struct net_driver_s *dev,
|
||||||
FAR struct udp_conn_s *conn, uint16_t flags);
|
FAR struct udp_conn_s *conn, uint16_t flags);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: udp_callback_cleanup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Cleanup data and cb when thread is canceled.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* arg - A pointer with conn and callback struct.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void udp_callback_cleanup(FAR void *arg);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: psock_udp_recvfrom
|
* Name: psock_udp_recvfrom
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -326,4 +326,28 @@ uint16_t udp_callback(FAR struct net_driver_s *dev,
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: udp_callback_cleanup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Cleanup data and cb when thread is canceled.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* arg - A pointer with conn and callback struct.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void udp_callback_cleanup(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct udp_callback_s *cb = (FAR struct udp_callback_s *)arg;
|
||||||
|
|
||||||
|
nerr("ERROR: pthread is being canceled, need to cleanup cb\n");
|
||||||
|
|
||||||
|
udp_callback_free(cb->dev, cb->conn, cb->udp_cb);
|
||||||
|
if (cb->sem)
|
||||||
|
{
|
||||||
|
nxsem_destroy(cb->sem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET && CONFIG_NET_UDP */
|
#endif /* CONFIG_NET && CONFIG_NET_UDP */
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/ip.h>
|
#include <nuttx/net/ip.h>
|
||||||
#include <nuttx/net/udp.h>
|
#include <nuttx/net/udp.h>
|
||||||
|
#include <nuttx/tls.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include "netdev/netdev.h"
|
#include "netdev/netdev.h"
|
||||||
@@ -680,6 +681,7 @@ ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR struct msghdr *msg,
|
|||||||
{
|
{
|
||||||
FAR struct udp_conn_s *conn = psock->s_conn;
|
FAR struct udp_conn_s *conn = psock->s_conn;
|
||||||
FAR struct net_driver_s *dev;
|
FAR struct net_driver_s *dev;
|
||||||
|
struct udp_callback_s info;
|
||||||
struct udp_recvfrom_s state;
|
struct udp_recvfrom_s state;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -748,6 +750,16 @@ ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR struct msghdr *msg,
|
|||||||
state.ir_cb->priv = (FAR void *)&state;
|
state.ir_cb->priv = (FAR void *)&state;
|
||||||
state.ir_cb->event = udp_eventhandler;
|
state.ir_cb->event = udp_eventhandler;
|
||||||
|
|
||||||
|
/* Push a cancellation point onto the stack. This will be
|
||||||
|
* called if the thread is canceled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
info.dev = dev;
|
||||||
|
info.conn = conn;
|
||||||
|
info.udp_cb = state.ir_cb;
|
||||||
|
info.sem = &state.ir_sem;
|
||||||
|
tls_cleanup_push(tls_get_info(), udp_callback_cleanup, &info);
|
||||||
|
|
||||||
/* Wait for either the receive to complete or for an error/timeout
|
/* Wait for either the receive to complete or for an error/timeout
|
||||||
* to occur. net_sem_timedwait will also terminate if a signal is
|
* to occur. net_sem_timedwait will also terminate if a signal is
|
||||||
* received.
|
* received.
|
||||||
@@ -755,6 +767,7 @@ ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR struct msghdr *msg,
|
|||||||
|
|
||||||
ret = net_sem_timedwait(&state.ir_sem,
|
ret = net_sem_timedwait(&state.ir_sem,
|
||||||
_SO_TIMEOUT(conn->sconn.s_rcvtimeo));
|
_SO_TIMEOUT(conn->sconn.s_rcvtimeo));
|
||||||
|
tls_cleanup_pop(tls_get_info(), 0);
|
||||||
if (ret == -ETIMEDOUT)
|
if (ret == -ETIMEDOUT)
|
||||||
{
|
{
|
||||||
ret = -EAGAIN;
|
ret = -EAGAIN;
|
||||||
|
|||||||
Reference in New Issue
Block a user