[master] ba7bf7ff6 vsm: Do not store MAP_FAILED in a VSM segment

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Mon May 27 10:09:05 UTC 2024


commit ba7bf7ff6dba835e2cba9ad0a07131819272fb8e
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Fri May 24 15:29:42 2024 +0200

    vsm: Do not store MAP_FAILED in a VSM segment
    
    The problem is that a MAP_FAILED segment ends up in its vsm_set::segs
    list, at which point NULL checks will determine what to do with the
    segment, and MAP_FAILED != NULL.
    
    This can happen when winning (or losing?) the race with a VSC segment
    that goes away after being found in the index, but before being mapped.
    
    One surefire result is a crash in vsm_unmapseg() tripping on assertions
    that other fields are also not NULL. There may be other unidentified ill
    effects.

diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index a2c3f7e89..ad5438428 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -181,6 +181,7 @@ vsm_mapseg(struct vsm *vd, struct vsm_seg *vg)
 {
 	size_t of, off, sz, ps, len;
 	struct vsb *vsb;
+	void *s;
 	int fd;
 
 	CHECK_OBJ_NOTNULL(vg, VSM_SEG_MAGIC);
@@ -213,7 +214,7 @@ vsm_mapseg(struct vsm *vd, struct vsm_seg *vg)
 		return (vsm_diag(vd, "Could not open segment"));
 	}
 
-	vg->s = (void*)mmap(NULL, len,
+	s = (void*)mmap(NULL, len,
 	    PROT_READ,
 	    MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED,
 	    fd, (off_t)off);
@@ -221,9 +222,10 @@ vsm_mapseg(struct vsm *vd, struct vsm_seg *vg)
 	VSB_destroy(&vsb);
 
 	closefd(&fd);
-	if (vg->s == MAP_FAILED)
+	if (s == MAP_FAILED)
 		return (vsm_diag(vd, "Could not mmap segment"));
 
+	vg->s = s;
 	vg->b = (char*)(vg->s) + of - off;
 	vg->e = (char *)vg->b + sz;
 	vg->sz = len;


More information about the varnish-commit mailing list