>From 434da108bba904eb6ac9a56e705ec97ecfc65a4f Mon Sep 17 00:00:00 2001
From: Nils Goroll <[email protected]>
Date: Wed, 17 Feb 2016 10:28:38 +0100
Subject: [PATCH] Fix workspace overglow handling in VFP_Push() and test for it

Fixes #1739
---
 bin/varnishd/cache/cache_fetch.c      | 21 +++++++++++++++------
 bin/varnishd/cache/cache_fetch_proc.c |  5 ++++-
 bin/varnishtest/tests/r01739.vtc      | 31 +++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 7 deletions(-)
 create mode 100644 bin/varnishtest/tests/r01739.vtc

diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index c168108..c210bd3 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -537,6 +537,15 @@ vbf_fetch_body_helper(struct busyobj *bo)
 /*--------------------------------------------------------------------
  */
 
+#define vbf_vfp_push(bo, vfp, top)					\
+	if (VFP_Push((bo)->vfc, (vfp), (top)) == NULL) {		\
+		assert (WS_Overflowed((bo)->vfc->http->ws));		\
+		(void)VFP_Error((bo)->vfc, "Bo workspace overflowed");	\
+		(bo)->htc->doclose = SC_OVERLOAD;			\
+		VDI_Finish((bo)->wrk, bo);				\
+		return (F_STP_ERROR);					\
+	}
+
 static enum fetch_step
 vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 {
@@ -592,19 +601,19 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	assert(bo->do_gzip == 0 || bo->do_gunzip == 0);
 
 	if (bo->do_gunzip || (bo->is_gzip && bo->do_esi))
-		(void)VFP_Push(bo->vfc, &vfp_gunzip, 1);
+		vbf_vfp_push(bo, &vfp_gunzip, 1);
 
 	if (bo->htc->content_length != 0) {
 		if (bo->do_esi && bo->do_gzip) {
-			(void)VFP_Push(bo->vfc, &vfp_esi_gzip, 1);
+			vbf_vfp_push(bo, &vfp_esi_gzip, 1);
 		} else if (bo->do_esi && bo->is_gzip && !bo->do_gunzip) {
-			(void)VFP_Push(bo->vfc, &vfp_esi_gzip, 1);
+			vbf_vfp_push(bo, &vfp_esi_gzip, 1);
 		} else if (bo->do_esi) {
-			(void)VFP_Push(bo->vfc, &vfp_esi, 1);
+			vbf_vfp_push(bo, &vfp_esi, 1);
 		} else if (bo->do_gzip) {
-			(void)VFP_Push(bo->vfc, &vfp_gzip, 1);
+			vbf_vfp_push(bo, &vfp_gzip, 1);
 		} else if (bo->is_gzip && !bo->do_gunzip) {
-			(void)VFP_Push(bo->vfc, &vfp_testgunzip, 1);
+			vbf_vfp_push(bo, &vfp_testgunzip, 1);
 		}
 	}
 
diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c
index cb0e1d1..ce9d138 100644
--- a/bin/varnishd/cache/cache_fetch_proc.c
+++ b/bin/varnishd/cache/cache_fetch_proc.c
@@ -203,8 +203,11 @@ VFP_Push(struct vfp_ctx *vc, const struct vfp *vfp, int top)
 
 	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(vc->http, HTTP_MAGIC);
+
 	vfe = WS_Alloc(vc->http->ws, sizeof *vfe);
-	AN(vfe);
+	if (vfe == NULL)
+		return NULL;
+
 	INIT_OBJ(vfe, VFP_ENTRY_MAGIC);
 	vfe->vfp = vfp;
 	vfe->closed = VFP_OK;
diff --git a/bin/varnishtest/tests/r01739.vtc b/bin/varnishtest/tests/r01739.vtc
new file mode 100644
index 0000000..0cf73df
--- /dev/null
+++ b/bin/varnishtest/tests/r01739.vtc
@@ -0,0 +1,31 @@
+varnishtest "Check workspace overflow in fetch processor"
+
+server s1 {
+	rxreq
+	txresp -bodylen 1024
+} -start
+
+
+varnish v1 \
+ -vcl+backend {
+	import ${vmod_debug};
+	sub vcl_backend_fetch {
+	}
+	sub vcl_backend_response {
+		set beresp.do_gzip = true;
+		debug.workspace_allocate(backend, debug.workspace_free(backend) - 16);
+	}
+} -start
+
+logexpect l1 -v v1 -g raw {
+	expect * 1002 FetchError {^Bo workspace overflowed}
+	expect * =    Error      {^out of workspace [(]Bo[)]}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 503
+} -run
+
+logexpect l1 -wait
-- 
2.1.4

_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to