aboutsummaryrefslogtreecommitdiffstats
path: root/main/varnish/CVE-2017-12425.patch
blob: 0ff0d9f57ad2891b84b4c8f4be43d5aba55847c7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
From c37821ddd539a23845ae8e9a7a9cc958358c1541 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 27 Jul 2017 11:52:58 +0200
Subject: [PATCH] Correctly handle bogusly large chunk sizes

This fixes a denial of service attack vector where bogusly large chunk
sizes in requests could be used to force restarts of the Varnish
server.

This is Varnish Security Vulnerability VSV00001

For more information visit: https://varnish-cache.org/security/VSV00001

Fixes: #2379
---
 bin/varnishd/http1/cache_http1_vfp.c |  2 +-
 bin/varnishtest/tests/f00001.vtc     | 69 ++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 bin/varnishtest/tests/f00001.vtc

diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c
index b836cd3ca..ded1550bf 100644
--- a/bin/varnishd/http1/cache_http1_vfp.c
+++ b/bin/varnishd/http1/cache_http1_vfp.c
@@ -155,7 +155,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr,
 		if (q == NULL || *q != '\0')
 			return (VFP_Error(vc, "chunked header number syntax"));
 		cl = (ssize_t)cll;
-		if((uintmax_t)cl != cll)
+		if (cl < 0 || (uintmax_t)cl != cll)
 			return (VFP_Error(vc, "bogusly large chunk size"));
 
 		vfe->priv2 = cl;
diff --git a/bin/varnishtest/tests/f00001.vtc b/bin/varnishtest/tests/f00001.vtc
new file mode 100644
index 000000000..bfb559228
--- /dev/null
+++ b/bin/varnishtest/tests/f00001.vtc
@@ -0,0 +1,69 @@
+varnishtest "Check that we handle bogusly large chunks correctly"
+
+# Check that the bug has been fixed
+
+server s1 {
+	rxreq
+	txresp
+
+	accept
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+} -start
+
+client c1 {
+	send "POST / HTTP/1.1\r\n"
+	send "Transfer-Encoding: chunked\r\n\r\n"
+	send "FFFFFFFFFFFFFFED\r\n"
+	send "0\r\n\r\n"
+
+	rxresp
+	expect resp.status == 503
+} -run
+
+# Check that the published workaround does not cause harm
+
+varnish v1 -cliok "param.set vcc_allow_inline_c true"
+
+varnish v1 -vcl+backend {
+	sub exploit_workaround {
+		# This needs to be defined before your vcl_recv function
+		# Make sure that the runtime parameter vcc_allow_inline_c is set to true
+		if (req.http.transfer-encoding ~ "(?i)chunked") {
+			C{
+			struct dummy_req {
+				unsigned	magic;
+				int		step;
+				int		req_body_status;
+			};
+			((struct dummy_req *)ctx->req)->req_body_status = 5;
+			}C
+
+			return (synth(503, "Bad request"));
+		}
+	}
+
+	sub vcl_recv {
+		# Call this early in your vcl_recv function
+		call exploit_workaround;
+	}
+}
+
+client c1 {
+	send "POST / HTTP/1.1\r\n"
+	send "Transfer-Encoding: chunked\r\n\r\n"
+	send "FFFFFFFFFFFFFFED\r\n"
+
+	expect_close
+} -run
+
+# Make sure that varnish is still running
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+} -run