[master] 0f3af407f Handle workspace allocation errors in VEP_Init()
Nils Goroll
nils.goroll at uplex.de
Wed Apr 1 08:10:07 UTC 2020
commit 0f3af407f65ac4bc6d446c61fb3e3b50747194cd
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Wed Mar 18 16:57:15 2020 +0100
Handle workspace allocation errors in VEP_Init()
Turn assertion into VFP error
The vtc is based upon r02645.vtc and reliably reproduces the panic
without the patch by sweeping through possible amounts of free workspace
ranging from 4 to 400 bytes.
Fixes #3253
diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c
index 74b430173..4592d37cc 100644
--- a/bin/varnishd/cache/cache_esi_fetch.c
+++ b/bin/varnishd/cache/cache_esi_fetch.c
@@ -165,8 +165,13 @@ vfp_esi_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
if (vef == NULL)
return (VFP_ERROR);
vc->obj_flags |= OF_GZIPED | OF_CHGCE | OF_ESIPROC;
- vef->vgz = VGZ_NewGzip(vc->wrk->vsl, "G F E");
vef->vep = VEP_Init(vc, vc->req, vfp_vep_callback, vef);
+ if (vef->vep == NULL) {
+ FREE_OBJ(vef);
+ return (VFP_ERROR);
+ }
+ vef->vgz = VGZ_NewGzip(vc->wrk->vsl, "G F E");
+
vef->ibuf_sz = cache_param->gzip_buffer;
vef->ibuf = calloc(1L, vef->ibuf_sz);
if (vef->ibuf == NULL)
@@ -232,6 +237,7 @@ static enum vfp_status v_matchproto_(vfp_init_f)
vfp_esi_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
{
struct vef_priv *vef;
+ struct vep_state *vep;
CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vc->req, HTTP_MAGIC);
@@ -240,11 +246,14 @@ vfp_esi_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
"Attempted ESI on partial (206) response");
return (VFP_ERROR);
}
+ vep = VEP_Init(vc, vc->req, NULL, NULL);
+ if (vep == NULL)
+ return (VFP_ERROR);
ALLOC_OBJ(vef, VEF_MAGIC);
if (vef == NULL)
return (VFP_ERROR);
vc->obj_flags |= OF_ESIPROC;
- vef->vep = VEP_Init(vc, vc->req, NULL, NULL);
+ vef->vep = vep;
vfe->priv1 = vef;
return (VFP_OK);
}
diff --git a/bin/varnishd/cache/cache_esi_parse.c b/bin/varnishd/cache/cache_esi_parse.c
index 2cd1f85c8..995087aa5 100644
--- a/bin/varnishd/cache/cache_esi_parse.c
+++ b/bin/varnishd/cache/cache_esi_parse.c
@@ -1042,7 +1042,11 @@ VEP_Init(struct vfp_ctx *vc, const struct http *req, vep_callback_t *cb,
CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
CHECK_OBJ_NOTNULL(req, HTTP_MAGIC);
vep = WS_Alloc(vc->resp->ws, sizeof *vep);
- AN(vep);
+ if (vep == NULL) {
+ VSLb(vc->wrk->vsl, SLT_VCL_Error,
+ "VEP_Init() workspace overflow");
+ return (NULL);
+ }
INIT_OBJ(vep, VEP_MAGIC);
vep->url = req->hd[HTTP_HDR_URL].b;
diff --git a/bin/varnishtest/tests/r03253.vtc b/bin/varnishtest/tests/r03253.vtc
new file mode 100644
index 000000000..af72560c5
--- /dev/null
+++ b/bin/varnishtest/tests/r03253.vtc
@@ -0,0 +1,26 @@
+varnishtest "ESI: sweep through tight backend workspace conditions"
+
+server s1 -repeat 100 {
+ rxreq
+ txresp -gzipbody "<html>"
+} -start
+
+varnish v1 -vcl+backend {
+ import vtc;
+ import std;
+ sub vcl_recv {
+ return (pass);
+ }
+ sub vcl_backend_response {
+ vtc.workspace_alloc(backend, -4 *
+ (std.integer(bereq.xid, 1002) - 1000) / 2);
+ set beresp.do_esi = true;
+ }
+} -start
+
+client c1 -repeat 100 {
+ txreq -url "/"
+ # some responses will fail (503), some won't. All we care
+ # about here is the fact that we don't panic
+ rxresp
+} -run
More information about the varnish-commit
mailing list