import UBI varnish-6.6.2-3.el9_2.1
This commit is contained in:
		
							parent
							
								
									5c76a49bf8
								
							
						
					
					
						commit
						4a00b436ae
					
				
							
								
								
									
										319
									
								
								SOURCES/varnish-6.6.2-CVE-2023-44487-rate_limit.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								SOURCES/varnish-6.6.2-CVE-2023-44487-rate_limit.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,319 @@ | ||||
| commit bb3f607590a102321a15a8a17474d87da8bec32c | ||||
| Author: Tomas Korbar <tkorbar@redhat.com> | ||||
| Date:   Tue Oct 17 16:52:32 2023 +0200 | ||||
| 
 | ||||
|     Upstream #3997 PR | ||||
|      | ||||
|     Fix CVE-2023-44487 | ||||
| 
 | ||||
| diff --git a/bin/varnishd/VSC_main.vsc b/bin/varnishd/VSC_main.vsc
 | ||||
| index 7b32584..d55b9df 100644
 | ||||
| --- a/bin/varnishd/VSC_main.vsc
 | ||||
| +++ b/bin/varnishd/VSC_main.vsc
 | ||||
| @@ -631,6 +631,14 @@
 | ||||
|   | ||||
|  	Number of session closes with Error VCL_FAILURE (VCL failure) | ||||
|   | ||||
| +.. varnish_vsc:: sc_rapid_reset
 | ||||
| +       :level: diag
 | ||||
| +       :oneliner:      Session Err RAPID_RESET
 | ||||
| +
 | ||||
| +       Number of times we failed an http/2 session because it hit its
 | ||||
| +       configured limits for the number of permitted rapid stream
 | ||||
| +       resets.
 | ||||
| +
 | ||||
|  .. varnish_vsc:: client_resp_500 | ||||
|  	:level: diag | ||||
|  	:group: wrk | ||||
| diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h
 | ||||
| index ea5eb52..9088e21 100644
 | ||||
| --- a/bin/varnishd/http2/cache_http2.h
 | ||||
| +++ b/bin/varnishd/http2/cache_http2.h
 | ||||
| @@ -184,6 +184,8 @@ struct h2_sess {
 | ||||
|  	VTAILQ_HEAD(,h2_req)		txqueue; | ||||
|   | ||||
|  	h2_error			error; | ||||
| +	double				rst_budget;
 | ||||
| +	vtim_real			last_rst;
 | ||||
|  }; | ||||
|   | ||||
|  #define ASSERT_RXTHR(h2) do {assert(h2->rxthr == pthread_self());} while(0) | ||||
| diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
 | ||||
| index 3597ec1..408acad 100644
 | ||||
| --- a/bin/varnishd/http2/cache_http2_proto.c
 | ||||
| +++ b/bin/varnishd/http2/cache_http2_proto.c
 | ||||
| @@ -45,6 +45,7 @@
 | ||||
|  #include "vtcp.h" | ||||
|  #include "vtim.h" | ||||
|   | ||||
| +#define H2_CUSTOM_ERRORS
 | ||||
|  #define H2EC1(U,v,r,d) const struct h2_error_s H2CE_##U[1] = {{#U,d,v,0,1,r}}; | ||||
|  #define H2EC2(U,v,r,d) const struct h2_error_s H2SE_##U[1] = {{#U,d,v,1,0,r}}; | ||||
|  #define H2EC3(U,v,r,d) H2EC1(U,v,r,d) H2EC2(U,v,r,d) | ||||
| @@ -304,9 +305,46 @@ h2_rx_push_promise(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
 | ||||
|  /********************************************************************** | ||||
|   */ | ||||
|   | ||||
| +static h2_error
 | ||||
| +h2_rapid_reset(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
 | ||||
| +{
 | ||||
| +	vtim_real now;
 | ||||
| +	vtim_dur d;
 | ||||
| +
 | ||||
| +	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 | ||||
| +	ASSERT_RXTHR(h2);
 | ||||
| +	CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
 | ||||
| +
 | ||||
| +	if (cache_param->h2_rapid_reset_limit == 0)
 | ||||
| +		return (0);
 | ||||
| +
 | ||||
| +	now = VTIM_real();
 | ||||
| +	CHECK_OBJ_NOTNULL(r2->req, REQ_MAGIC);
 | ||||
| +	AN(r2->req->t_first);
 | ||||
| +	if (now - r2->req->t_first > cache_param->h2_rapid_reset)
 | ||||
| +		return (0);
 | ||||
| +
 | ||||
| +	d = now - h2->last_rst;
 | ||||
| +	h2->rst_budget += cache_param->h2_rapid_reset_limit * d /
 | ||||
| +	    cache_param->h2_rapid_reset_period;
 | ||||
| +	h2->rst_budget = vmin_t(double, h2->rst_budget,
 | ||||
| +	    cache_param->h2_rapid_reset_limit);
 | ||||
| +	h2->last_rst = now;
 | ||||
| +
 | ||||
| +	if (h2->rst_budget < 1.0) {
 | ||||
| +		Lck_Lock(&h2->sess->mtx);
 | ||||
| +		VSLb(h2->vsl, SLT_Error, "H2: Hit RST limit. Closing session.");
 | ||||
| +		Lck_Unlock(&h2->sess->mtx);
 | ||||
| +		return (H2CE_RAPID_RESET);
 | ||||
| +	}
 | ||||
| +	h2->rst_budget -= 1.0;
 | ||||
| +	return (0);
 | ||||
| +}
 | ||||
| +
 | ||||
|  static h2_error v_matchproto_(h2_rxframe_f) | ||||
|  h2_rx_rst_stream(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) | ||||
|  { | ||||
| +	h2_error h2e;
 | ||||
|   | ||||
|  	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); | ||||
|  	ASSERT_RXTHR(h2); | ||||
| @@ -316,8 +354,9 @@ h2_rx_rst_stream(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
 | ||||
|  		return (H2CE_FRAME_SIZE_ERROR); | ||||
|  	if (r2 == NULL) | ||||
|  		return (0); | ||||
| +	h2e = h2_rapid_reset(wrk, h2, r2);
 | ||||
|  	h2_kill_req(wrk, h2, r2, h2_streamerror(vbe32dec(h2->rxf_data))); | ||||
| -	return (0);
 | ||||
| +	return (h2e);
 | ||||
|  } | ||||
|   | ||||
|  /********************************************************************** | ||||
| diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c
 | ||||
| index 36d4a1c..f81c94a 100644
 | ||||
| --- a/bin/varnishd/http2/cache_http2_session.c
 | ||||
| +++ b/bin/varnishd/http2/cache_http2_session.c
 | ||||
| @@ -128,6 +128,9 @@ h2_init_sess(const struct worker *wrk, struct sess *sp,
 | ||||
|  	h2_local_settings(&h2->local_settings); | ||||
|  	h2->remote_settings = H2_proto_settings; | ||||
|  	h2->decode = decode; | ||||
| +	h2->rst_budget = cache_param->h2_rapid_reset_limit;
 | ||||
| +	h2->last_rst = sp->t_open;
 | ||||
| +	AZ(isnan(h2->last_rst));
 | ||||
|   | ||||
|  	AZ(VHT_Init(h2->dectbl, h2->local_settings.header_table_size)); | ||||
|   | ||||
| diff --git a/bin/varnishtest/tests/r03996.vtc b/bin/varnishtest/tests/r03996.vtc
 | ||||
| new file mode 100644 | ||||
| index 0000000..3fee370
 | ||||
| --- /dev/null
 | ||||
| +++ b/bin/varnishtest/tests/r03996.vtc
 | ||||
| @@ -0,0 +1,51 @@
 | ||||
| +varnishtest "h2 rapid reset"
 | ||||
| +
 | ||||
| +barrier b1 sock 5
 | ||||
| +
 | ||||
| +server s1 {
 | ||||
| +	rxreq
 | ||||
| +	txresp
 | ||||
| +} -start
 | ||||
| +
 | ||||
| +varnish v1 -cliok "param.set feature +http2"
 | ||||
| +varnish v1 -cliok "param.set debug +syncvsl"
 | ||||
| +varnish v1 -cliok "param.set h2_rapid_reset_limit 3"
 | ||||
| +varnish v1 -cliok "param.set h2_rapid_reset 5"
 | ||||
| +
 | ||||
| +varnish v1 -vcl+backend {
 | ||||
| +	import vtc;
 | ||||
| +
 | ||||
| +	sub vcl_recv {
 | ||||
| +		vtc.barrier_sync("${b1_sock}");
 | ||||
| +	}
 | ||||
| +
 | ||||
| +} -start
 | ||||
| +
 | ||||
| +client c1 {
 | ||||
| +	stream 0 {
 | ||||
| +		rxgoaway
 | ||||
| +		expect goaway.err == ENHANCE_YOUR_CALM
 | ||||
| +	} -start
 | ||||
| +
 | ||||
| +	stream 1 {
 | ||||
| +		txreq
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +	stream 3 {
 | ||||
| +		txreq
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +	stream 5 {
 | ||||
| +		txreq
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +	stream 7 {
 | ||||
| +		txreq
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +
 | ||||
| +	barrier b1 sync
 | ||||
| +	stream 0 -wait
 | ||||
| +} -run
 | ||||
| +
 | ||||
| +varnish v1 -expect sc_rapid_reset == 1
 | ||||
| diff --git a/include/tbl/h2_error.h b/include/tbl/h2_error.h
 | ||||
| index e8104f8..11051de 100644
 | ||||
| --- a/include/tbl/h2_error.h
 | ||||
| +++ b/include/tbl/h2_error.h
 | ||||
| @@ -147,5 +147,17 @@ H2_ERROR(
 | ||||
|  	/* descr */	"Use HTTP/1.1 for the request" | ||||
|  ) | ||||
|   | ||||
| +#ifdef H2_CUSTOM_ERRORS
 | ||||
| +H2_ERROR(
 | ||||
| +       /* name */      RAPID_RESET,
 | ||||
| +       /* val */       11, /* ENHANCE_YOUR_CALM */
 | ||||
| +       /* types */     1,
 | ||||
| +       /* reason */    SC_RAPID_RESET,
 | ||||
| +       /* descr */     "http/2 rapid reset detected"
 | ||||
| +)
 | ||||
| +
 | ||||
| +#  undef H2_CUSTOM_ERRORS
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  #undef H2_ERROR | ||||
|  /*lint -restore */ | ||||
| diff --git a/include/tbl/params.h b/include/tbl/params.h
 | ||||
| index cca420c..4014dd6 100644
 | ||||
| --- a/include/tbl/params.h
 | ||||
| +++ b/include/tbl/params.h
 | ||||
| @@ -1217,6 +1217,47 @@ PARAM_SIMPLE(
 | ||||
|  	"HTTP2 maximum size of an uncompressed header list." | ||||
|  ) | ||||
|   | ||||
| +PARAM_SIMPLE(
 | ||||
| +	/* name */	h2_rapid_reset,
 | ||||
| +	/* typ */	timeout,
 | ||||
| +	/* min */	"0.000",
 | ||||
| +	/* max */	NULL,
 | ||||
| +	/* def */	"1.000",
 | ||||
| +	/* units */	"seconds",
 | ||||
| +	/* descr */
 | ||||
| +       "The upper threshold for how rapid an http/2 RST has to come for "
 | ||||
| +       "it to be treated as suspect and subjected to the rate limits "
 | ||||
| +       "specified by h2_rapid_reset_limit and h2_rapid_reset_period.",
 | ||||
| +	/* flags */	EXPERIMENTAL,
 | ||||
| +)
 | ||||
| +
 | ||||
| +PARAM_SIMPLE(
 | ||||
| +	/* name */	h2_rapid_reset_limit,
 | ||||
| +	/* typ */	uint,
 | ||||
| +	/* min */	"0",
 | ||||
| +	/* max */	NULL,
 | ||||
| +	/* def */	"3600",
 | ||||
| +	/* units */	NULL,
 | ||||
| +	/* descr */
 | ||||
| +	"HTTP2 RST Allowance.\n"
 | ||||
| +	"Specifies the maximum number of allowed stream resets issued by\n"
 | ||||
| +	"a client over a time period before the connection is closed.\n"
 | ||||
| +	"Setting this parameter to 0 disables the limit.",
 | ||||
| +	/* flags */	EXPERIMENTAL,
 | ||||
| +)
 | ||||
| +
 | ||||
| +PARAM_SIMPLE(
 | ||||
| +	/* name */	h2_rapid_reset_period,
 | ||||
| +	/* typ */	timeout,
 | ||||
| +	/* min */	"1.000",
 | ||||
| +	/* max */	NULL,
 | ||||
| +	/* def */	"60.000",
 | ||||
| +	/* units */	"seconds",
 | ||||
| +	/* descr */
 | ||||
| +	"HTTP2 sliding window duration for h2_rapid_reset_limit.",
 | ||||
| +	/* flags */	EXPERIMENTAL|WIZARD,
 | ||||
| +)
 | ||||
| +
 | ||||
|  /*-------------------------------------------------------------------- | ||||
|   * Memory pool parameters | ||||
|   */ | ||||
| diff --git a/include/tbl/sess_close.h b/include/tbl/sess_close.h
 | ||||
| index 9748314..6d2f635 100644
 | ||||
| --- a/include/tbl/sess_close.h
 | ||||
| +++ b/include/tbl/sess_close.h
 | ||||
| @@ -50,6 +50,7 @@ SESS_CLOSE(PIPE_OVERFLOW, pipe_overflow,1,	"Session pipe overflow")
 | ||||
|  SESS_CLOSE(RANGE_SHORT,   range_short,	1,	"Insufficient data for range") | ||||
|  SESS_CLOSE(REQ_HTTP20,	  req_http20,	1,	"HTTP2 not accepted") | ||||
|  SESS_CLOSE(VCL_FAILURE,	  vcl_failure,	1,	"VCL failure") | ||||
| +SESS_CLOSE(RAPID_RESET,	  rapid_reset,  1,      "HTTP2 rapid reset")
 | ||||
|  #undef SESS_CLOSE | ||||
|   | ||||
|  /*lint -restore */ | ||||
| diff --git a/include/vdef.h b/include/vdef.h
 | ||||
| index a9111fe..c85bea8 100644
 | ||||
| --- a/include/vdef.h
 | ||||
| +++ b/include/vdef.h
 | ||||
| @@ -106,6 +106,47 @@
 | ||||
|  #  define v_dont_optimize | ||||
|  #endif | ||||
|   | ||||
| +/**********************************************************************
 | ||||
| + * Find the minimum or maximum values.
 | ||||
| + * Only evaluate the expression once and perform type checking.
 | ||||
| + */
 | ||||
| +
 | ||||
| +/* ref: https://stackoverflow.com/a/17624752 */
 | ||||
| +
 | ||||
| +#define VINDIRECT(a, b, c)	a ## b ## c
 | ||||
| +#define VCOMBINE(a, b, c)	VINDIRECT(a, b, c)
 | ||||
| +
 | ||||
| +#if defined(__COUNTER__)
 | ||||
| +#	define VUNIQ_NAME(base)	VCOMBINE(base, __LINE__, __COUNTER__)
 | ||||
| +#else
 | ||||
| +#	define VUNIQ_NAME(base)	VCOMBINE(base, __LINE__, 0)
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef _lint
 | ||||
| +#define typeof(x) __typeof__(x)
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +/* ref: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html */
 | ||||
| +
 | ||||
| +#define _vtake(op, ta, tb, a, b, _va, _vb)				\
 | ||||
| +	({								\
 | ||||
| +	ta _va = (a);							\
 | ||||
| +	tb _vb = (b);							\
 | ||||
| +	(void)(&_va == &_vb);						\
 | ||||
| +	_va op _vb ? _va : _vb;						\
 | ||||
| +})
 | ||||
| +
 | ||||
| +#define opmin <
 | ||||
| +#define opmax >
 | ||||
| +#define vtake(n, ta, tb, a, b)	_vtake(op ## n, ta, tb, a, b,		\
 | ||||
| +    VUNIQ_NAME(_v ## n ## A), VUNIQ_NAME(_v ## n ## B))
 | ||||
| +
 | ||||
| +#define vmin(a, b)		vtake(min, typeof(a), typeof(b), a, b)
 | ||||
| +#define vmax(a, b)		vtake(max, typeof(a), typeof(b), a, b)
 | ||||
| +
 | ||||
| +#define vmin_t(type, a, b)	vtake(min, type, type, a, b)
 | ||||
| +#define vmax_t(type, a, b)	vtake(max, type, type, a, b)
 | ||||
| +
 | ||||
|  /********************************************************************* | ||||
|   * Pointer alignment magic | ||||
|   */ | ||||
							
								
								
									
										328
									
								
								SOURCES/varnish-6.6.2-CVE-2023-44487-vcl_vrt.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								SOURCES/varnish-6.6.2-CVE-2023-44487-vcl_vrt.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,328 @@ | ||||
| commit bb44b34d5e9078ede3769ef519badb65d340351a | ||||
| Author: Tomas Korbar <tkorbar@redhat.com> | ||||
| Date:   Wed Oct 18 12:32:24 2023 +0200 | ||||
| 
 | ||||
|     vcl_vrt: Skip VCL execution if the client is gone | ||||
|      | ||||
|     Upstream PR #3998 | ||||
|     and 4991d9f6e40f381d058a83fc21ceed90e34a822e for r03996.vtc | ||||
| 
 | ||||
| diff --git a/bin/varnishd/VSC_main.vsc b/bin/varnishd/VSC_main.vsc
 | ||||
| index d55b9df..0978c2f 100644
 | ||||
| --- a/bin/varnishd/VSC_main.vsc
 | ||||
| +++ b/bin/varnishd/VSC_main.vsc
 | ||||
| @@ -342,6 +342,15 @@
 | ||||
|  	Number of times an HTTP/2 stream was refused because the queue was | ||||
|  	too long already. See also parameter thread_queue_limit. | ||||
|   | ||||
| +.. varnish_vsc:: req_reset
 | ||||
| +	:group: wrk
 | ||||
| +	:oneliner:	Requests reset
 | ||||
| +
 | ||||
| +	Number of times a client left before the VCL processing of its
 | ||||
| +	requests completed. For HTTP/2 sessions, either the stream was
 | ||||
| +	reset by an RST_STREAM frame from the client, or a stream or
 | ||||
| +	connection error occurred.
 | ||||
| +
 | ||||
|  .. varnish_vsc:: n_object | ||||
|  	:type:	gauge | ||||
|  	:group: wrk | ||||
| diff --git a/bin/varnishd/cache/cache_transport.h b/bin/varnishd/cache/cache_transport.h
 | ||||
| index 3650291..be396b9 100644
 | ||||
| --- a/bin/varnishd/cache/cache_transport.h
 | ||||
| +++ b/bin/varnishd/cache/cache_transport.h
 | ||||
| @@ -44,6 +44,7 @@ typedef void vtr_sess_panic_f (struct vsb *, const struct sess *);
 | ||||
|  typedef void vtr_req_panic_f (struct vsb *, const struct req *); | ||||
|  typedef void vtr_req_fail_f (struct req *, enum sess_close); | ||||
|  typedef void vtr_reembark_f (struct worker *, struct req *); | ||||
| +typedef int vtr_poll_f (struct req *);
 | ||||
|  typedef int vtr_minimal_response_f (struct req *, uint16_t status); | ||||
|   | ||||
|  struct transport { | ||||
| @@ -64,6 +65,7 @@ struct transport {
 | ||||
|  	vtr_sess_panic_f		*sess_panic; | ||||
|  	vtr_req_panic_f			*req_panic; | ||||
|  	vtr_reembark_f			*reembark; | ||||
| +	vtr_poll_f			*poll;
 | ||||
|  	vtr_minimal_response_f		*minimal_response; | ||||
|   | ||||
|  	VTAILQ_ENTRY(transport)		list; | ||||
| diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c
 | ||||
| index 023ba00..2fbaff6 100644
 | ||||
| --- a/bin/varnishd/cache/cache_vrt_vcl.c
 | ||||
| +++ b/bin/varnishd/cache/cache_vrt_vcl.c
 | ||||
| @@ -42,6 +42,7 @@
 | ||||
|  #include "vbm.h" | ||||
|   | ||||
|  #include "cache_director.h" | ||||
| +#include "cache_transport.h"
 | ||||
|  #include "cache_vcl.h" | ||||
|  #include "vcc_interface.h" | ||||
|   | ||||
| @@ -437,6 +438,40 @@ VRT_VCL_Allow_Discard(struct vclref **refp)
 | ||||
|  	FREE_OBJ(ref); | ||||
|  } | ||||
|   | ||||
| +/*--------------------------------------------------------------------
 | ||||
| + */
 | ||||
| +
 | ||||
| +static int
 | ||||
| +req_poll(struct worker *wrk, struct req *req)
 | ||||
| +{
 | ||||
| +	struct req *top;
 | ||||
| +
 | ||||
| +	/* NB: Since a fail transition leads to vcl_synth, the request may be
 | ||||
| +	 * short-circuited twice.
 | ||||
| +	 */
 | ||||
| +	if (req->req_reset) {
 | ||||
| +		wrk->handling = VCL_RET_FAIL;
 | ||||
| +		return (-1);
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	top = req->top->topreq;
 | ||||
| +	CHECK_OBJ_NOTNULL(top, REQ_MAGIC);
 | ||||
| +	CHECK_OBJ_NOTNULL(top->transport, TRANSPORT_MAGIC);
 | ||||
| +
 | ||||
| +	if (!FEATURE(FEATURE_VCL_REQ_RESET))
 | ||||
| +		return (0);
 | ||||
| +	if (top->transport->poll == NULL)
 | ||||
| +		return (0);
 | ||||
| +	if (top->transport->poll(top) >= 0)
 | ||||
| +		return (0);
 | ||||
| +
 | ||||
| +	VSLb_ts_req(req, "Reset", W_TIM_real(wrk));
 | ||||
| +	wrk->stats->req_reset++;
 | ||||
| +	wrk->handling = VCL_RET_FAIL;
 | ||||
| +	req->req_reset = 1;
 | ||||
| +	return (-1);
 | ||||
| +}
 | ||||
| +
 | ||||
|  /*-------------------------------------------------------------------- | ||||
|   * Method functions to call into VCL programs. | ||||
|   * | ||||
| @@ -468,6 +503,8 @@ vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo,
 | ||||
|  		CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); | ||||
|  		CHECK_OBJ_NOTNULL(req->vcl, VCL_MAGIC); | ||||
|  		CHECK_OBJ_NOTNULL(req->top, REQTOP_MAGIC); | ||||
| +		if (req_poll(wrk, req))
 | ||||
| +			return;
 | ||||
|  		VCL_Req2Ctx(&ctx, req); | ||||
|  	} | ||||
|  	assert(ctx.now != 0); | ||||
| diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c
 | ||||
| index f81c94a..f978763 100644
 | ||||
| --- a/bin/varnishd/http2/cache_http2_session.c
 | ||||
| +++ b/bin/varnishd/http2/cache_http2_session.c
 | ||||
| @@ -439,6 +439,16 @@ h2_new_session(struct worker *wrk, void *arg)
 | ||||
|  	h2_del_sess(wrk, h2, h2->error->reason); | ||||
|  } | ||||
|   | ||||
| +static int v_matchproto_(vtr_poll_f)
 | ||||
| +h2_poll(struct req *req)
 | ||||
| +{
 | ||||
| +	struct h2_req *r2;
 | ||||
| +
 | ||||
| +	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 | ||||
| +	CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
 | ||||
| +	return (r2->error ? -1 : 1);
 | ||||
| +}
 | ||||
| +
 | ||||
|  struct transport H2_transport = { | ||||
|  	.name =			"H2", | ||||
|  	.magic =		TRANSPORT_MAGIC, | ||||
| @@ -448,4 +458,5 @@ struct transport H2_transport = {
 | ||||
|  	.req_body =		h2_req_body, | ||||
|  	.req_fail =		h2_req_fail, | ||||
|  	.sess_panic =		h2_sess_panic, | ||||
| +	.poll =			h2_poll,
 | ||||
|  }; | ||||
| diff --git a/bin/varnishd/mgt/mgt_param_bits.c b/bin/varnishd/mgt/mgt_param_bits.c
 | ||||
| index d6a9c3f..6d9b32a 100644
 | ||||
| --- a/bin/varnishd/mgt/mgt_param_bits.c
 | ||||
| +++ b/bin/varnishd/mgt/mgt_param_bits.c
 | ||||
| @@ -276,7 +276,7 @@ struct parspec VSL_parspec[] = {
 | ||||
|  #undef DEBUG_BIT | ||||
|  		}, | ||||
|  	{ "feature", tweak_feature, NULL, | ||||
| -		NULL, NULL, "default",
 | ||||
| +		NULL, NULL, "+validate_headers +vcl_req_reset",
 | ||||
|  		NULL, | ||||
|  		"Enable/Disable various minor features.\n" | ||||
|  		"\tdefault\tSet default value\n" | ||||
| diff --git a/bin/varnishtest/tests/r03996.vtc b/bin/varnishtest/tests/r03996.vtc
 | ||||
| index 3fee370..7faf783 100644
 | ||||
| --- a/bin/varnishtest/tests/r03996.vtc
 | ||||
| +++ b/bin/varnishtest/tests/r03996.vtc
 | ||||
| @@ -1,6 +1,7 @@
 | ||||
|  varnishtest "h2 rapid reset" | ||||
|   | ||||
| -barrier b1 sock 5
 | ||||
| +barrier b1 sock 2 -cyclic
 | ||||
| +barrier b2 sock 5 -cyclic
 | ||||
|   | ||||
|  server s1 { | ||||
|  	rxreq | ||||
| @@ -16,7 +17,10 @@ varnish v1 -vcl+backend {
 | ||||
|  	import vtc; | ||||
|   | ||||
|  	sub vcl_recv { | ||||
| -		vtc.barrier_sync("${b1_sock}");
 | ||||
| +		if (req.http.barrier) {
 | ||||
| +			vtc.barrier_sync(req.http.barrier);
 | ||||
| +		}
 | ||||
| +		vtc.barrier_sync("${b2_sock}");
 | ||||
|  	} | ||||
|   | ||||
|  } -start | ||||
| @@ -27,6 +31,41 @@ client c1 {
 | ||||
|  		expect goaway.err == ENHANCE_YOUR_CALM | ||||
|  	} -start | ||||
|   | ||||
| +	stream 1 {
 | ||||
| +		txreq -hdr barrier ${b1_sock}
 | ||||
| +		barrier b1 sync
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +	stream 3 {
 | ||||
| +		txreq -hdr barrier ${b1_sock}
 | ||||
| +		barrier b1 sync
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +	stream 5 {
 | ||||
| +		txreq -hdr barrier ${b1_sock}
 | ||||
| +		barrier b1 sync
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +	stream 7 {
 | ||||
| +		txreq -hdr barrier ${b1_sock}
 | ||||
| +		barrier b1 sync
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +
 | ||||
| +	barrier b2 sync
 | ||||
| +	stream 0 -wait
 | ||||
| +} -run
 | ||||
| +
 | ||||
| +varnish v1 -expect sc_rapid_reset == 1
 | ||||
| +
 | ||||
| +varnish v1 -cliok "param.set feature -vcl_req_reset"
 | ||||
| +
 | ||||
| +client c2 {
 | ||||
| +	stream 0 {
 | ||||
| +		rxgoaway
 | ||||
| +		expect goaway.err == ENHANCE_YOUR_CALM
 | ||||
| +	} -start
 | ||||
| +
 | ||||
|  	stream 1 { | ||||
|  		txreq | ||||
|  		txrst | ||||
| @@ -44,8 +83,8 @@ client c1 {
 | ||||
|  		txrst | ||||
|  	} -run | ||||
|   | ||||
| -	barrier b1 sync
 | ||||
| +	barrier b2 sync
 | ||||
|  	stream 0 -wait | ||||
|  } -run | ||||
|   | ||||
| -varnish v1 -expect sc_rapid_reset == 1
 | ||||
| +varnish v1 -expect sc_rapid_reset == 2
 | ||||
| diff --git a/bin/varnishtest/tests/t02025.vtc b/bin/varnishtest/tests/t02025.vtc
 | ||||
| new file mode 100644 | ||||
| index 0000000..3b7e90e
 | ||||
| --- /dev/null
 | ||||
| +++ b/bin/varnishtest/tests/t02025.vtc
 | ||||
| @@ -0,0 +1,49 @@
 | ||||
| +varnishtest "h2 reset interrupt"
 | ||||
| +
 | ||||
| +barrier b1 sock 2
 | ||||
| +barrier b2 sock 2
 | ||||
| +
 | ||||
| +varnish v1 -cliok "param.set feature +http2"
 | ||||
| +varnish v1 -cliok "param.set debug +syncvsl"
 | ||||
| +varnish v1 -vcl {
 | ||||
| +	import vtc;
 | ||||
| +
 | ||||
| +	backend be none;
 | ||||
| +
 | ||||
| +	sub vcl_recv {
 | ||||
| +		vtc.barrier_sync("${b1_sock}");
 | ||||
| +		vtc.barrier_sync("${b2_sock}");
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	sub vcl_miss {
 | ||||
| +		vtc.panic("unreachable");
 | ||||
| +	}
 | ||||
| +} -start
 | ||||
| +
 | ||||
| +logexpect l1 -v v1 -g raw -i Debug {
 | ||||
| +	expect * * Debug "^H2RXF RST_STREAM"
 | ||||
| +} -start
 | ||||
| +
 | ||||
| +client c1 {
 | ||||
| +	stream 1 {
 | ||||
| +		txreq
 | ||||
| +		barrier b1 sync
 | ||||
| +		txrst
 | ||||
| +	} -run
 | ||||
| +} -start
 | ||||
| +
 | ||||
| +logexpect l1 -wait
 | ||||
| +barrier b2 sync
 | ||||
| +
 | ||||
| +varnish v1 -vsl_catchup
 | ||||
| +varnish v1 -expect req_reset == 1
 | ||||
| +
 | ||||
| +# NB: The varnishncsa command below shows a minimal pattern to collect
 | ||||
| +# "rapid reset" suspects per session, with the IP address. Here rapid
 | ||||
| +# is interpreted as before a second elapsed. Session VXIDs showing up
 | ||||
| +# numerous times become increasingly more suspicious. The format can of
 | ||||
| +# course be extended to add anything else useful for data mining.
 | ||||
| +shell -expect "1000 ${localhost}" {
 | ||||
| +	varnishncsa -n ${v1_name} -d \
 | ||||
| +		-q 'Timestamp:Reset[2] < 1.0' -F '%{VSL:Begin[2]}x %h'
 | ||||
| +}
 | ||||
| diff --git a/doc/sphinx/reference/vsl.rst b/doc/sphinx/reference/vsl.rst
 | ||||
| index cf63089..f1ed987 100644
 | ||||
| --- a/doc/sphinx/reference/vsl.rst
 | ||||
| +++ b/doc/sphinx/reference/vsl.rst
 | ||||
| @@ -76,6 +76,11 @@ Resp
 | ||||
|  Restart | ||||
|  	Client request is being restarted. | ||||
|   | ||||
| +Reset
 | ||||
| +        The client closed its connection, reset its stream or caused
 | ||||
| +        a stream error that forced Varnish to reset the stream. Request
 | ||||
| +        processing is interrupted and considered failed.
 | ||||
| +
 | ||||
|  Pipe handling timestamps | ||||
|  ~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|   | ||||
| diff --git a/include/tbl/feature_bits.h b/include/tbl/feature_bits.h
 | ||||
| index d51b22c..3d6ac35 100644
 | ||||
| --- a/include/tbl/feature_bits.h
 | ||||
| +++ b/include/tbl/feature_bits.h
 | ||||
| @@ -82,6 +82,11 @@ FEATURE_BIT(BUSY_STATS_RATE,	busy_stats_rate,
 | ||||
|      "Make busy workers comply with thread_stats_rate." | ||||
|  ) | ||||
|   | ||||
| +FEATURE_BIT(VCL_REQ_RESET,			vcl_req_reset,
 | ||||
| +    "Stop processing client VCL once the client is gone. "
 | ||||
| +    "When this happens MAIN.req_reset is incremented."
 | ||||
| +)
 | ||||
| +
 | ||||
|  #undef FEATURE_BIT | ||||
|   | ||||
|  /*lint -restore */ | ||||
| diff --git a/include/tbl/req_flags.h b/include/tbl/req_flags.h
 | ||||
| index 2e82660..9e72312 100644
 | ||||
| --- a/include/tbl/req_flags.h
 | ||||
| +++ b/include/tbl/req_flags.h
 | ||||
| @@ -41,6 +41,7 @@ REQ_FLAG(is_hitpass,		1, 0, "")
 | ||||
|  REQ_FLAG(waitinglist,		0, 0, "") | ||||
|  REQ_FLAG(want100cont,		0, 0, "") | ||||
|  REQ_FLAG(late100cont,		0, 0, "") | ||||
| +REQ_FLAG(req_reset,		0, 0, "")
 | ||||
|  #undef REQ_FLAG | ||||
|   | ||||
|  /*lint -restore */ | ||||
| @ -23,7 +23,7 @@ | ||||
| Summary: High-performance HTTP accelerator | ||||
| Name: varnish | ||||
| Version: 6.6.2 | ||||
| Release: 3%{?dist} | ||||
| Release: 3%{?dist}.1 | ||||
| License: BSD | ||||
| URL: https://www.varnish-cache.org/ | ||||
| Source0: http://varnish-cache.org/_downloads/%{name}-%{version}.tgz | ||||
| @ -67,6 +67,12 @@ Source1: https://github.com/varnishcache/pkg-varnish-cache/archive/%{commit1}.ta | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2141844 | ||||
| Patch100: varnish-6.6.2-CVE-2022-45060.patch | ||||
| 
 | ||||
| # https://issues.redhat.com/browse/RHEL-12816 | ||||
| Patch101: varnish-6.6.2-CVE-2023-44487-rate_limit.patch | ||||
| 
 | ||||
| # https://issues.redhat.com/browse/RHEL-12816 | ||||
| Patch102: varnish-6.6.2-CVE-2023-44487-vcl_vrt.patch | ||||
| 
 | ||||
| %if 0%{?fedora} > 29 | ||||
| Provides: varnish%{_isa} = %{version}-%{release} | ||||
| Provides: varnishd(abi)%{_isa} = %{abi} | ||||
| @ -160,6 +166,8 @@ cp redhat/find-provides . | ||||
| sed -i 's,rst2man-3.6,rst2man-3.4,g; s,rst2html-3.6,rst2html-3.4,g; s,phinx-build-3.6,phinx-build-3.4,g' configure | ||||
| 
 | ||||
| %patch100 -p1 -b .CVE-2022-45060 | ||||
| %patch101 -p1 -b .CVE-2023-44487 | ||||
| %patch102 -p1 -b .CVE-2023-44487-vcl | ||||
| 
 | ||||
| %build | ||||
| # https://gcc.gnu.org/wiki/FAQ#PR323 | ||||
| @ -205,6 +213,9 @@ rm -rf doc/html/_sources | ||||
| %ifarch s390 s390x aarch64 | ||||
| rm bin/varnishtest/tests/o00005.vtc | ||||
| %endif | ||||
| # disable test because of CVE-2023-44487 fix | ||||
| # https://github.com/varnishcache/varnish-cache/pull/3998#issuecomment-1764649216 | ||||
| rm bin/varnishtest/tests/t02014.vtc | ||||
| 
 | ||||
| make %{?_smp_mflags} check VERBOSE=1 | ||||
| 
 | ||||
| @ -305,6 +316,10 @@ test -f /etc/varnish/secret || (uuidgen > /etc/varnish/secret && chmod 0600 /etc | ||||
| 
 | ||||
| 
 | ||||
| %changelog | ||||
| * Thu Oct 12 2023 Tomas Korbar <tkorbar@redhat.com> - 6.6.2-3.1 | ||||
| - Add parameters h2_rst_allowance and h2_rst_allowance_period to mitigate CVE-2023-44487 | ||||
| - Resolves: RHEL-12816 | ||||
| 
 | ||||
| * Mon Dec 05 2022 Luboš Uhliarik <luhliari@redhat.com> - 6.6.2-3 | ||||
| - Resolves: #2142096 - CVE-2022-45060 varnish: Request Forgery Vulnerability | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user