Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Ingvar Hagelund
669db0da9b just a missing detail in the changelog 2026-07-30 11:23:59 +02:00
Ingvar Hagelund
c91639c430 forgot to update the abi string 2026-06-18 12:35:03 +02:00
Ingvar Hagelund
41cd913502 Update to latest 7.7.x release available, a security release
Includes fixes for VSV00017 aka CVE-2025-8671
Added patches for for VSV00018 aka CVE-2026-34475
Added patches for for VSV00019
2026-06-17 09:14:20 +02:00
9 changed files with 841 additions and 6 deletions

1
.gitignore vendored
View file

@ -69,3 +69,4 @@ varnish-2.1.3.tar.gz
/varnish-7.7.0.tgz
/varnish-7.7.1.tgz
/jemalloc-5.3.0.tar.bz2
/varnish-7.7.3.tgz

View file

@ -1,3 +1,3 @@
SHA512 (varnish-7.7.1.tgz) = 4a15ff23dc07cb19959031be5070e7da46a2be2d1a1d2e3950966ca593849d3f8be4f41bd35dae75876bbc121bf268345b47aa35764645362aa42b822b634ad9
SHA512 (varnish-7.7.3.tgz) = 2de3f19d24e42ec092076226b629dc36d4d3c9961454502e7f9a8ff1d440cf54104198e2b5302361f093fa221f04f836bb8dda441921d1721b1d05c90c0f1661
SHA512 (pkg-varnish-cache-7d90347.tar.gz) = c5bf026bb50b416001d0e22e56c2774c143dab1f4658f03f1a4e6578369b71cfda5854b7d6b580c43c2ab8e68bfb9033b56734adfd29ac0fddc61fd6b1b4b0c0
SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1

View file

@ -0,0 +1,60 @@
Based on upstream commit 1a9073102fb737a44a9cd46588f3c0e23590f8eb
commit 1a9073102fb737a44a9cd46588f3c0e23590f8eb
Author: Nils Goroll <nils.goroll@uplex.de>
Date: Thu Mar 5 14:28:02 2026 +0100
Handle absolute form with empty path
This patch now adds dissection of
http://example.com?/foo
into Host: example.com, url: /?/foo
Conflicts
both modified: bin/varnishd/http1/cache_http1_proto.c
both modified: bin/varnishtest/tests/r01255.vtc
diff -u a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
--- a/bin/varnishd/http1/cache_http1_proto.c 2026-06-16 22:03:12.617853250 +0200
+++ b/bin/varnishd/http1/cache_http1_proto.c 2026-06-16 22:05:04.321967181 +0200
@@ -355,6 +355,7 @@
uint16_t retval;
const char *p;
const char *b = NULL, *e;
+ char c = '\0';
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
@@ -374,9 +375,11 @@
http_scheme_at(hp->hd[HTTP_HDR_URL].b, https))
b = hp->hd[HTTP_HDR_URL].b + 8;
if (b) {
- e = strchr(b, '/');
+ e = strpbrk(b, "/?");
if (e == NULL)
e = hp->hd[HTTP_HDR_URL].e;
+ else
+ c = *e;
if (e == b) {
// rfc9110 4.2.1 4.2.2 reject empty host
return (400);
@@ -385,10 +388,15 @@
http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b);
hp->hd[HTTP_HDR_URL].b = e;
if (Tlen(hp->hd[HTTP_HDR_URL]) == 0) {
+ // empty path
if (http_method_eq(http_GetMethod(hp), OPTIONS))
hp->hd[HTTP_HDR_URL] = Tstr("*");
else
hp->hd[HTTP_HDR_URL] = Tstr("/");
+ } else if (c == '?') {
+ hp->hd[HTTP_HDR_URL].b--;
+ char *t = TRUST_ME(hp->hd[HTTP_HDR_URL].b);
+ *t = '/';
}
}

View file

@ -0,0 +1,42 @@
Based on upstream commit 5c016b070e1994fd8a430b45dac7dc3ee63f04d7
commit 5c016b070e1994fd8a430b45dac7dc3ee63f04d7
Author: Nils Goroll <nils.goroll@uplex.de>
Date: Wed Mar 4 09:46:28 2026 +0100
Fix http/1.1 "absolute form" empty host handling
RFC9110 4.2.1:
A sender MUST NOT generate an "http" URI with an empty host identifier.
A recipient that processes such a URI reference MUST reject it as
invalid.
4.2.2:
A sender MUST NOT generate an "https" URI with an empty host identifier.
A recipient that processes such a URI reference MUST reject it as
invalid.
Pointed out by Walid
Related to VSV18
Conflicts:
both modified: doc/changes.rst
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index c710c6da5..35ad9260c 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -377,6 +377,10 @@ HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
e = strchr(b, '/');
if (e == NULL)
e = hp->hd[HTTP_HDR_URL].e;
+ if (e == b) {
+ // rfc9110 4.2.1 4.2.2 reject empty host
+ return (400);
+ }
http_Unset(hp, H_Host);
http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b);
hp->hd[HTTP_HDR_URL].b = e;

View file

@ -0,0 +1,258 @@
Based on upstream commit 73dcb85eb8ad9fa9b462c5477d8c4b5061f615de
commit 73dcb85eb8ad9fa9b462c5477d8c4b5061f615de
Author: Nils Goroll <nils.goroll@uplex.de>
Date: Tue Feb 3 09:15:02 2026 +0100
Fix http/1.1 "absolute form" dissection edge case
RFC9110 4.2.3:
When not being used as the target of an OPTIONS request, an empty path
component is equivalent to an absolute path of "/", so the normal form
is to provide a path of "/" instead.
7.7:
For example, a proxy forwarding a request to an origin server via
HTTP/1.1 will replace an empty path with "/" (Section 3.2.1 of
[HTTP/1.1]) or "*" (Section 3.2.4 of [HTTP/1.1]), depending on the
request method.
(Pointed out by Dridi)
Fixes VSV18
Conflicts:
both modified: doc/changes.rst
Edits:
cache_http1_proto.c: WKM does not exist yet in 8.0
commit 5c016b070e1994fd8a430b45dac7dc3ee63f04d7
Author: Nils Goroll <nils.goroll@uplex.de>
Date: Wed Mar 4 09:46:28 2026 +0100
Fix http/1.1 "absolute form" empty host handling
RFC9110 4.2.1:
A sender MUST NOT generate an "http" URI with an empty host identifier.
A recipient that processes such a URI reference MUST reject it as
invalid.
4.2.2:
A sender MUST NOT generate an "https" URI with an empty host identifier.
A recipient that processes such a URI reference MUST reject it as
invalid.
Pointed out by Walid
Related to VSV18
Conflicts:
both modified: doc/changes.rst
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index 1441b1d91..c710c6da5 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -375,10 +375,16 @@ HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
b = hp->hd[HTTP_HDR_URL].b + 8;
if (b) {
e = strchr(b, '/');
- if (e) {
- http_Unset(hp, H_Host);
- http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b);
- hp->hd[HTTP_HDR_URL].b = e;
+ if (e == NULL)
+ e = hp->hd[HTTP_HDR_URL].e;
+ http_Unset(hp, H_Host);
+ http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b);
+ hp->hd[HTTP_HDR_URL].b = e;
+ if (Tlen(hp->hd[HTTP_HDR_URL]) == 0) {
+ if (http_method_eq(http_GetMethod(hp), OPTIONS))
+ hp->hd[HTTP_HDR_URL] = Tstr("*");
+ else
+ hp->hd[HTTP_HDR_URL] = Tstr("/");
}
}
diff -u a/bin/varnishtest/tests/r01255.vtc b/bin/varnishtest/tests/r01255.vtc
--- a/bin/varnishtest/tests/r01255.vtc 2025-07-28 13:50:43.000000000 +0200
+++ b/bin/varnishtest/tests/r01255.vtc 2026-06-16 11:00:29.689109716 +0200
@@ -1,19 +1,167 @@
-varnishtest "Test RFC2616 5.2 compliance"
+varnishtest "Test RFC9112 3.2 compliance"
-server s1 {
+server s1 -repeat 8 {
rxreq
txresp -hdr "Foo: 1"
} -start
-varnish v1 -vcl+backend {
+varnish v1 -arg "-p vsl_mask=+ReqTarget" -vcl+backend {
+ sub vcl_req_method {
+ if (req.method == "CONNECT") {
+ return (pass);
+ }
+ }
sub vcl_deliver {
set resp.http.rxhost = req.http.host;
+ set resp.http.url = req.url;
}
} -start
+logexpect l1001 -v v1 -g vxid -q "vxid == 1001" {
+ fail add * ReqURL
+ fail add * End
+ expect 3 * ReqTarget {^\Qhttp://www.example.com/bar\E$}
+ expect 0 = ReqUnset {^\Qhost: another\E$}
+ expect 0 = ReqHeader {^\QHost: www.example.com\E$}
+ fail clear
+} -start
+
+logexpect l1003 -v v1 -g vxid -q "vxid == 1003" {
+ fail add * ReqURL
+ fail add * End
+ expect 3 * ReqTarget {^\Qhttp://www.example.com/\E$}
+ expect 0 = ReqUnset {^\Qhost: another\E$}
+ expect 0 = ReqHeader {^\QHost: www.example.com\E$}
+ fail clear
+} -start
+
+logexpect l1005 -v v1 -g vxid -q "vxid == 1005" {
+ fail add * ReqURL
+ fail add * End
+ expect 3 * ReqTarget {^\Qhttp://www.example.com\E$}
+ expect 0 = ReqUnset {^\Qhost: another\E$}
+ expect 0 = ReqHeader {^\QHost: www.example.com\E$}
+ fail clear
+} -start
+
+logexpect l1006 -v v1 -g vxid -q "vxid == 1006" {
+ fail add * ReqURL
+ fail add * End
+ expect 3 * ReqTarget {^\Qhttp://www.example.com\E$}
+ expect 0 = ReqUnset {^\Qhost: another\E$}
+ expect 0 = ReqHeader {^\QHost: www.example.com\E$}
+ fail clear
+ fail add * End
+ expect 3 = ReqMethod {^OPTIONS$}
+ expect 0 = ReqURL {^\Q*\E$}
+ fail clear
+} -start
+
+logexpect l1008 -v v1 -g vxid -q "vxid == 1008" {
+ fail add * End
+ expect 3 * ReqTarget {^\Qexample.com:80\E$}
+ expect 2 = ReqMethod {^CONNECT$}
+ expect 0 = ReqURL {^\Qexample.com:80\E$}
+ fail clear
+} -start
+
+logexpect l1010 -v v1 -g vxid -q "vxid == 1010" {
+ fail add * End
+ expect 3 * ReqTarget {^\Q*\E$}
+ expect 2 = ReqMethod {^OPTIONS$}
+ expect 0 = ReqURL {^\Q*\E$}
+ fail clear
+} -start
+
client c1 {
- txreq -url http://www.example.com/bar
+ # 1001
+ txreq -url http://www.example.com/bar -hdr "host: another"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == 1
+ expect resp.http.rxhost == www.example.com
+ expect resp.http.url == /bar
+
+ # 1003
+ txreq -url http://www.example.com/ -hdr "host: another"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == 1
+ expect resp.http.rxhost == www.example.com
+ expect resp.http.url == /
+
+ # 1005
+ txreq -url http://www.example.com -hdr "host: another"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == 1
+ expect resp.http.rxhost == www.example.com
+ expect resp.http.url == /
+
+ # 1006
+ txreq -method OPTIONS -url http://www.example.com -hdr "host: another"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == 1
+ expect resp.http.rxhost == www.example.com
+ expect resp.http.url == *
+
+ # 1008
+ # we do not actually handle CONNECT here
+ txreq -req CONNECT -url example.com:80 -hdr "host: another"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == 1
+ expect resp.http.rxhost == "another"
+ expect resp.http.url == "example.com:80"
+
+ # 1010
+ txreq -req OPTIONS -url "*" -hdr "host: another"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == 1
+ expect resp.http.rxhost == "another"
+ expect resp.http.url == "*"
+
+ # https, otherwise like 1005
+ txreq -url https://www.example.com -hdr "host: another"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == 1
+ expect resp.http.rxhost == www.example.com
+ expect resp.http.url == /
+
+ #
+ txreq -url https://www.example.com?/foo -hdr "host: another"
rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == 1
expect resp.http.rxhost == www.example.com
+ expect resp.http.url == /?/foo
+
+ txreq -url http:///bar -hdr "host: another"
+ rxresp
+ expect resp.status == 400
+} -run
+
+client c2 {
+ txreq -url http:// -hdr "host: another"
+ rxresp
+ expect resp.status == 400
} -run
+
+client c3 {
+ txreq -method OPTIONS -url http:// -hdr "host: another"
+ rxresp
+ expect resp.status == 400
+} -run
+
+varnish v1 -expect MAIN.http1_absolute_form == 9
+
+logexpect l1001 -wait
+logexpect l1003 -wait
+logexpect l1005 -wait
+logexpect l1006 -wait
+logexpect l1008 -wait
+logexpect l1010 -wait

View file

@ -0,0 +1,55 @@
Based on upsteam commit e8eccd46514e4b4f7ee5d970ee08a4e5a59586b8
commit e8eccd46514e4b4f7ee5d970ee08a4e5a59586b8
Author: Nils Goroll <nils.goroll@uplex.de>
Date: Wed Mar 4 10:48:27 2026 +0100
Enable https_scheme feature by default
RFC9110 explicitly names https as "HTTP-related" and RFC9112 states that we MUST
convert the host, so not parsing https:// is considered a violation of the
standard, which, in turn, should be a deliberate decision.
Related to VSV18
Conflicts:
both modified: doc/changes.rst
diff --git a/include/tbl/params.h b/include/tbl/params.h
index c94f771d5..bdb34e085 100644
--- a/include/tbl/params.h
+++ b/include/tbl/params.h
@@ -1987,6 +1987,7 @@ PARAM_BITS(
/* fld */ feature_bits,
/* def */
"none,"
+ "+https_scheme,"
"+validate_headers,"
"+vcl_req_reset",
/* descr */
--- a/bin/varnishtest/tests/r01847.vtc 2026-06-16 17:15:34.491797476 +0200
+++ b/bin/varnishtest/tests/r01847.vtc 2026-06-16 17:20:29.853055662 +0200
@@ -23,14 +23,9 @@
rxresp
expect resp.http.rxhost == www.example.com
expect resp.http.rxurl == /bar
-
- txreq -url https://www.example.com/bar
- rxresp
- expect resp.http.rxhost == "${localhost}"
- expect resp.http.rxurl == https://www.example.com/bar
} -run
-varnish v1 -cliok "param.set feature +https_scheme"
+varnish v1 -cliok "param.set feature -https_scheme"
client c1 {
txreq -url http://www.example.com/bar
@@ -40,6 +35,5 @@
txreq -url https://www.example.com/bar
rxresp
- expect resp.http.rxhost == www.example.com
- expect resp.http.rxurl == /bar
+ expect resp.status == 400
} -run

View file

@ -0,0 +1,274 @@
Based on commit f89df57ab8e30ca5c8d04ba27870d473f17bedd4
commit f89df57ab8e30ca5c8d04ba27870d473f17bedd4
Author: Nils Goroll <nils.goroll@uplex.de>
Date: Tue Feb 3 10:33:14 2026 +0100
Add more defensive req.url checks to builtin.vcl
As a defensive measure, we add vcl_req_url, which requires req.url to start with
"/" except for
* the CONNECT method, where req.url contains hostname:port (for
http/1.1) and
* the OPTIONS method, where req.url can be "*"
Note that, by default, we do not accept CONNECT requests.
As with all built-in "hooks", vcl_req_url can be overridden selectively from the
custom vcl.
As a particular case, this, by default, prevents processing of https:// request
targets, unless the https_scheme feature flag is set.
Conflict:
both modified: doc/changes.rst
diff -u a/bin/varnishd/builtin.vcl b/bin/varnishd/builtin.vcl
--- a/bin/varnishd/builtin.vcl 2026-06-16 23:27:52.311584972 +0200
+++ b/bin/varnishd/builtin.vcl 2026-06-16 23:27:56.544046238 +0200
@@ -41,6 +41,7 @@
}
sub vcl_builtin_recv {
+ call vcl_req_url;
call vcl_req_host;
call vcl_req_method;
call vcl_req_authorization;
@@ -58,6 +59,16 @@
return (synth(400));
}
}
+
+sub vcl_req_url {
+ if (req.url == "*" && req.method == "OPTIONS") {
+ return;
+ }
+ # NB: we do not allow connect by default (see vcl_req_method)
+ if (req.url !~ "^/" && req.method != "CONNECT") {
+ return (synth(400));
+ }
+}
sub vcl_req_method {
if (req.method == "PRI") {
diff --git a/bin/varnishtest/tests/b00026.vtc b/bin/varnishtest/tests/b00026.vtc
index e12676985..1b0df4c04 100644
--- a/bin/varnishtest/tests/b00026.vtc
+++ b/bin/varnishtest/tests/b00026.vtc
@@ -2,13 +2,13 @@ varnishtest "Check the precedence for timeouts"
server s1 {
rxreq
- expect req.url == "from_backend"
+ expect req.url == "/from_backend"
delay 1
txresp
} -start
server s2 {
rxreq
- expect req.url == "from_vcl"
+ expect req.url == "/from_vcl"
delay 1.5
txresp
} -start
@@ -26,13 +26,13 @@ varnish v1 -vcl {
}
sub vcl_recv {
- if (req.url == "from_backend") {
+ if (req.url == "/from_backend") {
return(pass);
}
}
sub vcl_backend_fetch {
set bereq.first_byte_timeout = 2s;
- if (bereq.url == "from_backend") {
+ if (bereq.url == "/from_backend") {
set bereq.backend = b1;
} else {
set bereq.backend = b2;
@@ -42,10 +42,10 @@ varnish v1 -vcl {
varnish v1 -cliok "param.set first_byte_timeout 0.5"
client c1 {
- txreq -url "from_backend"
+ txreq -url "/from_backend"
rxresp
expect resp.status == 200
- txreq -url "from_vcl"
+ txreq -url "/from_vcl"
rxresp
expect resp.status == 200
} -run
diff --git a/bin/varnishtest/tests/c00005.vtc b/bin/varnishtest/tests/c00005.vtc
index 0a6e90517..74f6ed585 100644
--- a/bin/varnishtest/tests/c00005.vtc
+++ b/bin/varnishtest/tests/c00005.vtc
@@ -5,7 +5,7 @@ server s1 {
expect req.url == "/"
txresp -body "1111\n"
rxreq
- expect req.url == "foo"
+ expect req.url == "/foo"
txresp -body "2222\n"
} -start
@@ -40,7 +40,7 @@ varnish v1 -vcl+backend {
} -start
client c1 {
- txreq -url "foo"
+ txreq -url "/foo"
rxresp
expect resp.status == 200
expect resp.http.acl == acl1
diff --git a/bin/varnishtest/tests/e00009.vtc b/bin/varnishtest/tests/e00009.vtc
index e15e56ae7..b40e89c9d 100644
--- a/bin/varnishtest/tests/e00009.vtc
+++ b/bin/varnishtest/tests/e00009.vtc
@@ -40,7 +40,7 @@ varnish v1 -expect MAIN.s_resp_bodybytes == 57
varnish v1 -cli "param.set feature +esi_disable_xml_check"
client c1 {
- txreq -url bar
+ txreq -url /bar
rxresp
expect resp.status == 200
expect resp.bodylen == 22
diff --git a/bin/varnishtest/tests/e00019.vtc b/bin/varnishtest/tests/e00019.vtc
index 1fb159ec0..e73286aa1 100644
--- a/bin/varnishtest/tests/e00019.vtc
+++ b/bin/varnishtest/tests/e00019.vtc
@@ -34,19 +34,19 @@ server s1 {
# Varnish 4
server s2 {
rxreq
- expect req.url == "bar/foo"
+ expect req.url == "/foo"
txresp -body {<INCL>}
} -start
varnish v1 -vcl+backend {
sub vcl_backend_fetch {
- if (bereq.url != "bar") {
+ if (bereq.url != "/bar") {
set bereq.backend = s2;
}
}
sub vcl_backend_response {
- if (bereq.url == "bar") {
+ if (bereq.url == "/bar") {
set beresp.do_esi = true;
}
}
@@ -67,7 +67,7 @@ logexpect l1 -v v1 -g vxid -q "vxid == 1002" {
} -start
client c1 {
- txreq -url bar
+ txreq -url /bar
rxresp
expect resp.status == 200
expect resp.bodylen == 65856
diff --git a/bin/varnishtest/tests/r02339.vtc b/bin/varnishtest/tests/r02339.vtc
index 9ff18632d..e934bf45b 100644
--- a/bin/varnishtest/tests/r02339.vtc
+++ b/bin/varnishtest/tests/r02339.vtc
@@ -11,10 +11,10 @@ varnish v1 -vcl+backend {
import purge;
sub vcl_miss {
- if (req.url == "miss") { purge.hard(); }
+ if (req.url == "/miss") { purge.hard(); }
}
sub vcl_hit {
- if (req.url == "hit") { purge.hard(); }
+ if (req.url == "/hit") { purge.hard(); }
}
} -start
@@ -39,15 +39,15 @@ logexpect l1 -v v1 {
} -start
client c1 {
- txreq -url hit
+ txreq -url /hit
rxresp
expect resp.status == 200
- txreq -url hit
+ txreq -url /hit
rxresp
expect resp.status == 200
- txreq -url miss
+ txreq -url /miss
rxresp
expect resp.status == 200
} -run
@@ -59,7 +59,7 @@ varnish v1 -errvcl "Not available in subroutine 'vcl_purge'" {
import purge;
sub vcl_purge {
- if (req.url == "purge") { purge.hard(); }
+ if (req.url == "/purge") { purge.hard(); }
}
}
@@ -67,7 +67,7 @@ varnish v1 -errvcl "Not available in subroutine 'vcl_pass'" {
import purge;
sub vcl_pass {
- if (req.url == "pass") { purge.hard(); }
+ if (req.url == "/pass") { purge.hard(); }
}
}
@@ -75,7 +75,7 @@ varnish v1 -errvcl "Not available in subroutine 'vcl_deliver'" {
import purge;
sub vcl_deliver {
- if (req.url == "deliver") { purge.hard(); }
+ if (req.url == "/deliver") { purge.hard(); }
}
}
@@ -83,7 +83,7 @@ varnish v1 -errvcl "Not available in subroutine 'vcl_synth'" {
import purge;
sub vcl_synth {
- if (req.url == "synth") { purge.hard(); }
+ if (req.url == "/synth") { purge.hard(); }
}
}
@@ -91,7 +91,7 @@ varnish v1 -errvcl "Not available in subroutine 'vcl_backend_fetch'" {
import purge;
sub vcl_backend_fetch {
- if (bereq.url == "fetch") { purge.hard(); }
+ if (bereq.url == "/fetch") { purge.hard(); }
}
}
@@ -99,7 +99,7 @@ varnish v1 -errvcl "Not available in subroutine 'vcl_backend_error'" {
import purge;
sub vcl_backend_error {
- if (bereq.url == "error") { purge.hard(); }
+ if (bereq.url == "/error") { purge.hard(); }
}
}
@@ -107,6 +107,6 @@ varnish v1 -errvcl "Not available in subroutine 'vcl_backend_response'" {
import purge;
sub vcl_backend_response {
- if (bereq.url == "response") { purge.hard(); }
+ if (bereq.url == "/response") { purge.hard(); }
}
}

View file

@ -0,0 +1,120 @@
Based on upstream patches
db19a0c6c6260f18efe441698a55156b41a6dc7f
8acf0968c5e19b580b27bdec3367067250ba0c16
9985187ac2c21f9a0675a3d23dcc8ddf4c2bf36a
commit db19a0c6c6260f18efe441698a55156b41a6dc7f
Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Date: Thu Sep 18 17:25:02 2025 +0200
vdef: Retire Tstrcmp() macro
commit 8acf0968c5e19b580b27bdec3367067250ba0c16
Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Date: Thu Sep 18 17:23:17 2025 +0200
http2_hpack: Check pseudo-header names with Tstreq()
commit 9985187ac2c21f9a0675a3d23dcc8ddf4c2bf36a
Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Date: Wed Jan 22 15:05:08 2025 +0100
vdef: Test equality between txt and string
diff --git a/bin/varnishd/http2/cache_http2_hpack.c b/bin/varnishd/http2/cache_http2_hpack.c
index a90e6fde2..cb40b738f 100644
--- a/bin/varnishd/http2/cache_http2_hpack.c
+++ b/bin/varnishd/http2/cache_http2_hpack.c
@@ -171,7 +171,7 @@ h2h_addhdr(struct http *hp, struct h2h_decode *d)
/* Match H/2 pseudo headers */
/* XXX: Should probably have some include tbl for pseudo-headers */
- if (!Tstrcmp(nm, ":method")) {
+ if (Tstreq(nm, ":method")) {
hdr.b = val.b;
n = HTTP_HDR_METHOD;
disallow_empty = 1;
@@ -181,13 +181,13 @@ h2h_addhdr(struct http *hp, struct h2h_decode *d)
if (!vct_istchar(*p))
return (H2SE_PROTOCOL_ERROR);
}
- } else if (!Tstrcmp(nm, ":path")) {
+ } else if (Tstreq(nm, ":path")) {
hdr.b = val.b;
n = HTTP_HDR_URL;
disallow_empty = 1;
// rfc9113,l,2693,2705
- if (Tlen(val) > 0 && val.b[0] != '/' && Tstrcmp(val, "*")) {
+ if (Tlen(val) > 0 && val.b[0] != '/' && !Tstreq(val, "*")) {
VSLb(hp->vsl, SLT_BogoHeader,
"Illegal :path pseudo-header %.*s",
(int)Tlen(val), val.b);
@@ -199,7 +199,7 @@ h2h_addhdr(struct http *hp, struct h2h_decode *d)
if (vct_islws(*p) || vct_isctl(*p))
return (H2SE_PROTOCOL_ERROR);
}
- } else if (!Tstrcmp(nm, ":scheme")) {
+ } else if (Tstreq(nm, ":scheme")) {
/* XXX: What to do about this one? (typically
"http" or "https"). For now set it as a normal
header, stripping the first ':'. */
@@ -213,7 +213,7 @@ h2h_addhdr(struct http *hp, struct h2h_decode *d)
if (!vct_istchar(*p))
return (H2SE_PROTOCOL_ERROR);
}
- } else if (!Tstrcmp(nm, ":authority")) {
+ } else if (Tstreq(nm, ":authority")) {
/* NB: we inject "host" in place of "rity" for
* the ":authority" pseudo-header.
*/
diff --git a/bin/varnishtest/tests/f00019.vtc b/bin/varnishtest/tests/f00019.vtc
new file mode 100644
index 000000000..e85fb449c
--- /dev/null
+++ b/bin/varnishtest/tests/f00019.vtc
@@ -0,0 +1,31 @@
+vtest "Verify pseudo-header parsing"
+
+varnish v1 -cliok "param.set feature +http2"
+varnish v1 -vcl {
+ backend default none;
+ sub vcl_recv {
+ return (synth(200));
+ }
+} -start
+
+client c1 {
+ stream 1 {
+ txreq -noadd \
+ -hdr ":authority" "foo.com" \
+ -hdr ":path" "/foobar" \
+ -hdr ":scheme" "http" \
+ -hdr ":method" "GET"
+ rxresp
+ expect resp.status == 200
+ } -run
+
+ stream 3 {
+ txreq -noadd \
+ -hdr ":a" "foo.com" \
+ -hdr ":p" "/foobar" \
+ -hdr ":s" "http" \
+ -hdr ":m" "GET"
+ rxrst
+ expect rst.err == PROTOCOL_ERROR
+ } -run
+} -run
diff -u a/include/vdef.h b/include/vdef.h
--- a/include/vdef.h 2026-06-16 21:12:28.080660988 +0200
+++ b/include/vdef.h 2026-06-16 21:13:10.391582611 +0200
@@ -276,7 +276,7 @@
#define Tcheck(t) do { (void)pdiff((t).b, (t).e); } while (0)
#define Tlen(t) (pdiff((t).b, (t).e))
#define Tstr(s) (/*lint -e(446)*/ (txt){(s), (s) + strlen(s)})
-#define Tstrcmp(t, s) (strncmp((t).b, (s), Tlen(t)))
+#define Tstreq(t, s) (Tlen(t) == strlen(s) && !strncmp((t).b, (s), Tlen(t)))
#define Tforeach(c, t) for ((c) = (t).b; (c) < (t).e; (c)++)
/* #3020 dummy definitions until PR is merged*/

View file

@ -4,7 +4,7 @@
%global __provides_exclude_from ^%{_libdir}/varnish/vmods
%global abi 2e8180f788715e5bc44df08479d60c9435d79bdd
%global abi 6884b75af9c9bdb2c9b6e2aa464a435e42cb4931
%global vrt 21.0
# Package scripts are now external
@ -31,8 +31,8 @@
Summary: High-performance HTTP accelerator
Name: varnish
Version: 7.7.1
Release: 4%{?dist}
Version: 7.7.3
Release: 2%{?dist}
License: BSD-2-Clause AND (BSD-2-Clause-FreeBSD AND BSD-3-Clause AND LicenseRef-Fedora-Public-Domain AND Zlib)
URL: https://www.varnish-cache.org/
Source0: http://varnish-cache.org/_downloads/%{name}-%{version}.tgz
@ -44,6 +44,15 @@ Source3: https://github.com/jemalloc/jemalloc/releases/download/%{jemalloc_versi
# https://github.com/varnishcache/varnish-cache/issues/4298
Patch0: varnish-7.7.0_fix_4298.patch
# Upstream patches for VSV00018
Patch1: varnish-8.0_vsv18_f89df57a.patch
Patch2: varnish-8.0_vsv18_73dcb85e.patch
Patch3: varnish-8.0_vsv18_5c016b07.patch
Patch4: varnish-8.0_vsv18_e8eccd46.patch
Patch5: varnish-8.0_vsv18_1a907310.patch
# Upstream patches for VSV00019
Patch6: varnish-8.0_vsv19_db19a0c6-9985187a.patch
%if %{with bundled_jemalloc}
# bundled jemalloc patch
Patch100: jemalloc-5.3.0_fno-builtin.patch
@ -153,12 +162,22 @@ Documentation files for %name
%prep
%setup -q
%patch 0 -p1
%patch 1 -p1
%patch 2 -p1
%patch 3 -p1
%patch 4 -p1
%patch 5 -p1
%patch 6 -p1
tar xzf %SOURCE1
ln -s pkg-varnish-cache-%{commit1}/redhat redhat
ln -s pkg-varnish-cache-%{commit1}/debian debian
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
# Not yet implemented
rm bin/varnishtest/tests/r01255.vtc
# jemalloc
%if %{with bundled_jemalloc}
tar xjf %SOURCE3
@ -223,7 +242,7 @@ export CFLAGS="$CFLAGS -ffloat-store -fexcess-precision=standard"
%endif
%if 0%{?fedora} > 41 || 0%{?rhel} > 10
export CFLAGS="$CFLAGS -std=gnu17"
export CFLAGS="$CFLAGS -std=gnu17 -Wno-error=discarded-qualifiers"
%endif
%ifarch s390x
@ -407,7 +426,13 @@ test -f /etc/varnish/secret || (uuidgen > /etc/varnish/secret && chmod 0600 /etc
%changelog
* Fri Jun 31 2025 Luboš Uhliarik <luhliari@redhat.com> - 7.7.1-4
* Mon Jun 15 2026 Ingvar Hagelund <ingvar@redpill-linpro.com> - 7.7.3-2
- Update to latest 7.7.x release available, a security release
- Includes fixes for VSV00017 aka CVE-2025-8671
- Added patches for for VSV00018 aka CVE-2026-34475
- Added patches for for VSV00019 aka CVE-2026-50052
* Fri Jul 25 2025 Luboš Uhliarik <luhliari@redhat.com> - 7.7.1-4
- bundle jemalloc in RHEL
* Fri Jul 25 2025 Fedora Release Engineering <releng@fedoraproject.org> - 7.7.1-3