diff -Nru varnish-6.2.1/debian/changelog varnish-6.2.1/debian/changelog --- varnish-6.2.1/debian/changelog 2019-09-08 07:59:25.000000000 +0100 +++ varnish-6.2.1/debian/changelog 2022-05-04 21:16:37.000000000 +0100 @@ -1,3 +1,14 @@ +varnish (6.2.1-2ubuntu0.1) focal-security; urgency=medium + + * SECURITY UPDATE: CVE-2019-20637, CVE-2020-11653, CVE-2021-36740, + CVE-2022-23959 (LP: #1939281, #1971504) + - debian/patches/CVE-2019-20637.patch: New patch from upstream GitHub. + - debian/patches/CVE-2020-11653.patch: New patch from tag varnish-6.2.3 in upstream GitHub. + - debian/patches/CVE-2021-36740.patch: New patch from tag varnish-6.0.8 in upstream GitHub. + - debian/patches/CVE-2022-23959.patch: New patch from Debian buster. + + -- Luís Infante da Câmara Wed, 04 May 2022 21:16:37 +0100 + varnish (6.2.1-2) unstable; urgency=medium * Update varnishreload script from upstream packaging repo, making diff -Nru varnish-6.2.1/debian/patches/CVE-2019-20637.patch varnish-6.2.1/debian/patches/CVE-2019-20637.patch --- varnish-6.2.1/debian/patches/CVE-2019-20637.patch 1970-01-01 01:00:00.000000000 +0100 +++ varnish-6.2.1/debian/patches/CVE-2019-20637.patch 2022-05-04 21:16:37.000000000 +0100 @@ -0,0 +1,16 @@ +Based on https://github.com/varnishcache/varnish-cache/commit/bd7b3d6d47ccbb5e1747126f8e2a297f38e56b8c +Line numbers changed for 6.2.1. + +diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c +index c04eb9bf7..6fdce85a2 100644 +--- a/bin/varnishd/cache/cache_req_fsm.c ++++ b/bin/varnishd/cache/cache_req_fsm.c +@@ -802,6 +802,8 @@ cnt_recv_prep(struct req *req, const char *ci) + req->is_hit = 0; + req->is_hitmiss = 0; + req->is_hitpass = 0; ++ req->err_code = 0; ++ req->err_reason = NULL; + } + + /*-------------------------------------------------------------------- diff -Nru varnish-6.2.1/debian/patches/CVE-2020-11653.patch varnish-6.2.1/debian/patches/CVE-2020-11653.patch --- varnish-6.2.1/debian/patches/CVE-2020-11653.patch 1970-01-01 01:00:00.000000000 +0100 +++ varnish-6.2.1/debian/patches/CVE-2020-11653.patch 2022-05-04 21:16:37.000000000 +0100 @@ -0,0 +1,47 @@ +diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c +index c9a0f5180..b6731b820 100644 +--- a/bin/varnishd/cache/cache_session.c ++++ b/bin/varnishd/cache/cache_session.c +@@ -403,6 +403,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) { +@@ -415,6 +416,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; +@@ -438,6 +440,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); +@@ -455,10 +458,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; + } diff -Nru varnish-6.2.1/debian/patches/CVE-2021-36740.patch varnish-6.2.1/debian/patches/CVE-2021-36740.patch --- varnish-6.2.1/debian/patches/CVE-2021-36740.patch 1970-01-01 01:00:00.000000000 +0100 +++ varnish-6.2.1/debian/patches/CVE-2021-36740.patch 2022-05-04 21:16:37.000000000 +0100 @@ -0,0 +1,133 @@ +From https://github.com/varnishcache/varnish-cache/commit/9be22198e258d0e7a5c41f4291792214a29405cf + +diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h +index c377d03aa..205b96ccb 100644 +--- a/bin/varnishd/http2/cache_http2.h ++++ b/bin/varnishd/http2/cache_http2.h +@@ -132,6 +132,8 @@ struct h2_req { + /* Where to wake this stream up */ + struct worker *wrk; + ++ ssize_t reqbody_bytes; ++ + VTAILQ_ENTRY(h2_req) tx_list; + h2_error error; + }; +diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c +index cb35bb487..98f5dc4f3 100644 +--- a/bin/varnishd/http2/cache_http2_proto.c ++++ b/bin/varnishd/http2/cache_http2_proto.c +@@ -572,6 +572,7 @@ h2_end_headers(struct worker *wrk, struct h2_sess *h2, + struct req *req, struct h2_req *r2) + { + h2_error h2e; ++ ssize_t cl; + + ASSERT_RXTHR(h2); + assert(r2->state == H2_S_OPEN); +@@ -597,14 +598,24 @@ h2_end_headers(struct worker *wrk, struct h2_sess *h2, + // XXX: Have I mentioned H/2 Is hodge-podge ? + http_CollectHdrSep(req->http, H_Cookie, "; "); // rfc7540,l,3114,3120 + ++ cl = http_GetContentLength(req->http); ++ assert(cl >= -2); ++ if (cl == -2) { ++ VSLb(h2->vsl, SLT_Debug, "Non-parseable Content-Length"); ++ return (H2SE_PROTOCOL_ERROR); ++ } ++ + if (req->req_body_status == REQ_BODY_INIT) { +- if (!http_GetHdr(req->http, H_Content_Length, NULL)) ++ if (cl == -1) + req->req_body_status = REQ_BODY_WITHOUT_LEN; + else + req->req_body_status = REQ_BODY_WITH_LEN; ++ req->htc->content_length = cl; + } else { ++ /* A HEADER frame contained END_STREAM */ + assert (req->req_body_status == REQ_BODY_NONE); +- if (http_GetContentLength(req->http) > 0) ++ r2->state = H2_S_CLOS_REM; ++ if (cl > 0) + return (H2CE_PROTOCOL_ERROR); //rfc7540,l,1838,1840 + } + +@@ -759,6 +769,7 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + int w1 = 0, w2 = 0; + char buf[4]; + unsigned wi; ++ ssize_t cl; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + ASSERT_RXTHR(h2); +@@ -754,6 +765,27 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + Lck_Lock(&h2->sess->mtx); + while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0) + AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0)); ++ if (h2->error || r2->error) { ++ Lck_Unlock(&h2->sess->mtx); ++ return (h2->error ? h2->error : r2->error); ++ } ++ ++ r2->reqbody_bytes += h2->rxf_len; ++ if (h2->rxf_flags & H2FF_DATA_END_STREAM) ++ r2->state = H2_S_CLOS_REM; ++ cl = r2->req->htc->content_length; ++ if (cl >= 0 && (r2->reqbody_bytes > cl || ++ (r2->state >= H2_S_CLOS_REM && r2->reqbody_bytes != cl))) { ++ VSLb(h2->vsl, SLT_Debug, ++ "H2: stream %u: Received data and Content-Length" ++ " mismatch", h2->rxf_stream); ++ r2->error = H2SE_PROTOCOL_ERROR; // rfc7540,l,3150,3163 ++ if (r2->cond) ++ AZ(pthread_cond_signal(r2->cond)); ++ Lck_Unlock(&h2->sess->mtx); ++ return (H2SE_PROTOCOL_ERROR); ++ } ++ + AZ(h2->mailcall); + h2->mailcall = r2; + h2->req0->r_window -= h2->rxf_len; +@@ -772,6 +800,8 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + r2->r_window += wi; + w2 = 1; + } ++ ++ + Lck_Unlock(&h2->sess->mtx); + + if (w1 || w2) { +@@ -794,7 +824,7 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) + struct h2_req *r2; + struct h2_sess *h2; + unsigned l; +- enum vfp_status retval = VFP_OK; ++ enum vfp_status retval; + + CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); + CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); +@@ -807,7 +837,6 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) + *lp = 0; + + Lck_Lock(&h2->sess->mtx); +- assert (r2->state == H2_S_OPEN); + r2->cond = &vc->wrk->cond; + while (h2->mailcall != r2 && h2->error == 0 && r2->error == 0) + AZ(Lck_CondWait(r2->cond, &h2->sess->mtx, 0)); +@@ -830,12 +859,10 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) + Lck_Unlock(&h2->sess->mtx); + return (VFP_OK); + } +- if (h2->rxf_len == 0) { +- if (h2->rxf_flags & H2FF_DATA_END_STREAM) { +- retval = VFP_END; +- r2->state = H2_S_CLOS_REM; +- } +- } ++ if (h2->rxf_len == 0 && r2->state >= H2_S_CLOS_REM) ++ retval = VFP_END; ++ else ++ retval = VFP_OK; + h2->mailcall = NULL; + AZ(pthread_cond_signal(h2->cond)); + } diff -Nru varnish-6.2.1/debian/patches/CVE-2022-23959.patch varnish-6.2.1/debian/patches/CVE-2022-23959.patch --- varnish-6.2.1/debian/patches/CVE-2022-23959.patch 1970-01-01 01:00:00.000000000 +0100 +++ varnish-6.2.1/debian/patches/CVE-2022-23959.patch 2022-05-04 21:16:37.000000000 +0100 @@ -0,0 +1,27 @@ +Changed for 6.2.1. + +From: Martin Blix Grydeland +Date: Fri, 17 Dec 2021 22:10:16 +0100 +X-Dgit-Generated: 6.1.1-1+deb10u3 bdd0ecb0018cc536ee370c7625aeb7b1addde6d9 +Subject: Mark req doclose when failing to ignore req body + +Previously we would ignore errors to iterate the request body into +oblivion in VRB_Ignore(), keeping the connection open. This opens an +out-of-sync vulnerability on H/1 connections. + +This patch tests the status of the request body in VRB_Ignore(), marking +the request failed and that it should be closed on errors. + +--- + +--- varnish-6.1.1.orig/bin/varnishd/cache/cache_req_body.c ++++ varnish-6.1.1/bin/varnishd/cache/cache_req_body.c +@@ -247,6 +247,8 @@ VRB_Ignore(struct req *req) + if (req->req_body_status == REQ_BODY_WITH_LEN || + req->req_body_status == REQ_BODY_WITHOUT_LEN) + (void)VRB_Iterate(req, httpq_req_body_discard, NULL); ++ if (req->req_body_status == REQ_BODY_FAIL) ++ req->doclose = SC_RX_BODY; + return (0); + } + diff -Nru varnish-6.2.1/debian/patches/debian-changes varnish-6.2.1/debian/patches/debian-changes --- varnish-6.2.1/debian/patches/debian-changes 1970-01-01 01:00:00.000000000 +0100 +++ varnish-6.2.1/debian/patches/debian-changes 2022-05-04 21:16:37.000000000 +0100 @@ -0,0 +1,26 @@ +The Debian packaging of varnish is maintained in git, using the merging +workflow described in dgit-maint-merge(7). There isn't a patch queue +that can be represented as a quilt series. + +A detailed breakdown of the changes is available from their canonical +representation - git commits in the packaging repository. For example, +to see the changes made by the Debian maintainer in the first upload +of upstream version 1.2.3, you could use: + + % git clone https://git.dgit.debian.org/varnish + % cd varnish + % git log --oneline 1.2.3..debian/1.2.3-1 -- . ':!debian' + +(If you have dgit, use `dgit clone varnish`, rather than plain `git +clone`.) + +A single combined diff, containing all the changes, follows. +--- /dev/null ++++ varnish-6.2.1/2 +@@ -0,0 +1,6 @@ ++ case WAITER_ACTION: ++ pp = sp->pool; ++ CHECK_OBJ_NOTNULL(pp, POOL_MAGIC); ++ assert(sizeof *tp <= WS_ReserveSize(sp->ws, sizeof *tp)); ++ tp = (void*)sp->ws->f; ++ tp->func = xp->unwait; diff -Nru varnish-6.2.1/debian/patches/series varnish-6.2.1/debian/patches/series --- varnish-6.2.1/debian/patches/series 1970-01-01 01:00:00.000000000 +0100 +++ varnish-6.2.1/debian/patches/series 2022-05-04 21:16:37.000000000 +0100 @@ -0,0 +1,7 @@ +CVE-2019-20637.patch +WS_ReserveAll.patch +WS_ReserveSize.patch +CVE-2020-11653.patch +CVE-2021-36740.patch +CVE-2022-23959.patch +debian-changes diff -Nru varnish-6.2.1/debian/patches/WS_ReserveAll.patch varnish-6.2.1/debian/patches/WS_ReserveAll.patch --- varnish-6.2.1/debian/patches/WS_ReserveAll.patch 1970-01-01 01:00:00.000000000 +0100 +++ varnish-6.2.1/debian/patches/WS_ReserveAll.patch 2022-05-04 21:16:37.000000000 +0100 @@ -0,0 +1,277 @@ +From https://github.com/varnishcache/varnish-cache/commit/c6df6a5fa9e5575b079d602895eb429db417c5cd + +diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h +index 163c52948..cc2fc993d 100644 +--- a/bin/varnishd/cache/cache.h ++++ b/bin/varnishd/cache/cache.h +@@ -765,6 +765,7 @@ void WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func, + + void WS_Init(struct ws *ws, const char *id, void *space, unsigned len); + unsigned WS_Reserve(struct ws *ws, unsigned bytes); ++unsigned WS_ReserveAll(struct ws *); + unsigned WS_ReserveLumps(struct ws *ws, size_t sz); + void WS_MarkOverflow(struct ws *ws); + void WS_Release(struct ws *ws, unsigned bytes); +diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c +index f43e214ff..1395f7101 100644 +--- a/bin/varnishd/cache/cache_hash.c ++++ b/bin/varnishd/cache/cache_hash.c +@@ -650,7 +650,7 @@ HSH_Purge(struct worker *wrk, struct objhead *oh, vtim_real ttl_now, + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); +- ospc = WS_Reserve(wrk->aws, 0); ++ ospc = WS_ReserveAll(wrk->aws); + assert(ospc >= sizeof *ocp); + /* + * Because of "soft" purges, there might be oc's in the list that has +diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c +index 63d25799b..f77fcf30c 100644 +--- a/bin/varnishd/cache/cache_http.c ++++ b/bin/varnishd/cache/cache_http.c +@@ -394,7 +394,7 @@ http_CollectHdrSep(struct http *hp, const char *hdr, const char *sep) + } + if (b == NULL) { + /* Found second header, start our collection */ +- ml = WS_Reserve(hp->ws, 0); ++ ml = WS_ReserveAll(hp->ws); + b = hp->ws->f; + e = b + ml; + x = Tlen(hp->hd[f]); +@@ -1228,7 +1228,7 @@ http_PrintfHeader(struct http *to, const char *fmt, ...) + unsigned l, n; + + CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); +- l = WS_Reserve(to->ws, 0); ++ l = WS_ReserveAll(to->ws); + va_start(ap, fmt); + n = vsnprintf(to->ws->f, l, fmt, ap); + va_end(ap); +diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c +index 259110d7b..eac4773fc 100644 +--- a/bin/varnishd/cache/cache_session.c ++++ b/bin/varnishd/cache/cache_session.c +@@ -203,7 +203,7 @@ HTC_RxInit(struct http_conn *htc, struct ws *ws) + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + htc->ws = ws; +- (void)WS_Reserve(htc->ws, 0); ++ (void)WS_ReserveAll(htc->ws); + htc->rxbuf_b = ws->f; + htc->rxbuf_e = ws->f; + if (htc->pipeline_b != NULL) { +diff --git a/bin/varnishd/cache/cache_vary.c b/bin/varnishd/cache/cache_vary.c +index 46d6930fb..4af92f69c 100644 +--- a/bin/varnishd/cache/cache_vary.c ++++ b/bin/varnishd/cache/cache_vary.c +@@ -230,7 +230,7 @@ VRY_Prep(struct req *req) + AZ(req->vary_b); + AZ(req->vary_l); + AZ(req->vary_e); +- (void)WS_Reserve(req->ws, 0); ++ (void)WS_ReserveAll(req->ws); + } else { + AN(req->ws->r); + } +diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c +index 2edfb85b6..bf1676653 100644 +--- a/bin/varnishd/cache/cache_vrt.c ++++ b/bin/varnishd/cache/cache_vrt.c +@@ -261,7 +261,7 @@ VRT_String(struct ws *ws, const char *h, const char *p, va_list ap) + unsigned u, x; + va_list aq; + +- u = WS_Reserve(ws, 0); ++ u = WS_ReserveAll(ws); + e = b = ws->f; + e += u; + +@@ -385,7 +385,7 @@ VRT_StrandsWS(struct ws *ws, const char *h, VCL_STRANDS s) + int i; + + AN(s); +- u = WS_Reserve(ws, 0); ++ u = WS_ReserveAll(ws); + + for (i = 0; i < s->n; i++) + if (s->p[i] != NULL && *s->p[i] != '\0') { +@@ -573,7 +573,7 @@ VRT_IP_string(VRT_CTX, VCL_IP ip) + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + if (ip == NULL) + return (NULL); +- len = WS_Reserve(ctx->ws, 0); ++ len = WS_ReserveAll(ctx->ws); + if (len == 0) { + WS_Release(ctx->ws, 0); + return (NULL); +diff --git a/bin/varnishd/cache/cache_vrt_filter.c b/bin/varnishd/cache/cache_vrt_filter.c +index 271be6ccd..f192c3a7a 100644 +--- a/bin/varnishd/cache/cache_vrt_filter.c ++++ b/bin/varnishd/cache/cache_vrt_filter.c +@@ -251,7 +251,7 @@ filter_on_ws(struct ws *ws, filter_list_t *func, void *arg) + + AN(func); + AN(arg); +- u = WS_Reserve(ws, 0); ++ u = WS_ReserveAll(ws); + if (u == 0) { + WS_Release(ws, 0); + WS_MarkOverflow(ws); +diff --git a/bin/varnishd/cache/cache_vrt_re.c b/bin/varnishd/cache/cache_vrt_re.c +index 9cd0de3e7..ad1f44de8 100644 +--- a/bin/varnishd/cache/cache_vrt_re.c ++++ b/bin/varnishd/cache/cache_vrt_re.c +@@ -127,7 +127,7 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re, + return (str); + } + +- u = WS_Reserve(ctx->ws, 0); ++ u = WS_ReserveAll(ctx->ws); + res_e = res_b = b0 = ctx->ws->f; + res_e += u; + +diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c +index 3ec5ec017..e0a9b1d48 100644 +--- a/bin/varnishd/cache/cache_ws.c ++++ b/bin/varnishd/cache/cache_ws.c +@@ -202,7 +202,7 @@ WS_Printf(struct ws *ws, const char *fmt, ...) + va_list ap; + char *p; + +- u = WS_Reserve(ws, 0); ++ u = WS_ReserveAll(ws); + p = ws->f; + va_start(ap, fmt); + v = vsnprintf(p, u, fmt, ap); +@@ -227,6 +227,30 @@ WS_Snapshot(struct ws *ws) + return (ws->f == ws->s ? 0 : (uintptr_t)ws->f); + } + ++/* ++ * WS_Release() must be called in all cases ++ */ ++unsigned ++WS_ReserveAll(struct ws *ws) ++{ ++ unsigned b; ++ ++ assert(ws->r == NULL); ++ ++ ws->r = ws->e; ++ b = pdiff(ws->f, ws->r); ++ ++ WS_Assert(ws); ++ DSL(DBG_WORKSPACE, 0, "WS_ReserveAll(%p) = %u", ws, b); ++ ++ return (b); ++} ++ ++/* ++ * bytes == 0 argument is deprecated - use WS_ReserveAll ++ * ++ * XXX rename to WS_ReserveSize and macro-wrap WS_Reserve to emit #warn ? ++ */ + unsigned + WS_Reserve(struct ws *ws, unsigned bytes) + { +@@ -253,11 +277,7 @@ WS_Reserve(struct ws *ws, unsigned bytes) + unsigned + WS_ReserveLumps(struct ws *ws, size_t sz) + { +- unsigned u; +- +- u = WS_Reserve(ws, 0); +- u /= sz; +- return (u); ++ return (WS_ReserveAll(ws) / sz); + } + + void +diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c +index 7ee71ac99..26e4cc5da 100644 +--- a/bin/varnishd/http2/cache_http2_deliver.c ++++ b/bin/varnishd/http2/cache_http2_deliver.c +@@ -225,9 +225,11 @@ h2_build_headers(struct vsb *resp, struct req *req) + uint8_t buf[6]; + ssize_t sz, sz1; + +- l = WS_Reserve(req->ws, 0); +- if (l < 10) ++ l = WS_ReserveAll(req->ws); ++ if (l < 10) { ++ WS_Release(req->ws, 0); + return (-1); ++ } + + AN(VSB_new(resp, req->ws->f, l, VSB_FIXEDLEN)); + +diff --git a/bin/varnishd/http2/cache_http2_hpack.c b/bin/varnishd/http2/cache_http2_hpack.c +index 0524f3e32..d55c37614 100644 +--- a/bin/varnishd/http2/cache_http2_hpack.c ++++ b/bin/varnishd/http2/cache_http2_hpack.c +@@ -175,7 +175,7 @@ h2h_decode_init(const struct h2_sess *h2) + d = h2->decode; + INIT_OBJ(d, H2H_DECODE_MAGIC); + VHD_Init(d->vhd); +- d->out_l = WS_Reserve(h2->new_req->http->ws, 0); ++ d->out_l = WS_ReserveAll(h2->new_req->http->ws); + assert(d->out_l > 0); /* Can't do any work without any buffer + space. Require non-zero size. */ + d->out = h2->new_req->http->ws->f; +diff --git a/lib/libvmod_blob/vmod_blob.c b/lib/libvmod_blob/vmod_blob.c +index 7820e810c..5fe6be553 100644 +--- a/lib/libvmod_blob/vmod_blob.c ++++ b/lib/libvmod_blob/vmod_blob.c +@@ -339,7 +339,7 @@ vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, VCL_STRANDS strings) + CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC); + + buf = WS_Front(ctx->ws); +- space = WS_Reserve(ctx->ws, 0); ++ space = WS_ReserveAll(ctx->ws); + + if (length <= 0) + length = -1; +@@ -378,7 +378,7 @@ encode(VRT_CTX, enum encoding enc, enum case_e kase, VCL_BLOB b) + CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC); + snap = WS_Snapshot(ctx->ws); + buf = WS_Front(ctx->ws); +- space = WS_Reserve(ctx->ws, 0); ++ space = WS_ReserveAll(ctx->ws); + + len = func[enc].encode(enc, kase, buf, space, b->blob, b->len); + +diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c +index d35d89f6c..11e5f8667 100644 +--- a/lib/libvmod_std/vmod_std.c ++++ b/lib/libvmod_std/vmod_std.c +@@ -72,7 +72,7 @@ vmod_updown(VRT_CTX, int up, const char *s, va_list ap) + const char *p; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); +- u = WS_Reserve(ctx->ws, 0); ++ u = WS_ReserveAll(ctx->ws); + e = b = ctx->ws->f; + e += u; + p = s; +diff --git a/lib/libvmod_vtc/vmod_vtc.c b/lib/libvmod_vtc/vmod_vtc.c +index 72320ba94..ee9d23fa0 100644 +--- a/lib/libvmod_vtc/vmod_vtc.c ++++ b/lib/libvmod_vtc/vmod_vtc.c +@@ -155,7 +155,7 @@ vmod_workspace_alloc(VRT_CTX, VCL_ENUM which, VCL_INT size) + WS_Assert(ws); + + if (size < 0) { +- size += WS_Reserve(ws, 0); ++ size += WS_ReserveAll(ws); + WS_Release(ws, 0); + } + if (size <= 0) { +@@ -182,7 +182,7 @@ vmod_workspace_free(VRT_CTX, VCL_ENUM which) + return(-1); + WS_Assert(ws); + +- u = WS_Reserve(ws, 0); ++ u = WS_ReserveAll(ws); + WS_Release(ws, 0); + return (u); + } diff -Nru varnish-6.2.1/debian/patches/WS_ReserveSize.patch varnish-6.2.1/debian/patches/WS_ReserveSize.patch --- varnish-6.2.1/debian/patches/WS_ReserveSize.patch 1970-01-01 01:00:00.000000000 +0100 +++ varnish-6.2.1/debian/patches/WS_ReserveSize.patch 2022-05-04 21:16:37.000000000 +0100 @@ -0,0 +1,116 @@ +From https://github.com/varnishcache/varnish-cache/commit/68de849b1e874403e9d1eb0145c10c6b5d35f541 + +diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h +index cc2fc993d..c67dca563 100644 +--- a/bin/varnishd/cache/cache.h ++++ b/bin/varnishd/cache/cache.h +@@ -764,7 +764,10 @@ void WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func, + /* cache_ws.c */ + + void WS_Init(struct ws *ws, const char *id, void *space, unsigned len); ++ ++/* WS_Reserve(): Use WS_ReserveSize() or WS_ReserveAll() */ + unsigned WS_Reserve(struct ws *ws, unsigned bytes); ++unsigned WS_ReserveSize(struct ws *, unsigned); + unsigned WS_ReserveAll(struct ws *); + unsigned WS_ReserveLumps(struct ws *ws, size_t sz); + void WS_MarkOverflow(struct ws *ws); +diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c +index eac4773fc..8c9e2d7c9 100644 +--- a/bin/varnishd/cache/cache_session.c ++++ b/bin/varnishd/cache/cache_session.c +@@ -112,7 +112,7 @@ ses_reserve_attr(struct sess *sp, enum sess_attr a, void **dst, int sz) + assert(a < SA_LAST); + assert(sz >= 0); + AN(dst); +- o = WS_Reserve(sp->ws, sz); ++ o = WS_ReserveSize(sp->ws, sz); + assert(o >= sz); + *dst = sp->ws->f; + o = sp->ws->f - sp->ws->s; +@@ -415,7 +415,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); +- assert(sizeof *tp <= WS_Reserve(sp->ws, sizeof *tp)); ++ assert(sizeof *tp <= WS_ReserveSize(sp->ws, sizeof *tp)); + tp = (void*)sp->ws->f; + tp->func = xp->unwait; + tp->priv = sp; +@@ -453,7 +453,7 @@ SES_Wait(struct sess *sp, const struct transport *xp) + /* + * put struct waited on the workspace + */ +- if (WS_Reserve(sp->ws, sizeof(struct waited)) ++ if (WS_ReserveSize(sp->ws, sizeof(struct waited)) + < sizeof(struct waited)) { + SES_Delete(sp, SC_OVERLOAD, NAN); + return; +diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c +index a0fc4eacb..c6a37b862 100644 +--- a/bin/varnishd/cache/cache_wrk.c ++++ b/bin/varnishd/cache/cache_wrk.c +@@ -238,7 +238,7 @@ Pool_Task_Arg(struct worker *wrk, enum task_prio prio, task_func_t *func, + retval = 0; + } + AZ(wrk2->task.func); +- assert(arg_len <= WS_Reserve(wrk2->aws, arg_len)); ++ assert(arg_len <= WS_ReserveSize(wrk2->aws, arg_len)); + memcpy(wrk2->aws->f, arg, arg_len); + wrk2->task.func = func; + wrk2->task.priv = wrk2->aws->f; +diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c +index e0a9b1d48..7b8df6d23 100644 +--- a/bin/varnishd/cache/cache_ws.c ++++ b/bin/varnishd/cache/cache_ws.c +@@ -247,9 +247,34 @@ WS_ReserveAll(struct ws *ws) + } + + /* +- * bytes == 0 argument is deprecated - use WS_ReserveAll +- * +- * XXX rename to WS_ReserveSize and macro-wrap WS_Reserve to emit #warn ? ++ * WS_Release() must be called for retval > 0 only ++ */ ++unsigned ++WS_ReserveSize(struct ws *ws, unsigned bytes) ++{ ++ unsigned b2; ++ ++ WS_Assert(ws); ++ assert(ws->r == NULL); ++ assert(bytes > 0); ++ ++ b2 = PRNDDN(ws->e - ws->f); ++ if (bytes < b2) ++ b2 = PRNDUP(bytes); ++ ++ if (ws->f + b2 > ws->e) { ++ WS_MarkOverflow(ws); ++ return (0); ++ } ++ ws->r = ws->f + b2; ++ DSL(DBG_WORKSPACE, 0, "WS_ReserveSize(%p, %u/%u) = %u", ++ ws, b2, bytes, pdiff(ws->f, ws->r)); ++ WS_Assert(ws); ++ return (pdiff(ws->f, ws->r)); ++} ++ ++/* ++ * XXX remove for 2020-03-15 release + */ + unsigned + WS_Reserve(struct ws *ws, unsigned bytes) +diff --git a/lib/libvmod_proxy/vmod_proxy.c b/lib/libvmod_proxy/vmod_proxy.c +index fa7b9617e..58f2db295 100644 +--- a/lib/libvmod_proxy/vmod_proxy.c ++++ b/lib/libvmod_proxy/vmod_proxy.c +@@ -105,7 +105,7 @@ tlv_string(VRT_CTX, int tlv) + + if (VPX_tlv(ctx->req, tlv, (void **)&dst, &len)) + return (NULL); +- if (!WS_Reserve(ctx->ws, len+1)) ++ if (!WS_ReserveSize(ctx->ws, len+1)) + return (NULL); + d = ctx->ws->f; + memcpy(d, dst, len);