[vlc-commits] rc: add lock for output (fixes #25200)

Rémi Denis-Courmont git at videolan.org
Sun Oct 18 20:26:05 CEST 2020


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Oct 18 21:19:59 2020 +0300| [47f1b7b645076b495deacbab76392d2ba2fec3ca] | committer: Rémi Denis-Courmont

rc: add lock for output (fixes #25200)

This fixes the (mostly harmless but nevertheless undefined behaviour)
data race on the output file descriptor.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=47f1b7b645076b495deacbab76392d2ba2fec3ca
---

 modules/control/cli/cli.c | 33 ++++++++++++++++++++++++---------
 modules/control/cli/cli.h |  1 +
 2 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/modules/control/cli/cli.c b/modules/control/cli/cli.c
index ed7df6b83f..5ec2d4d359 100644
--- a/modules/control/cli/cli.c
+++ b/modules/control/cli/cli.c
@@ -69,17 +69,25 @@ static void msg_vprint(intf_thread_t *p_intf, const char *psz_fmt, va_list args)
 {
 #ifndef _WIN32
     intf_sys_t *sys = p_intf->p_sys;
-    char fmt_eol[strlen (psz_fmt) + 3], *msg;
-    int len;
+    int fd;
 
-    snprintf (fmt_eol, sizeof (fmt_eol), "%s\r\n", psz_fmt);
-    len = vasprintf( &msg, fmt_eol, args );
+    vlc_mutex_lock(&sys->output_lock);
+    fd = sys->fd;
+    if (fd != -1)
+    {
+        char fmt_eol[strlen (psz_fmt) + 3], *msg;
+        int len;
 
-    if( len < 0 )
-        return;
+        snprintf(fmt_eol, sizeof (fmt_eol), "%s\r\n", psz_fmt);
+        len = vasprintf(&msg, fmt_eol, args);
 
-    vlc_write(sys->fd, msg, len);
-    free( msg );
+        if (len < 0)
+            return;
+
+        vlc_write(sys->fd, msg, len);
+        free(msg);
+    }
+    vlc_mutex_unlock(&sys->output_lock);
 #else
     char fmt_eol[strlen (psz_fmt) + 3], *msg;
     int len;
@@ -221,9 +229,11 @@ static void LogOut(intf_thread_t *intf, const char *const *args, size_t count)
 #ifndef _WIN32
     if (sys->pi_socket_listen != NULL)
     {
+        vlc_mutex_lock(&sys->output_lock);
+        sys->fd = -1;
+        vlc_mutex_unlock(&sys->output_lock);
         fclose(sys->stream);
         sys->stream = NULL;
-        sys->fd = -1;
     }
     else
     {   /* Force end-of-file on the standard input. */
@@ -363,7 +373,11 @@ static void *Run(void *data)
             fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
             sys->stream = fdopen(fd, "r");
             if (sys->stream != NULL)
+            {
+                vlc_mutex_lock(&sys->output_lock);
                 sys->fd = fd;
+                vlc_mutex_unlock(&sys->output_lock);
+            }
             else
                 vlc_close(fd);
             vlc_restorecancel(canc);
@@ -721,6 +735,7 @@ static int Activate( vlc_object_t *p_this )
 
     p_intf->p_sys = p_sys;
     p_sys->commands = NULL;
+    vlc_mutex_init(&p_sys->output_lock);
     p_sys->pi_socket_listen = pi_socket;
     p_sys->playlist = vlc_intf_GetMainPlaylist(p_intf);;
 
diff --git a/modules/control/cli/cli.h b/modules/control/cli/cli.h
index 7eaedafd87..ae2dedc5c1 100644
--- a/modules/control/cli/cli.h
+++ b/modules/control/cli/cli.h
@@ -34,6 +34,7 @@ struct intf_sys_t
     /* playlist */
     vlc_playlist_t              *playlist;
 
+    vlc_mutex_t output_lock;
 #ifndef _WIN32
     FILE *stream;
     int fd;



More information about the vlc-commits mailing list