[4.1] 5efed9d Error handling for V1F_Setup_Fetch

Nils Goroll nils.goroll at uplex.de
Thu Mar 17 19:22:05 CET 2016


commit 5efed9dadbda8f9a099020ab2d58a53b22941e99
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Thu Mar 17 19:16:55 2016 +0100

    Error handling for V1F_Setup_Fetch
    
    Fixes #1871

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 0718757..48e3e97 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -247,8 +247,7 @@ vbe_dir_getbody(const struct director *d, struct worker *wrk,
 	CHECK_OBJ_NOTNULL(bo->vfc, VFP_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
 
-	V1F_Setup_Fetch(bo->vfc, bo->htc);
-	return (0);
+	return (V1F_Setup_Fetch(bo->vfc, bo->htc));
 }
 
 static const struct suckaddr * __match_proto__(vdi_getip_f)
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 1a05c8f..03e833a 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -651,8 +651,14 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	      http_GetHdr(bo->beresp, H_ETag, &p)))
 		ObjSetFlag(bo->wrk, bo->fetch_objcore, OF_IMSCAND, 1);
 
-	if (bo->htc->body_status != BS_NONE)
-		AZ(VDI_GetBody(bo->wrk, bo));
+	if (bo->htc->body_status != BS_NONE &&
+	    VDI_GetBody(bo->wrk, bo) != 0) {
+		(void)VFP_Error(bo->vfc,
+		    "GetBody failed - backend_workspace overflow?");
+		bo->htc->doclose = SC_OVERLOAD;
+		VDI_Finish(bo->wrk, bo);
+		return (F_STP_ERROR);
+	}
 
 	assert(bo->refcount >= 1);
 
diff --git a/bin/varnishd/cache/cache_req_body.c b/bin/varnishd/cache/cache_req_body.c
index 63f0ba2..ccd7308 100644
--- a/bin/varnishd/cache/cache_req_body.c
+++ b/bin/varnishd/cache/cache_req_body.c
@@ -109,7 +109,11 @@ VRB_Iterate(struct req *req, req_body_iter_f *func, void *priv)
 	VFP_Setup(vfc);
 	vfc->http = req->http;
 	vfc->wrk = req->wrk;
-	V1F_Setup_Fetch(vfc, req->htc);
+	if (V1F_Setup_Fetch(vfc, req->htc) != 0) {
+		VSLb(req->vsl, SLT_FetchError, "Fetch Pipeline Setup failed -"
+		    "out of workspace?");
+		return (-1);
+	}
 	if (VFP_Open(vfc) < 0) {
 		VSLb(req->vsl, SLT_FetchError, "Could not open Fetch Pipeline");
 		return (-1);
@@ -239,7 +243,12 @@ VRB_Cache(struct req *req, ssize_t maxsize)
 
 	vfc->http = req->http;
 	vfc->oc = req->body_oc;
-	V1F_Setup_Fetch(vfc, req->htc);
+	if (V1F_Setup_Fetch(vfc, req->htc) != 0) {
+		(void)VFP_Error(vfc, "Fetch Pipeline Setup failed -"
+		    "out of workspace?");
+		req->req_body_status = REQ_BODY_FAIL;
+		return (-1);
+	}
 
 	if (VFP_Open(vfc) < 0) {
 		req->req_body_status = REQ_BODY_FAIL;
diff --git a/bin/varnishd/http1/cache_http1.h b/bin/varnishd/http1/cache_http1.h
index f717b78..2f59167 100644
--- a/bin/varnishd/http1/cache_http1.h
+++ b/bin/varnishd/http1/cache_http1.h
@@ -31,7 +31,7 @@
 int V1F_SendReq(struct worker *, struct busyobj *, uint64_t *ctr,
     int onlycached);
 int V1F_FetchRespHdr(struct busyobj *);
-void V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc);
+int V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc);
 
 /* cache_http1_fsm.c [HTTP1] */
 void HTTP1_Session(struct worker *, struct req *);
diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c
index 1c11384..b836cd3 100644
--- a/bin/varnishd/http1/cache_http1_vfp.c
+++ b/bin/varnishd/http1/cache_http1_vfp.c
@@ -260,7 +260,7 @@ static const struct vfp v1f_eof = {
 /*--------------------------------------------------------------------
  */
 
-void
+int
 V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc)
 {
 	struct vfp_entry *vfe;
@@ -272,19 +272,22 @@ V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc)
 	case BS_EOF:
 		assert(htc->content_length == -1);
 		vfe = VFP_Push(vfc, &v1f_eof, 0);
-		XXXAN(vfe);
+		if (vfe == NULL)
+			return (ENOSPC);
 		vfe->priv2 = 0;
 		break;
 	case BS_LENGTH:
 		assert(htc->content_length > 0);
 		vfe = VFP_Push(vfc, &v1f_straight, 0);
-		XXXAN(vfe);
+		if (vfe == NULL)
+			return (ENOSPC);
 		vfe->priv2 = htc->content_length;
 		break;
 	case BS_CHUNKED:
 		assert(htc->content_length == -1);
 		vfe = VFP_Push(vfc, &v1f_chunked, 0);
-		XXXAN(vfe);
+		if (vfe == NULL)
+			return (ENOSPC);
 		vfe->priv2 = -1;
 		break;
 	default:
@@ -292,4 +295,5 @@ V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc)
 		break;
 	}
 	vfe->priv1 = htc;
+	return 0;
 }



More information about the varnish-commit mailing list