[7.3] 1fb4303d4 Fix a race between VBP_Remove() and vbp_thread()

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Wed Oct 25 14:33:09 UTC 2023


commit 1fb4303d4feaaaccd05354f9c9b327de21b743b3
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Tue Jul 11 23:37:05 2023 +0200

    Fix a race between VBP_Remove() and vbp_thread()
    
    Suppose the following happens:
    
    vbp_task() finishes with vt->running = 0 and a heap insert. The
    vbp_cond is signaled under the lock, but now instead of vbp_thread()
    waking up first, VBP_Remove() gets the lock and reaches
    assert(vt->heap_idx == VBH_NOIDX) before the racing vbp_thread()
    deleted the heap.
    
    This is unlikely to happen with static backends, because for those,
    the probe is stopped via the vcl temperature before they get removed.
    
    Fixes https://github.com/nigoroll/libvmod-dynamic/issues/100

diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c
index e4589dd37..800bb6b67 100644
--- a/bin/varnishd/cache/cache_backend_probe.c
+++ b/bin/varnishd/cache/cache_backend_probe.c
@@ -710,8 +710,12 @@ VBP_Remove(struct backend *be)
 	be->probe = NULL;
 	vt->backend = NULL;
 	if (vt->running) {
+		// task scheduled, it calls vbp_delete()
 		vt->running = -1;
 		vt = NULL;
+	} else if (vt->heap_idx != VBH_NOIDX) {
+		// task done, not yet rescheduled
+		VBH_delete(vbp_heap, vt->heap_idx);
 	}
 	Lck_Unlock(&vbp_mtx);
 	if (vt != NULL) {


More information about the varnish-commit mailing list