[master] 2d8fc1a78 Take sizeof pool_task into account when reserving WS in SES_Wait

Martin Blix Grydeland martin at varnish-software.com
Tue Feb 4 10:01:07 UTC 2020


commit 2d8fc1a784a1e26d78c30174923a2b14ee2ebf62
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Mon Dec 16 17:04:43 2019 +0100

    Take sizeof pool_task into account when reserving WS in SES_Wait
    
    The assert on WS_ReserveSize() in ses_handle() can not trip because
    sizeof (struct pool_task) is less than sizeof (struct waited). But to safe
    guard against future problems if that were to change, this patch makes
    sure that the session workspace can hold the largest of them before
    entering the waiter, erroring out if not.

diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index 1ba60742f..973304b88 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -419,6 +419,7 @@ ses_handle(struct waited *wp, enum wait_event ev, vtim_real now)
 	wp->magic = 0;
 	wp = NULL;
 
+	/* The WS was reserved in SES_Wait() */
 	WS_Release(sp->ws, 0);
 
 	switch (ev) {
@@ -431,6 +432,7 @@ ses_handle(struct waited *wp, enum wait_event ev, vtim_real now)
 	case WAITER_ACTION:
 		pp = sp->pool;
 		CHECK_OBJ_NOTNULL(pp, POOL_MAGIC);
+		/* SES_Wait() guarantees the next will not assert. */
 		assert(sizeof *tp <= WS_ReserveSize(sp->ws, sizeof *tp));
 		tp = (void*)sp->ws->f;
 		tp->func = xp->unwait;
@@ -454,6 +456,7 @@ SES_Wait(struct sess *sp, const struct transport *xp)
 {
 	struct pool *pp;
 	struct waited *wp;
+	unsigned u;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(xp, TRANSPORT_MAGIC);
@@ -467,10 +470,15 @@ SES_Wait(struct sess *sp, const struct transport *xp)
 	VTCP_nonblocking(sp->fd);
 
 	/*
-	 * put struct waited on the workspace
+	 * Put struct waited on the workspace. Make sure that the
+	 * workspace can hold enough space for the largest of struct
+	 * waited and pool_task, as pool_task will be needed when coming
+	 * off the waiter again.
 	 */
-	if (WS_ReserveSize(sp->ws, sizeof(struct waited))
-	    < sizeof(struct waited)) {
+	u = sizeof (struct waited);
+	if (sizeof (struct pool_task) > u)
+		u = sizeof (struct pool_task);
+	if (!WS_ReserveSize(sp->ws, u)) {
 		SES_Delete(sp, SC_OVERLOAD, NAN);
 		return;
 	}


More information about the varnish-commit mailing list