[vlc-devel] [PATCH] securetransport: Protect reading/writing with a mutex

Marvin Scholz epirat07 at gmail.com
Thu Oct 5 09:04:12 CEST 2017


Secure Transport reading/writing is not thread safe, doing it from
different threads results in memory corruption and other unpredictable
behavior.
---
 modules/misc/securetransport.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/modules/misc/securetransport.c b/modules/misc/securetransport.c
index 74d4b9cdc7..fcd5e8bc72 100644
--- a/modules/misc/securetransport.c
+++ b/modules/misc/securetransport.c
@@ -96,6 +96,8 @@ typedef struct {
     bool b_blocking_send;
     bool b_handshaked;
     bool b_server_mode;
+
+    vlc_mutex_t lock;
 } vlc_tls_st_t;
 
 static int st_Error (vlc_tls_t *obj, int val)
@@ -449,6 +451,8 @@ static ssize_t st_Send (vlc_tls_t *session, const struct iovec *iov,
     if (unlikely(count == 0))
         return 0;
 
+    vlc_mutex_lock(&sys->lock);
+
     /*
      * SSLWrite does not return the number of bytes actually written to
      * the socket, but the number of bytes written to the internal cache.
@@ -477,6 +481,7 @@ static ssize_t st_Send (vlc_tls_t *session, const struct iovec *iov,
             sys->i_send_buffered_bytes = 0;
 
         } else if (ret == errSSLWouldBlock) {
+            vlc_mutex_unlock(&sys->lock);
             errno = againErr;
             return -1;
         }
@@ -488,10 +493,12 @@ static ssize_t st_Send (vlc_tls_t *session, const struct iovec *iov,
         if (ret == errSSLWouldBlock) {
             sys->i_send_buffered_bytes = iov->iov_len;
             errno = againErr;
+            vlc_mutex_unlock(&sys->lock);
             return -1;
         }
     }
 
+    vlc_mutex_unlock(&sys->lock);
     return ret != noErr ? st_Error(session, ret) : actualSize;
 }
 
@@ -505,19 +512,25 @@ static ssize_t st_Recv (vlc_tls_t *session, struct iovec *iov, unsigned count)
     if (unlikely(count == 0))
         return 0;
 
+    vlc_mutex_lock(&sys->lock);
+
     size_t actualSize;
     OSStatus ret = SSLRead(sys->p_context, iov->iov_base, iov->iov_len,
                            &actualSize);
 
-    if (ret == errSSLWouldBlock && actualSize)
+    if (ret == errSSLWouldBlock && actualSize) {
+        vlc_mutex_unlock(&sys->lock);
         return actualSize;
+    }
 
     /* peer performed shutdown */
     if (ret == errSSLClosedNoNotify || ret == errSSLClosedGraceful) {
         msg_Dbg(sys->obj, "Got close notification with code %i", (int)ret);
+        vlc_mutex_unlock(&sys->lock);
         return 0;
     }
 
+    vlc_mutex_unlock(&sys->lock);
     return ret != noErr ? st_Error(session, ret) : actualSize;
 }
 
@@ -531,6 +544,8 @@ static int st_SessionShutdown (vlc_tls_t *session, bool duplex) {
 
     msg_Dbg(sys->obj, "shutdown TLS session");
 
+    vlc_mutex_destroy(&sys->lock);
+
     OSStatus ret = noErr;
     VLC_UNUSED(duplex);
 
@@ -581,6 +596,7 @@ static vlc_tls_t *st_SessionOpenCommon(vlc_tls_creds_t *crd, vlc_tls_t *sock,
     sys->p_context = NULL;
     sys->sock = sock;
     sys->b_server_mode = b_server;
+    vlc_mutex_init(&sys->lock);
     sys->obj = VLC_OBJECT(crd);
 
     vlc_tls_t *tls = &sys->tls;
-- 
2.13.5 (Apple Git-94)



More information about the vlc-devel mailing list