[6.0] 7c3fac93c H2: Check rapid reset whenever we send a RST frame for a stream
Martin Blix Grydeland
martin at varnish-software.com
Wed Aug 13 12:03:06 UTC 2025
commit 7c3fac93c39260873b87f69b6178e73abb42be6b
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Tue Jul 1 15:50:10 2025 +0200
H2: Check rapid reset whenever we send a RST frame for a stream
This checks and charges the rapid reset budget whenever we send a RST
frame, causing a session error if the budget is exhausted.
This fixes the reverse rapid reset vulnerability.
diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c
index 520f3e5eb..51f5f0de8 100644
--- a/bin/varnishd/http2/cache_http2_send.c
+++ b/bin/varnishd/http2/cache_http2_send.c
@@ -419,6 +419,7 @@ H2_Send_RST(struct worker *wrk, struct h2_sess *h2, const struct h2_req *r2,
uint32_t stream, h2_error h2e)
{
char b[4];
+ h2_error h2e_rr = NULL;
CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
@@ -431,6 +432,11 @@ H2_Send_RST(struct worker *wrk, struct h2_sess *h2, const struct h2_req *r2,
vbe32enc(b, h2e->val);
H2_Send_Frame(wrk, h2, H2_F_RST_STREAM, 0, sizeof b, stream, b);
+
+ if (h2_rapid_reset_check(wrk, h2, r2))
+ h2e_rr = h2_rapid_reset_charge(wrk, h2, r2);
+ if (h2e_rr != NULL)
+ h2->error = h2e_rr;
}
void
diff --git a/bin/varnishtest/tests/f00017.vtc b/bin/varnishtest/tests/f00017.vtc
new file mode 100644
index 000000000..6370652be
--- /dev/null
+++ b/bin/varnishtest/tests/f00017.vtc
@@ -0,0 +1,63 @@
+varnishtest "h2 reverse rapid reset"
+
+barrier b1 sock 2 -cyclic
+barrier b2 sock 5 -cyclic
+
+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 {
+ if (req.http.barrier) {
+ vtc.barrier_sync(req.http.barrier);
+ }
+ vtc.barrier_sync("${b2_sock}");
+ }
+
+} -start
+
+client c1 {
+ stream 0 {
+ rxgoaway
+ expect goaway.err == ENHANCE_YOUR_CALM
+ } -start
+
+ stream 1 {
+ txreq -hdr barrier ${b1_sock}
+ barrier b1 sync
+ txwinup -size 0
+ rxrst
+ } -run
+ stream 3 {
+ txreq -hdr barrier ${b1_sock}
+ barrier b1 sync
+ txwinup -size 0
+ rxrst
+ } -run
+ stream 5 {
+ txreq -hdr barrier ${b1_sock}
+ barrier b1 sync
+ txwinup -size 0
+ rxrst
+ } -run
+ stream 7 {
+ txreq -hdr barrier ${b1_sock}
+ barrier b1 sync
+ txwinup -size 0
+ rxrst
+ } -run
+
+ barrier b2 sync
+ stream 0 -wait
+} -run
+
+varnish v1 -expect sc_rapid_reset == 1
More information about the varnish-commit
mailing list