[master] 4ed6181f8 Fix a wrap-around issue in buffered VSLs

Poul-Henning Kamp phk at FreeBSD.org
Wed Nov 16 16:55:06 UTC 2022


commit 4ed6181f8d505283c879d34ac9bcbdc07074cdd9
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Nov 16 16:53:57 2022 +0000

    Fix a wrap-around issue in buffered VSLs

diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c
index afb74535e..7a217d6f8 100644
--- a/bin/varnishd/cache/cache_shmlog.c
+++ b/bin/varnishd/cache/cache_shmlog.c
@@ -151,6 +151,26 @@ vsl_hdr(enum VSL_tag_e tag, uint32_t *p, unsigned len, vxid_t vxid)
 	return (VSL_END(p, len));
 }
 
+/*--------------------------------------------------------------------
+ * Space available in a VSL buffer when accounting for overhead
+ */
+
+static unsigned
+vsl_space(const struct vsl_log *vsl)
+{
+	ptrdiff_t mlen;
+
+	mlen = vsl->wle - vsl->wlp;
+	assert(mlen >= 0);
+	if (mlen < VSL_OVERHEAD + 1)
+		return (0);
+	mlen -= VSL_OVERHEAD;
+	mlen *= sizeof *vsl->wlp;
+	if (mlen > cache_param->vsl_reclen)
+		mlen = cache_param->vsl_reclen;
+	return(mlen);
+}
+
 /*--------------------------------------------------------------------
  * Wrap the VSL buffer
  */
@@ -353,7 +373,7 @@ vslb_get(struct vsl_log *vsl, enum VSL_tag_e tag, unsigned *length)
 
 	/* If it still doesn't fit, truncate */
 	if (VSL_END(vsl->wlp, mlen) > vsl->wle)
-		mlen = ((char *)vsl->wle) - VSL_DATA(vsl->wlp);
+		mlen = vsl_space(vsl);
 
 	vsl->wlp = vsl_hdr(tag, vsl->wlp, mlen, vsl->wid);
 	vsl->wlr++;
@@ -448,7 +468,7 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap)
 
 	vsl_sanity(vsl);
 
-	mlen = (char *)vsl->wle - VSL_DATA(vsl->wlp);
+	mlen = vsl_space(vsl);
 
 	// First attempt, only if any space at all
 	if (mlen > 0) {
@@ -458,11 +478,10 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap)
 		va_end(ap2);
 	}
 
-	// Second attempt after a flush
-	if (mlen == 0 || n + 1 > mlen) {
-		// Second attempt after a flush
+	// Second attempt, if a flush might help
+	if (mlen == 0 || (n + 1 > mlen && n + 1 <= cache_param->vsl_reclen)) {
 		VSL_Flush(vsl, 1);
-		mlen = (char *)vsl->wle - VSL_DATA(vsl->wlp);
+		mlen = vsl_space(vsl);
 		p = VSL_DATA(vsl->wlp);
 		n = vsnprintf(p, mlen, fmt, ap);
 	}


More information about the varnish-commit mailing list