[vlc-commits] [Git][videolan/vlc][master] sd: fix race condition in vlc_media_source_provider_GetMediaSource

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Tue Dec 17 22:28:27 UTC 2024



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
62566105 by Pierre Lamot at 2024-12-17T22:16:16+00:00
sd: fix race condition in vlc_media_source_provider_GetMediaSource

T1:
  - calls vlc_media_source_Release
  - rc is decremented and equals 0
  - start calling vlc_media_source_Delete (provider->lock is not locked yet)
T2:
  - calls vlc_media_source_provider_GetMediaSource
  - locks provider->lock
  - vlc_media_source_provider_Find will return the node (not yet removed from the list)
  - vlc_media_source_Hold increments rc, assert as rc == 0

fix: #28891

- - - - -


1 changed file:

- src/media_source/media_source.c


Changes:

=====================================
src/media_source/media_source.c
=====================================
@@ -40,7 +40,7 @@ typedef struct
     vlc_media_source_t public_data;
 
     services_discovery_t *sd;
-    vlc_atomic_rc_t rc;
+    size_t rc;
     vlc_media_source_provider_t *owner;
     struct vlc_list node;
     char name[];
@@ -111,7 +111,7 @@ vlc_media_source_New(vlc_media_source_provider_t *provider, const char *name)
     if (unlikely(!priv))
         return NULL;
 
-    vlc_atomic_rc_init(&priv->rc);
+    priv->rc = 1;
 
     vlc_media_source_t *ms = &priv->public_data;
 
@@ -147,20 +147,12 @@ vlc_media_source_New(vlc_media_source_provider_t *provider, const char *name)
     return ms;
 }
 
-static void
-vlc_media_source_provider_Remove(vlc_media_source_provider_t *provider,
-                                 vlc_media_source_t *ms)
-{
-    vlc_mutex_lock(&provider->lock);
-    vlc_list_remove(&ms_priv(ms)->node);
-    vlc_mutex_unlock(&provider->lock);
-}
 
 static void
 vlc_media_source_Delete(vlc_media_source_t *ms)
 {
     media_source_private_t *priv = ms_priv(ms);
-    vlc_media_source_provider_Remove(priv->owner, ms);
+
     vlc_sd_Destroy(priv->sd);
     vlc_media_tree_Release(ms->tree);
     free(priv);
@@ -170,15 +162,31 @@ void
 vlc_media_source_Hold(vlc_media_source_t *ms)
 {
     media_source_private_t *priv = ms_priv(ms);
-    vlc_atomic_rc_inc(&priv->rc);
+    vlc_media_source_provider_t *provider = priv->owner;
+    vlc_mutex_lock(&provider->lock);
+    vlc_assert(priv->rc != 0);
+    priv->rc++;
+    vlc_mutex_unlock(&provider->lock);
 }
 
 void
 vlc_media_source_Release(vlc_media_source_t *ms)
 {
     media_source_private_t *priv = ms_priv(ms);
-    if (vlc_atomic_rc_dec(&priv->rc))
-        vlc_media_source_Delete(ms);
+    vlc_media_source_provider_t *provider = priv->owner;
+
+    vlc_mutex_lock(&provider->lock);
+    vlc_assert(priv->rc != 0);
+    priv->rc--;
+    if (priv->rc != 0)
+    {
+        vlc_mutex_unlock(&provider->lock);
+        return;
+    }
+    vlc_list_remove(&priv->node);
+    vlc_mutex_unlock(&provider->lock);
+
+    vlc_media_source_Delete(ms);
 }
 
 static vlc_media_source_t *
@@ -262,7 +270,11 @@ vlc_media_source_provider_GetMediaSource(vlc_media_source_provider_t *provider,
     vlc_mutex_lock(&provider->lock);
     vlc_media_source_t *ms = vlc_media_source_provider_Find(provider, name);
     if (ms)
-        vlc_media_source_Hold(ms);
+    {
+        media_source_private_t *priv = ms_priv(ms);
+        vlc_assert(priv->rc != 0);
+        priv->rc++;
+    }
     else
         ms = vlc_media_source_provider_Add(provider, name);
     vlc_mutex_unlock(&provider->lock);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/6256610531ef5a65681dd484568de36ea125a0e3

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/6256610531ef5a65681dd484568de36ea125a0e3
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list