Mailing List Archive

[6.0] a8cbe14c3 Handle workspace allocation errors in VEP_Init()
commit a8cbe14c33e7a9bb050c27e4a940cf1f710b8c1e
Author: Nils Goroll <nils.goroll@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 16ff6e749..3852dec88 100644
--- a/bin/varnishd/cache/cache_esi_fetch.c
+++ b/bin/varnishd/cache/cache_esi_fetch.c
@@ -164,8 +164,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)
@@ -231,6 +236,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);
@@ -239,11 +245,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 1c1f13a04..302203a98 100644
--- a/bin/varnishd/cache/cache_esi_parse.c
+++ b/bin/varnishd/cache/cache_esi_parse.c
@@ -1040,7 +1040,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
_______________________________________________
varnish-commit mailing list
varnish-commit@varnish-cache.org
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit