This is an automated email from the ASF dual-hosted git repository.

archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 540036ab6024db9edd93136ad457ed8f24813295
Author: wangchen <wangche...@xiaomi.com>
AuthorDate: Wed Jun 26 23:35:37 2024 +0800

    udp:add tls cleanup protection to protect udp_callback info in 
psock_udp_recvfrom
    
    Signed-off-by: wangchen <wangche...@xiaomi.com>
---
 net/udp/udp.h          | 21 +++++++++++++++++++++
 net/udp/udp_callback.c | 24 ++++++++++++++++++++++++
 net/udp/udp_recvfrom.c | 13 +++++++++++++
 3 files changed, 58 insertions(+)

diff --git a/net/udp/udp.h b/net/udp/udp.h
index 86e2a3ce32..de28a43fc3 100644
--- a/net/udp/udp.h
+++ b/net/udp/udp.h
@@ -179,6 +179,14 @@ struct udp_wrbuffer_s
 };
 #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
  ****************************************************************************/
@@ -727,6 +735,19 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn,
 uint16_t udp_callback(FAR struct net_driver_s *dev,
                       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
  *
diff --git a/net/udp/udp_callback.c b/net/udp/udp_callback.c
index 390dcbf97c..970439c0f9 100644
--- a/net/udp/udp_callback.c
+++ b/net/udp/udp_callback.c
@@ -326,4 +326,28 @@ uint16_t udp_callback(FAR struct net_driver_s *dev,
   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 */
diff --git a/net/udp/udp_recvfrom.c b/net/udp/udp_recvfrom.c
index 0f19c9df20..0854a20c43 100644
--- a/net/udp/udp_recvfrom.c
+++ b/net/udp/udp_recvfrom.c
@@ -39,6 +39,7 @@
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/ip.h>
 #include <nuttx/net/udp.h>
+#include <nuttx/tls.h>
 #include <netinet/in.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 net_driver_s *dev;
+  struct udp_callback_s info;
   struct udp_recvfrom_s state;
   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->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
            * to occur.  net_sem_timedwait will also terminate if a signal is
            * 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,
                               _SO_TIMEOUT(conn->sconn.s_rcvtimeo));
+          tls_cleanup_pop(tls_get_info(), 0);
           if (ret == -ETIMEDOUT)
             {
               ret = -EAGAIN;

Reply via email to