Browse Source

haproxy: add patches from upstream

 - [PATCH 1/2] BUG/MEDIUM: stats: properly initialize the scope before
 - [PATCH 2/2] BUG/MEDIUM: http: don't forward client shutdown without
 - [PATCH 3/8] BUG/MINOR: check: fix tcpcheck error message
 - [PATCH 4/8] CLEANUP: checks: fix double usage of cur / current_step
 - [PATCH 5/8] BUG/MEDIUM: checks: do not dereference head of a
 - [PATCH 6/8] CLEANUP: checks: simplify the loop processing of
 - [PATCH 7/8] BUG/MAJOR: checks: always check for end of list before
 - [PATCH 8/8] BUG/MEDIUM: checks: do not dereference a list as a
 - [PATCH 09/10] BUG/MEDIUM: peers: apply a random reconnection timeout
 - [PATCH 10/10] DOC: Update doc about weight, act and bck fields in the
 - [PATCH 11/14] MINOR: ssl: add a destructor to free allocated SSL
 - [PATCH 12/14] BUG/MEDIUM: ssl: fix tune.ssl.default-dh-param value
 - [PATCH 13/14] BUG/MINOR: cfgparse: fix typo in 'option httplog' error
 - [PATCH 14/14] BUG/MEDIUM: cfgparse: segfault when userlist is misused

Signed-off-by: heil <heil@terminal-consulting.de>
heil 9 years ago
parent
commit
d5c18252d4

+ 1
- 1
net/haproxy/Makefile View File

@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
10 10
 
11 11
 PKG_NAME:=haproxy
12 12
 PKG_VERSION:=1.5.12
13
-PKG_RELEASE:=01
13
+PKG_RELEASE:=14
14 14
 PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
15 15
 PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.5/src/
16 16
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)

+ 32
- 0
net/haproxy/patches/0001-BUG-MEDIUM-stats-properly-initialize-the-scope-befor.patch View File

@@ -0,0 +1,32 @@
1
+From 0aa5899911bbc765ba16ce52a80fa76230781779 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Mon, 4 May 2015 18:07:56 +0200
4
+Subject: [PATCH 1/2] BUG/MEDIUM: stats: properly initialize the scope before
5
+ dumping stats
6
+
7
+Issuing a "show sess all" prior to a "show stat" on the CLI results in no
8
+proxy being dumped because the scope_len union member was not properly
9
+reinitialized.
10
+
11
+This fix must be backported into 1.5.
12
+(cherry picked from commit 6bcb95da5b9cb143088102b460c7bcb37c1b3d81)
13
+---
14
+ src/dumpstats.c | 2 ++
15
+ 1 file changed, 2 insertions(+)
16
+
17
+diff --git a/src/dumpstats.c b/src/dumpstats.c
18
+index b616478..ca084ac 100644
19
+--- a/src/dumpstats.c
20
++++ b/src/dumpstats.c
21
+@@ -1109,6 +1109,8 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
22
+ 		arg++;
23
+ 	}
24
+ 
25
++	appctx->ctx.stats.scope_str = 0;
26
++	appctx->ctx.stats.scope_len = 0;
27
+ 	appctx->ctx.stats.flags = 0;
28
+ 	if (strcmp(args[0], "show") == 0) {
29
+ 		if (strcmp(args[1], "stat") == 0) {
30
+-- 
31
+2.0.5
32
+

+ 82
- 0
net/haproxy/patches/0002-BUG-MEDIUM-http-don-t-forward-client-shutdown-withou.patch View File

@@ -0,0 +1,82 @@
1
+From 294e4676a3b775a7accb50eb8428f293c218b5e2 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Mon, 11 May 2015 18:30:33 +0200
4
+Subject: [PATCH 2/2] BUG/MEDIUM: http: don't forward client shutdown without
5
+ NOLINGER except for tunnels
6
+
7
+There's an issue related with shutting down POST transfers or closing the
8
+connection after the end of the upload : the shutdown is forwarded to the
9
+server regardless of the abortonclose option. The problem it causes is that
10
+during a scan, brute force or whatever, it becomes possible that all source
11
+ports are exhausted with all sockets in TIME_WAIT state.
12
+
13
+There are multiple issues at once in fact :
14
+  - no action is done for the close, it automatically happens at the lower
15
+    layers thanks for channel_auto_close(), so we cannot act on NOLINGER ;
16
+
17
+  - we *do* want to continue to send a clean shutdown in tunnel mode because
18
+    some protocols transported over HTTP may need this, regardless of option
19
+    abortonclose, thus we can't set the option inconditionally
20
+
21
+  - for all other modes, we do want to close the dirty way because we're
22
+    certain whether we've sent everything or not, and we don't want to eat
23
+    all source ports.
24
+
25
+The solution is a bit complex and applies to DONE/TUNNEL states :
26
+
27
+  1) disable automatic close for everything not a tunnel and not just
28
+     keep-alive / server-close. Force-close is now covered, as is HTTP/1.0
29
+     which implicitly works in force-close mode ;
30
+
31
+  2) when processing option abortonclose, we know we can disable lingering
32
+     if the client has closed and the connection is not in tunnel mode.
33
+
34
+Since the last case above leads to a situation where the client side reports
35
+an error, we know the connection will not be reused, so leaving the flag on
36
+the stream-interface is safe. A client closing in the middle of the data
37
+transmission already aborts the transaction so this case is not a problem.
38
+
39
+This fix must be backported to 1.5 where the problem was detected.
40
+(cherry picked from commit bbfb6c40854925367ae5f9e8b22c5c9a18dc69d5)
41
+---
42
+ src/proto_http.c | 14 ++++++++++----
43
+ 1 file changed, 10 insertions(+), 4 deletions(-)
44
+
45
+diff --git a/src/proto_http.c b/src/proto_http.c
46
+index 0ac3a47..5db64b5 100644
47
+--- a/src/proto_http.c
48
++++ b/src/proto_http.c
49
+@@ -5452,9 +5452,10 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
50
+ 				msg->sov -= msg->next;
51
+ 			msg->next = 0;
52
+ 
53
+-			/* for keep-alive we don't want to forward closes on DONE */
54
+-			if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
55
+-			    (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL)
56
++			/* we don't want to forward closes on DONE except in
57
++			 * tunnel mode.
58
++			 */
59
++			if ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN)
60
+ 				channel_dont_close(req);
61
+ 			if (http_resync_states(s)) {
62
+ 				/* some state changes occurred, maybe the analyser
63
+@@ -5478,10 +5479,15 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
64
+ 			 * want to monitor the client's connection and forward
65
+ 			 * any shutdown notification to the server, which will
66
+ 			 * decide whether to close or to go on processing the
67
+-			 * request.
68
++			 * request. We only do that in tunnel mode, and not in
69
++			 * other modes since it can be abused to exhaust source
70
++			 * ports.
71
+ 			 */
72
+ 			if (s->be->options & PR_O_ABRT_CLOSE) {
73
+ 				channel_auto_read(req);
74
++				if ((req->flags & (CF_SHUTR|CF_READ_NULL)) &&
75
++				    ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN))
76
++					s->si[1].flags |= SI_FL_NOLINGER;
77
+ 				channel_auto_close(req);
78
+ 			}
79
+ 			else if (s->txn.meth == HTTP_METH_POST) {
80
+-- 
81
+2.0.5
82
+

+ 28
- 0
net/haproxy/patches/0003-BUG-MINOR-check-fix-tcpcheck-error-message.patch View File

@@ -0,0 +1,28 @@
1
+From 68e4fc2b9910dd090c5e729203b72444f75aaa75 Mon Sep 17 00:00:00 2001
2
+From: Baptiste Assmann <bedis9@gmail.com>
3
+Date: Fri, 1 May 2015 08:09:29 +0200
4
+Subject: [PATCH 3/8] BUG/MINOR: check: fix tcpcheck error message
5
+
6
+add the keyword 'string' when required (error in a tcpcheck expect
7
+string)
8
+(cherry picked from commit 96a5c9b57738c05ecce7822093b9c4118123dc1e)
9
+---
10
+ src/checks.c | 2 +-
11
+ 1 file changed, 1 insertion(+), 1 deletion(-)
12
+
13
+diff --git a/src/checks.c b/src/checks.c
14
+index 71debb6..8b53f97 100644
15
+--- a/src/checks.c
16
++++ b/src/checks.c
17
+@@ -614,7 +614,7 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi
18
+ 			}
19
+ 			else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_EXPECT) {
20
+ 				if (check->last_started_step->string)
21
+-					chunk_appendf(chk, " (string '%s')", check->last_started_step->string);
22
++					chunk_appendf(chk, " (expect string '%s')", check->last_started_step->string);
23
+ 				else if (check->last_started_step->expect_regex)
24
+ 					chunk_appendf(chk, " (expect regex)");
25
+ 			}
26
+-- 
27
+2.0.5
28
+

+ 178
- 0
net/haproxy/patches/0004-CLEANUP-checks-fix-double-usage-of-cur-current_step-.patch View File

@@ -0,0 +1,178 @@
1
+From 4f889006269e4d3f802de46f280ed198a15e3a69 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Wed, 13 May 2015 11:23:01 +0200
4
+Subject: [PATCH 4/8] CLEANUP: checks: fix double usage of cur / current_step
5
+ in tcp-checks
6
+
7
+This cleanup is a preliminary requirement to the upcoming fixes for
8
+the bug that affect tcp-check's improper use of lists. It will have
9
+to be backported to 1.5 though it will not easily apply.
10
+
11
+There are two variables pointing to the current rule within the loop,
12
+and either one or the other is used depending on the code blocks,
13
+making it much harder to apply checks to fix the list walking bug.
14
+So first get rid of "cur" and only focus on current_step.
15
+(cherry picked from commit ce8c42a37a44a1e0cb94e81abb7cc2baf3d0ef80)
16
+
17
+[wt: 1.5 doesn't have comments so this patch differs significantly
18
+ from 1.6, but it's needed for the next batch of fixes]
19
+---
20
+ src/checks.c | 57 ++++++++++++++++++++++++++++-----------------------------
21
+ 1 file changed, 28 insertions(+), 29 deletions(-)
22
+
23
+diff --git a/src/checks.c b/src/checks.c
24
+index 8b53f97..cfdfe8c 100644
25
+--- a/src/checks.c
26
++++ b/src/checks.c
27
+@@ -1859,7 +1859,7 @@ static int tcpcheck_get_step_id(struct server *s)
28
+ static void tcpcheck_main(struct connection *conn)
29
+ {
30
+ 	char *contentptr;
31
+-	struct tcpcheck_rule *cur, *next;
32
++	struct tcpcheck_rule *next;
33
+ 	int done = 0, ret = 0;
34
+ 	struct check *check = conn->owner;
35
+ 	struct server *s = check->server;
36
+@@ -1916,15 +1916,11 @@ static void tcpcheck_main(struct connection *conn)
37
+ 		check->bo->o = 0;
38
+ 		check->bi->p = check->bi->data;
39
+ 		check->bi->i = 0;
40
+-		cur = check->current_step = LIST_ELEM(head->n, struct tcpcheck_rule *, list);
41
++		check->current_step = LIST_ELEM(head->n, struct tcpcheck_rule *, list);
42
+ 		t->expire = tick_add(now_ms, MS_TO_TICKS(check->inter));
43
+ 		if (s->proxy->timeout.check)
44
+ 			t->expire = tick_add_ifset(now_ms, s->proxy->timeout.check);
45
+ 	}
46
+-	/* keep on processing step */
47
+-	else {
48
+-		cur = check->current_step;
49
+-	}
50
+ 
51
+ 	/* It's only the rules which will enable send/recv */
52
+ 	__conn_data_stop_both(conn);
53
+@@ -1934,7 +1930,7 @@ static void tcpcheck_main(struct connection *conn)
54
+ 		 * or if we're about to send a string that does not fit in the remaining space.
55
+ 		 */
56
+ 		if (check->bo->o &&
57
+-		    (&cur->list == head ||
58
++		    (&check->current_step->list == head ||
59
+ 		     check->current_step->action != TCPCHK_ACT_SEND ||
60
+ 		     check->current_step->string_len >= buffer_total_space(check->bo))) {
61
+ 
62
+@@ -1949,14 +1945,17 @@ static void tcpcheck_main(struct connection *conn)
63
+ 		}
64
+ 
65
+ 		/* did we reach the end ? If so, let's check that everything was sent */
66
+-		if (&cur->list == head) {
67
++		if (&check->current_step->list == head) {
68
+ 			if (check->bo->o)
69
+ 				goto out_need_io;
70
+ 			break;
71
+ 		}
72
+ 
73
+-		/* have 'next' point to the next rule or NULL if we're on the last one */
74
+-		next = (struct tcpcheck_rule *)cur->list.n;
75
++		/* have 'next' point to the next rule or NULL if we're on the
76
++		 * last one, connect() needs this.
77
++		 */
78
++		next = (struct tcpcheck_rule *)check->current_step->list.n;
79
++
80
+ 		if (&next->list == head)
81
+ 			next = NULL;
82
+ 
83
+@@ -2058,8 +2057,7 @@ static void tcpcheck_main(struct connection *conn)
84
+ 			}
85
+ 
86
+ 			/* allow next rule */
87
+-			cur = (struct tcpcheck_rule *)cur->list.n;
88
+-			check->current_step = cur;
89
++			check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
90
+ 
91
+ 			/* don't do anything until the connection is established */
92
+ 			if (!(conn->flags & CO_FL_CONNECTED)) {
93
+@@ -2113,8 +2111,7 @@ static void tcpcheck_main(struct connection *conn)
94
+ 			*check->bo->p = '\0'; /* to make gdb output easier to read */
95
+ 
96
+ 			/* go to next rule and try to send */
97
+-			cur = (struct tcpcheck_rule *)cur->list.n;
98
+-			check->current_step = cur;
99
++			check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
100
+ 		} /* end 'send' */
101
+ 		else if (check->current_step->action == TCPCHK_ACT_EXPECT) {
102
+ 			if (unlikely(check->result == CHK_RES_FAILED))
103
+@@ -2167,14 +2164,14 @@ static void tcpcheck_main(struct connection *conn)
104
+ 				goto out_end_tcpcheck;
105
+ 			}
106
+ 
107
+-			if (!done && (cur->string != NULL) && (check->bi->i < cur->string_len) )
108
++			if (!done && (check->current_step->string != NULL) && (check->bi->i < check->current_step->string_len) )
109
+ 				continue; /* try to read more */
110
+ 
111
+ 		tcpcheck_expect:
112
+-			if (cur->string != NULL)
113
+-				ret = my_memmem(contentptr, check->bi->i, cur->string, cur->string_len) != NULL;
114
+-			else if (cur->expect_regex != NULL)
115
+-				ret = regex_exec(cur->expect_regex, contentptr);
116
++			if (check->current_step->string != NULL)
117
++				ret = my_memmem(contentptr, check->bi->i, check->current_step->string, check->current_step->string_len) != NULL;
118
++			else if (check->current_step->expect_regex != NULL)
119
++				ret = regex_exec(check->current_step->expect_regex, contentptr);
120
+ 
121
+ 			if (!ret && !done)
122
+ 				continue; /* try to read more */
123
+@@ -2182,11 +2179,11 @@ static void tcpcheck_main(struct connection *conn)
124
+ 			/* matched */
125
+ 			if (ret) {
126
+ 				/* matched but we did not want to => ERROR */
127
+-				if (cur->inverse) {
128
++				if (check->current_step->inverse) {
129
+ 					/* we were looking for a string */
130
+-					if (cur->string != NULL) {
131
++					if (check->current_step->string != NULL) {
132
+ 						chunk_printf(&trash, "TCPCHK matched unwanted content '%s' at step %d",
133
+-								cur->string, tcpcheck_get_step_id(s));
134
++						             check->current_step->string, tcpcheck_get_step_id(s));
135
+ 					}
136
+ 					else {
137
+ 					/* we were looking for a regex */
138
+@@ -2198,8 +2195,9 @@ static void tcpcheck_main(struct connection *conn)
139
+ 				}
140
+ 				/* matched and was supposed to => OK, next step */
141
+ 				else {
142
+-					cur = (struct tcpcheck_rule*)cur->list.n;
143
+-					check->current_step = cur;
144
++					/* allow next rule */
145
++					check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
146
++
147
+ 					if (check->current_step->action == TCPCHK_ACT_EXPECT)
148
+ 						goto tcpcheck_expect;
149
+ 					__conn_data_stop_recv(conn);
150
+@@ -2208,9 +2206,10 @@ static void tcpcheck_main(struct connection *conn)
151
+ 			else {
152
+ 			/* not matched */
153
+ 				/* not matched and was not supposed to => OK, next step */
154
+-				if (cur->inverse) {
155
+-					cur = (struct tcpcheck_rule*)cur->list.n;
156
+-					check->current_step = cur;
157
++				if (check->current_step->inverse) {
158
++					/* allow next rule */
159
++					check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
160
++
161
+ 					if (check->current_step->action == TCPCHK_ACT_EXPECT)
162
+ 						goto tcpcheck_expect;
163
+ 					__conn_data_stop_recv(conn);
164
+@@ -2218,9 +2217,9 @@ static void tcpcheck_main(struct connection *conn)
165
+ 				/* not matched but was supposed to => ERROR */
166
+ 				else {
167
+ 					/* we were looking for a string */
168
+-					if (cur->string != NULL) {
169
++					if (check->current_step->string != NULL) {
170
+ 						chunk_printf(&trash, "TCPCHK did not match content '%s' at step %d",
171
+-								cur->string, tcpcheck_get_step_id(s));
172
++						             check->current_step->string, tcpcheck_get_step_id(s));
173
+ 					}
174
+ 					else {
175
+ 					/* we were looking for a regex */
176
+-- 
177
+2.0.5
178
+

+ 53
- 0
net/haproxy/patches/0005-BUG-MEDIUM-checks-do-not-dereference-head-of-a-tcp-c.patch View File

@@ -0,0 +1,53 @@
1
+From b94a6d5a37499ce6649ad58f4a8c4664779abd8b Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Wed, 13 May 2015 11:38:17 +0200
4
+Subject: [PATCH 5/8] BUG/MEDIUM: checks: do not dereference head of a
5
+ tcp-check at the end
6
+
7
+When the end of the list is reached, the current step's action is checked
8
+to know if we must poll or not. Unfortunately, the main reason for going
9
+there is that we walked past the end of list and current_step points to
10
+the head. We cannot dereference ->action since it does not belong to this
11
+structure and can definitely crash if the address is not mapped.
12
+
13
+This bug is unlikely to cause a crash since the action appears just after
14
+the list, and corresponds to the "char *check_req" pointer in the proxy
15
+struct, and it seems that we can't go there with current_step being null.
16
+At worst it can cause the check to register for recv events.
17
+
18
+This fix needs to be backported to 1.5 since the code is incorrect there
19
+as well.
20
+(cherry picked from commit 53c5a049e1f4dbf67412472e23690dc6b3c8d0f8)
21
+---
22
+ src/checks.c | 5 +++--
23
+ 1 file changed, 3 insertions(+), 2 deletions(-)
24
+
25
+diff --git a/src/checks.c b/src/checks.c
26
+index cfdfe8c..a887be1 100644
27
+--- a/src/checks.c
28
++++ b/src/checks.c
29
+@@ -2237,10 +2237,12 @@ static void tcpcheck_main(struct connection *conn)
30
+ 	goto out_end_tcpcheck;
31
+ 
32
+  out_need_io:
33
++	/* warning, current_step may now point to the head */
34
+ 	if (check->bo->o)
35
+ 		__conn_data_want_send(conn);
36
+ 
37
+-	if (check->current_step->action == TCPCHK_ACT_EXPECT)
38
++	if (&check->current_step->list != head &&
39
++	    check->current_step->action == TCPCHK_ACT_EXPECT)
40
+ 		__conn_data_want_recv(conn);
41
+ 	return;
42
+ 
43
+@@ -2256,7 +2258,6 @@ static void tcpcheck_main(struct connection *conn)
44
+ 		conn->flags |= CO_FL_ERROR;
45
+ 
46
+ 	__conn_data_stop_both(conn);
47
+-
48
+ 	return;
49
+ }
50
+ 
51
+-- 
52
+2.0.5
53
+

+ 82
- 0
net/haproxy/patches/0006-CLEANUP-checks-simplify-the-loop-processing-of-tcp-c.patch View File

@@ -0,0 +1,82 @@
1
+From ebb2bceb34d7787453548627ed0e99c60354672b Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Wed, 13 May 2015 11:59:14 +0200
4
+Subject: [PATCH 6/8] CLEANUP: checks: simplify the loop processing of
5
+ tcp-checks
6
+
7
+There is some unobvious redundancy between the various ways we can leave
8
+the loop. Some of them can be factored out. So now we leave the loop when
9
+we can't go further, whether it's caused by reaching the end of the rules
10
+or by a blocking I/O.
11
+(cherry picked from commit 263013d031d754c9f96de0d0cb5afcc011af6441)
12
+[wt: this patch is required for the next fix]
13
+---
14
+ src/checks.c | 26 ++++++++++++++------------
15
+ 1 file changed, 14 insertions(+), 12 deletions(-)
16
+
17
+diff --git a/src/checks.c b/src/checks.c
18
+index a887be1..a0c42f2 100644
19
+--- a/src/checks.c
20
++++ b/src/checks.c
21
+@@ -1926,8 +1926,10 @@ static void tcpcheck_main(struct connection *conn)
22
+ 	__conn_data_stop_both(conn);
23
+ 
24
+ 	while (1) {
25
+-		/* we have to try to flush the output buffer before reading, at the end,
26
+-		 * or if we're about to send a string that does not fit in the remaining space.
27
++		/* We have to try to flush the output buffer before reading, at
28
++		 * the end, or if we're about to send a string that does not fit
29
++		 * in the remaining space. That explains why we break out of the
30
++		 * loop after this control.
31
+ 		 */
32
+ 		if (check->bo->o &&
33
+ 		    (&check->current_step->list == head ||
34
+@@ -1940,16 +1942,12 @@ static void tcpcheck_main(struct connection *conn)
35
+ 					__conn_data_stop_both(conn);
36
+ 					goto out_end_tcpcheck;
37
+ 				}
38
+-				goto out_need_io;
39
++				break;
40
+ 			}
41
+ 		}
42
+ 
43
+-		/* did we reach the end ? If so, let's check that everything was sent */
44
+-		if (&check->current_step->list == head) {
45
+-			if (check->bo->o)
46
+-				goto out_need_io;
47
++		if (&check->current_step->list == head)
48
+ 			break;
49
+-		}
50
+ 
51
+ 		/* have 'next' point to the next rule or NULL if we're on the
52
+ 		 * last one, connect() needs this.
53
+@@ -2131,7 +2129,7 @@ static void tcpcheck_main(struct connection *conn)
54
+ 					}
55
+ 				}
56
+ 				else
57
+-					goto out_need_io;
58
++					break;
59
+ 			}
60
+ 
61
+ 			/* mark the step as started */
62
+@@ -2233,10 +2231,14 @@ static void tcpcheck_main(struct connection *conn)
63
+ 		} /* end expect */
64
+ 	} /* end loop over double chained step list */
65
+ 
66
+-	set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)");
67
+-	goto out_end_tcpcheck;
68
++	/* We're waiting for some I/O to complete, we've reached the end of the
69
++	 * rules, or both. Do what we have to do, otherwise we're done.
70
++	 */
71
++	if (&check->current_step->list == head && !check->bo->o) {
72
++		set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)");
73
++		goto out_end_tcpcheck;
74
++	}
75
+ 
76
+- out_need_io:
77
+ 	/* warning, current_step may now point to the head */
78
+ 	if (check->bo->o)
79
+ 		__conn_data_want_send(conn);
80
+-- 
81
+2.0.5
82
+

+ 90
- 0
net/haproxy/patches/0007-BUG-MAJOR-checks-always-check-for-end-of-list-before.patch View File

@@ -0,0 +1,90 @@
1
+From 97fccc87f1297d189ee80735e5b8746c34956eda Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Wed, 13 May 2015 12:08:21 +0200
4
+Subject: [PATCH 7/8] BUG/MAJOR: checks: always check for end of list before
5
+ proceeding
6
+
7
+This is the most important fix of this series. There's a risk of endless
8
+loop and crashes caused by the fact that we go past the head of the list
9
+when skipping to next rule, without checking if it's still a valid element.
10
+Most of the time, the ->action field is checked, which points to the proxy's
11
+check_req pointer (generally NULL), meaning the element is confused with a
12
+TCPCHK_ACT_SEND action.
13
+
14
+The situation was accidently made worse with the addition of tcp-check
15
+comment since it also skips list elements. However, since the action that
16
+makes it go forward is TCPCHK_ACT_COMMENT (3), there's little chance to
17
+see this as a valid pointer, except on 64-bit machines where it can match
18
+the end of a check_req string pointer.
19
+
20
+This fix heavily depends on previous cleanup and both must be backported
21
+to 1.5 where the bug is present.
22
+(cherry picked from commit f2c87353a7f8160930b5f342bb6d6ad0991ee3d1)
23
+[wt: this patch differs significantly from 1.6 since we don't have comments]
24
+---
25
+ src/cfgparse.c |  4 +++-
26
+ src/checks.c   | 12 ++++++++++++
27
+ 2 files changed, 15 insertions(+), 1 deletion(-)
28
+
29
+diff --git a/src/cfgparse.c b/src/cfgparse.c
30
+index 746c7eb..dba59d1 100644
31
+--- a/src/cfgparse.c
32
++++ b/src/cfgparse.c
33
+@@ -4368,7 +4368,9 @@ stats_error_parsing:
34
+ 			l = (struct list *)&curproxy->tcpcheck_rules;
35
+ 			if (l->p != l->n) {
36
+ 				tcpcheck = (struct tcpcheck_rule *)l->n;
37
+-				if (tcpcheck && tcpcheck->action != TCPCHK_ACT_CONNECT) {
38
++
39
++				if (&tcpcheck->list != &curproxy->tcpcheck_rules
40
++				    && tcpcheck->action != TCPCHK_ACT_CONNECT) {
41
+ 					Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
42
+ 					      file, linenum);
43
+ 					err_code |= ERR_ALERT | ERR_FATAL;
44
+diff --git a/src/checks.c b/src/checks.c
45
+index a0c42f2..e13d561 100644
46
+--- a/src/checks.c
47
++++ b/src/checks.c
48
+@@ -2057,6 +2057,9 @@ static void tcpcheck_main(struct connection *conn)
49
+ 			/* allow next rule */
50
+ 			check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
51
+ 
52
++			if (&check->current_step->list == head)
53
++				break;
54
++
55
+ 			/* don't do anything until the connection is established */
56
+ 			if (!(conn->flags & CO_FL_CONNECTED)) {
57
+ 				/* update expire time, should be done by process_chk */
58
+@@ -2110,6 +2113,9 @@ static void tcpcheck_main(struct connection *conn)
59
+ 
60
+ 			/* go to next rule and try to send */
61
+ 			check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
62
++
63
++			if (&check->current_step->list == head)
64
++				break;
65
+ 		} /* end 'send' */
66
+ 		else if (check->current_step->action == TCPCHK_ACT_EXPECT) {
67
+ 			if (unlikely(check->result == CHK_RES_FAILED))
68
+@@ -2196,6 +2202,9 @@ static void tcpcheck_main(struct connection *conn)
69
+ 					/* allow next rule */
70
+ 					check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
71
+ 
72
++					if (&check->current_step->list == head)
73
++						break;
74
++
75
+ 					if (check->current_step->action == TCPCHK_ACT_EXPECT)
76
+ 						goto tcpcheck_expect;
77
+ 					__conn_data_stop_recv(conn);
78
+@@ -2208,6 +2217,9 @@ static void tcpcheck_main(struct connection *conn)
79
+ 					/* allow next rule */
80
+ 					check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
81
+ 
82
++					if (&check->current_step->list == head)
83
++						break;
84
++
85
+ 					if (check->current_step->action == TCPCHK_ACT_EXPECT)
86
+ 						goto tcpcheck_expect;
87
+ 					__conn_data_stop_recv(conn);
88
+-- 
89
+2.0.5
90
+

+ 116
- 0
net/haproxy/patches/0008-BUG-MEDIUM-checks-do-not-dereference-a-list-as-a-tcp.patch View File

@@ -0,0 +1,116 @@
1
+From 5bff05986c501d9ffb67873b60472f9c2a2e41be Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Wed, 13 May 2015 12:24:53 +0200
4
+Subject: [PATCH 8/8] BUG/MEDIUM: checks: do not dereference a list as a
5
+ tcpcheck struct
6
+
7
+The method used to skip to next rule in the list is wrong, it assumes
8
+that the list element starts at the same offset as the rule. It happens
9
+to be true on most architectures since the list is the first element for
10
+now but it's definitely wrong. Now the code doesn't crash anymore when
11
+the struct list is moved anywhere else in the struct tcpcheck_rule.
12
+
13
+This fix must be backported to 1.5.
14
+(cherry picked from commit 5581c27b579cbfc53afb0ca04cdeebe7e2200131)
15
+[wt: changes from 1.6 : no tcp-check comments, check becomes s->proxy]
16
+---
17
+ src/cfgparse.c | 18 +++++++-----------
18
+ src/checks.c   | 15 +++++++++------
19
+ 2 files changed, 16 insertions(+), 17 deletions(-)
20
+
21
+diff --git a/src/cfgparse.c b/src/cfgparse.c
22
+index dba59d1..e04eff8 100644
23
+--- a/src/cfgparse.c
24
++++ b/src/cfgparse.c
25
+@@ -4362,20 +4362,16 @@ stats_error_parsing:
26
+ 			const char *ptr_arg;
27
+ 			int cur_arg;
28
+ 			struct tcpcheck_rule *tcpcheck;
29
+-			struct list *l;
30
+ 
31
+ 			/* check if first rule is also a 'connect' action */
32
+-			l = (struct list *)&curproxy->tcpcheck_rules;
33
+-			if (l->p != l->n) {
34
+-				tcpcheck = (struct tcpcheck_rule *)l->n;
35
++			tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
36
+ 
37
+-				if (&tcpcheck->list != &curproxy->tcpcheck_rules
38
+-				    && tcpcheck->action != TCPCHK_ACT_CONNECT) {
39
+-					Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
40
+-					      file, linenum);
41
+-					err_code |= ERR_ALERT | ERR_FATAL;
42
+-					goto out;
43
+-				}
44
++			if (&tcpcheck->list != &curproxy->tcpcheck_rules
45
++			    && tcpcheck->action != TCPCHK_ACT_CONNECT) {
46
++				Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
47
++				      file, linenum);
48
++				err_code |= ERR_ALERT | ERR_FATAL;
49
++				goto out;
50
+ 			}
51
+ 
52
+ 			cur_arg = 2;
53
+diff --git a/src/checks.c b/src/checks.c
54
+index e13d561..27a23b2 100644
55
+--- a/src/checks.c
56
++++ b/src/checks.c
57
+@@ -1444,7 +1444,10 @@ static int connect_chk(struct task *t)
58
+ 	quickack = check->type == 0 || check->type == PR_O2_TCPCHK_CHK;
59
+ 
60
+ 	if (check->type == PR_O2_TCPCHK_CHK && !LIST_ISEMPTY(&s->proxy->tcpcheck_rules)) {
61
+-		struct tcpcheck_rule *r = (struct tcpcheck_rule *) s->proxy->tcpcheck_rules.n;
62
++		struct tcpcheck_rule *r;
63
++
64
++		r = LIST_NEXT(&s->proxy->tcpcheck_rules, struct tcpcheck_rule *, list);
65
++
66
+ 		/* if first step is a 'connect', then tcpcheck_main must run it */
67
+ 		if (r->action == TCPCHK_ACT_CONNECT) {
68
+ 			tcpcheck_main(conn);
69
+@@ -1952,7 +1955,7 @@ static void tcpcheck_main(struct connection *conn)
70
+ 		/* have 'next' point to the next rule or NULL if we're on the
71
+ 		 * last one, connect() needs this.
72
+ 		 */
73
+-		next = (struct tcpcheck_rule *)check->current_step->list.n;
74
++		next = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list);
75
+ 
76
+ 		if (&next->list == head)
77
+ 			next = NULL;
78
+@@ -2055,7 +2058,7 @@ static void tcpcheck_main(struct connection *conn)
79
+ 			}
80
+ 
81
+ 			/* allow next rule */
82
+-			check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
83
++			check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list);
84
+ 
85
+ 			if (&check->current_step->list == head)
86
+ 				break;
87
+@@ -2112,7 +2115,7 @@ static void tcpcheck_main(struct connection *conn)
88
+ 			*check->bo->p = '\0'; /* to make gdb output easier to read */
89
+ 
90
+ 			/* go to next rule and try to send */
91
+-			check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
92
++			check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list);
93
+ 
94
+ 			if (&check->current_step->list == head)
95
+ 				break;
96
+@@ -2200,7 +2203,7 @@ static void tcpcheck_main(struct connection *conn)
97
+ 				/* matched and was supposed to => OK, next step */
98
+ 				else {
99
+ 					/* allow next rule */
100
+-					check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
101
++					check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list);
102
+ 
103
+ 					if (&check->current_step->list == head)
104
+ 						break;
105
+@@ -2215,7 +2218,7 @@ static void tcpcheck_main(struct connection *conn)
106
+ 				/* not matched and was not supposed to => OK, next step */
107
+ 				if (check->current_step->inverse) {
108
+ 					/* allow next rule */
109
+-					check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
110
++					check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list);
111
+ 
112
+ 					if (&check->current_step->list == head)
113
+ 						break;
114
+-- 
115
+2.0.5
116
+

+ 77
- 0
net/haproxy/patches/0009-BUG-MEDIUM-peers-apply-a-random-reconnection-timeout.patch View File

@@ -0,0 +1,77 @@
1
+From 76a06b2804bcdba0fb2c19f834bdb511ce3cf344 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Wed, 20 May 2015 10:39:04 +0200
4
+Subject: [PATCH 09/10] BUG/MEDIUM: peers: apply a random reconnection timeout
5
+
6
+Commit 9ff95bb ("BUG/MEDIUM: peers: correctly configure the client timeout")
7
+uncovered an old bug in the peers : upon disconnect, we reconnect immediately.
8
+This sometimes results in both ends to do the same thing in parallel causing
9
+a loop of connect/accept/close/close that can last several seconds. The risk
10
+of occurrence of the trouble increases with latency, and is emphasized by the
11
+fact that idle connections are now frequently recycled (after 5s of idle).
12
+
13
+In order to avoid this we must apply a random delay before reconnecting.
14
+Fortunately the mechanism already supports a reconnect delay, so here we
15
+compute the random timeout when killing a session. The delay is 50ms plus
16
+a random between 0 and 2 seconds. Ideally an exponential back-off would
17
+be preferred but it's preferable to keep the fix simple.
18
+
19
+This bug was reported by Marco Corte.
20
+
21
+This fix must be backported to 1.5 since the fix above was backported into
22
+1.5.12.
23
+(cherry picked from commit b4e34da692d8a7f6837ad16b3389f5830dbc11d2)
24
+---
25
+ src/peers.c | 14 +++++++++++---
26
+ 1 file changed, 11 insertions(+), 3 deletions(-)
27
+
28
+diff --git a/src/peers.c b/src/peers.c
29
+index b196d88..159f0a4 100644
30
+--- a/src/peers.c
31
++++ b/src/peers.c
32
+@@ -1063,6 +1063,7 @@ static void peer_session_forceshutdown(struct session * session)
33
+ {
34
+ 	struct stream_interface *oldsi = NULL;
35
+ 	struct appctx *appctx = NULL;
36
++	struct peer_session *ps;
37
+ 	int i;
38
+ 
39
+ 	for (i = 0; i <= 1; i++) {
40
+@@ -1079,6 +1080,14 @@ static void peer_session_forceshutdown(struct session * session)
41
+ 	if (!appctx)
42
+ 		return;
43
+ 
44
++	ps = (struct peer_session *)appctx->ctx.peers.ptr;
45
++	/* we're killing a connection, we must apply a random delay before
46
++	 * retrying otherwise the other end will do the same and we can loop
47
++	 * for a while.
48
++	 */
49
++	if (ps)
50
++		ps->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + random() % 2000));
51
++
52
+ 	/* call release to reinit resync states if needed */
53
+ 	peer_session_release(oldsi);
54
+ 	appctx->st0 = PEER_SESS_ST_END;
55
+@@ -1352,8 +1361,8 @@ static struct task *process_peer_sync(struct task * task)
56
+ 				if (!ps->session) {
57
+ 					/* no active session */
58
+ 					if (ps->statuscode == 0 ||
59
+-					    ps->statuscode == PEER_SESS_SC_SUCCESSCODE ||
60
+ 					    ((ps->statuscode == PEER_SESS_SC_CONNECTCODE ||
61
++					      ps->statuscode == PEER_SESS_SC_SUCCESSCODE ||
62
+ 					      ps->statuscode == PEER_SESS_SC_CONNECTEDCODE) &&
63
+ 					     tick_is_expired(ps->reconnect, now_ms))) {
64
+ 						/* connection never tried
65
+@@ -1364,8 +1373,7 @@ static struct task *process_peer_sync(struct task * task)
66
+ 						/* retry a connect */
67
+ 						ps->session = peer_session_create(ps->peer, ps);
68
+ 					}
69
+-					else if (ps->statuscode == PEER_SESS_SC_CONNECTCODE ||
70
+-						 ps->statuscode == PEER_SESS_SC_CONNECTEDCODE) {
71
++					else if (!tick_is_expired(ps->reconnect, now_ms)) {
72
+ 						/* If previous session failed during connection
73
+ 						 * but reconnection timer is not expired */
74
+ 
75
+-- 
76
+2.0.5
77
+

+ 33
- 0
net/haproxy/patches/0010-DOC-Update-doc-about-weight-act-and-bck-fields-in-th.patch View File

@@ -0,0 +1,33 @@
1
+From ac372e18c422841a9f1197b4238637c470e8edca Mon Sep 17 00:00:00 2001
2
+From: Pavlos Parissis <pavlos.parissis@gmail.com>
3
+Date: Sat, 2 May 2015 20:30:44 +0200
4
+Subject: [PATCH 10/10] DOC: Update doc about weight, act and bck fields in the
5
+ statistics
6
+
7
+Reorder description of the mentioned fields in order to match the
8
+order of types
9
+(cherry picked from commit 1f673c72c11d011bbd24e309d3155384eddf7a46)
10
+---
11
+ doc/configuration.txt | 6 +++---
12
+ 1 file changed, 3 insertions(+), 3 deletions(-)
13
+
14
+diff --git a/doc/configuration.txt b/doc/configuration.txt
15
+index a9d497e..6f5eeb1 100644
16
+--- a/doc/configuration.txt
17
++++ b/doc/configuration.txt
18
+@@ -13240,9 +13240,9 @@ S (Servers).
19
+      server. The server value counts the number of times that server was
20
+      switched away from.
21
+  17. status [LFBS]: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)
22
+- 18. weight [..BS]: server weight (server), total weight (backend)
23
+- 19. act [..BS]: server is active (server), number of active servers (backend)
24
+- 20. bck [..BS]: server is backup (server), number of backup servers (backend)
25
++ 18. weight [..BS]: total weight (backend), server weight (server)
26
++ 19. act [..BS]: number of active servers (backend), server is active (server)
27
++ 20. bck [..BS]: number of backup servers (backend), server is backup (server)
28
+  21. chkfail [...S]: number of failed checks. (Only counts checks failed when
29
+      the server is up.)
30
+  22. chkdown [..BS]: number of UP->DOWN transitions. The backend counter counts
31
+-- 
32
+2.0.5
33
+

+ 64
- 0
net/haproxy/patches/0011-MINOR-ssl-add-a-destructor-to-free-allocated-SSL-res.patch View File

@@ -0,0 +1,64 @@
1
+From 269a02fbb332da8faf6c2a614d45d5b5018816d1 Mon Sep 17 00:00:00 2001
2
+From: Remi Gacogne <rgacogne@aquaray.fr>
3
+Date: Thu, 28 May 2015 16:39:47 +0200
4
+Subject: [PATCH 11/14] MINOR: ssl: add a destructor to free allocated SSL
5
+ ressources
6
+
7
+Using valgrind or another memory leak tracking tool is easier
8
+when the memory internally allocated by OpenSSL is cleanly released
9
+at shutdown.
10
+(cherry picked from commit d3a23c3eb8c0950d26204568a133207099923494)
11
+---
12
+ src/ssl_sock.c | 36 ++++++++++++++++++++++++++++++++++++
13
+ 1 file changed, 36 insertions(+)
14
+
15
+diff --git a/src/ssl_sock.c b/src/ssl_sock.c
16
+index d0f4d01..a78fc6a 100644
17
+--- a/src/ssl_sock.c
18
++++ b/src/ssl_sock.c
19
+@@ -4717,6 +4717,42 @@ static void __ssl_sock_init(void)
20
+ 	cfg_register_keywords(&cfg_kws);
21
+ }
22
+ 
23
++__attribute__((destructor))
24
++static void __ssl_sock_deinit(void)
25
++{
26
++#ifndef OPENSSL_NO_DH
27
++        if (local_dh_1024) {
28
++                DH_free(local_dh_1024);
29
++                local_dh_1024 = NULL;
30
++        }
31
++
32
++        if (local_dh_2048) {
33
++                DH_free(local_dh_2048);
34
++                local_dh_2048 = NULL;
35
++        }
36
++
37
++        if (local_dh_4096) {
38
++                DH_free(local_dh_4096);
39
++                local_dh_4096 = NULL;
40
++        }
41
++
42
++        if (local_dh_8192) {
43
++                DH_free(local_dh_8192);
44
++                local_dh_8192 = NULL;
45
++        }
46
++#endif
47
++
48
++        ERR_remove_state(0);
49
++        ERR_free_strings();
50
++
51
++        EVP_cleanup();
52
++
53
++#if OPENSSL_VERSION_NUMBER >= 0x00907000L
54
++        CRYPTO_cleanup_all_ex_data();
55
++#endif
56
++}
57
++
58
++
59
+ /*
60
+  * Local variables:
61
+  *  c-indent-level: 8
62
+-- 
63
+2.0.5
64
+

+ 98
- 0
net/haproxy/patches/0012-BUG-MEDIUM-ssl-fix-tune.ssl.default-dh-param-value-b.patch View File

@@ -0,0 +1,98 @@
1
+From 5d769ca828fdb055052b3dbc232864bdf2853c9f Mon Sep 17 00:00:00 2001
2
+From: Remi Gacogne <rgacogne@aquaray.fr>
3
+Date: Thu, 28 May 2015 16:23:00 +0200
4
+Subject: [PATCH 12/14] BUG/MEDIUM: ssl: fix tune.ssl.default-dh-param value
5
+ being overwritten
6
+MIME-Version: 1.0
7
+Content-Type: text/plain; charset=UTF-8
8
+Content-Transfer-Encoding: 8bit
9
+
10
+Hervé Commowick reported that the logic used to avoid complaining about
11
+ssl-default-dh-param not being set when static DH params are present
12
+in the certificate file was clearly wrong when more than one sni_ctx
13
+is used.
14
+This patch stores whether static DH params are being used for each
15
+SSL_CTX individually, and does not overwrite the value of
16
+tune.ssl.default-dh-param.
17
+(cherry picked from commit 4f902b88323927c9d25d391a809e3678ac31df41)
18
+---
19
+ src/ssl_sock.c | 28 +++++++++++++++++++++++-----
20
+ 1 file changed, 23 insertions(+), 5 deletions(-)
21
+
22
+diff --git a/src/ssl_sock.c b/src/ssl_sock.c
23
+index a78fc6a..0f7819b 100644
24
+--- a/src/ssl_sock.c
25
++++ b/src/ssl_sock.c
26
+@@ -47,6 +47,9 @@
27
+ #ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
28
+ #include <openssl/ocsp.h>
29
+ #endif
30
++#ifndef OPENSSL_NO_DH
31
++#include <openssl/dh.h>
32
++#endif
33
+ 
34
+ #include <common/buffer.h>
35
+ #include <common/compat.h>
36
+@@ -107,6 +110,7 @@ int sslconns = 0;
37
+ int totalsslconns = 0;
38
+ 
39
+ #ifndef OPENSSL_NO_DH
40
++static int ssl_dh_ptr_index = -1;
41
+ static DH *local_dh_1024 = NULL;
42
+ static DH *local_dh_2048 = NULL;
43
+ static DH *local_dh_4096 = NULL;
44
+@@ -1076,10 +1080,12 @@ int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
45
+ 	if (dh) {
46
+ 		ret = 1;
47
+ 		SSL_CTX_set_tmp_dh(ctx, dh);
48
+-		/* Setting ssl default dh param to the size of the static DH params
49
+-		   found in the file. This way we know that there is no use
50
+-		   complaining later about ssl-default-dh-param not being set. */
51
+-		global.tune.ssl_default_dh_param = DH_size(dh) * 8;
52
++
53
++		if (ssl_dh_ptr_index >= 0) {
54
++			/* store a pointer to the DH params to avoid complaining about
55
++			   ssl-default-dh-param not being set for this SSL_CTX */
56
++			SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
57
++		}
58
+ 	}
59
+ 	else {
60
+ 		/* Clear openssl global errors stack */
61
+@@ -1274,6 +1280,12 @@ static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf
62
+ 	 * the tree, so it will be discovered and cleaned in time.
63
+ 	 */
64
+ #ifndef OPENSSL_NO_DH
65
++	/* store a NULL pointer to indicate we have not yet loaded
66
++	   a custom DH param file */
67
++	if (ssl_dh_ptr_index >= 0) {
68
++		SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
69
++	}
70
++
71
+ 	ret = ssl_sock_load_dh_params(ctx, path);
72
+ 	if (ret < 0) {
73
+ 		if (err)
74
+@@ -1593,7 +1605,9 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy
75
+ 
76
+ 	/* If tune.ssl.default-dh-param has not been set and
77
+ 	   no static DH params were in the certificate file. */
78
+-	if (global.tune.ssl_default_dh_param == 0) {
79
++	if (global.tune.ssl_default_dh_param == 0 &&
80
++	    (ssl_dh_ptr_index == -1 ||
81
++	     SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
82
+ 		ciphers = ctx->cipher_list;
83
+ 
84
+ 		if (ciphers) {
85
+@@ -4715,6 +4729,10 @@ static void __ssl_sock_init(void)
86
+ 	bind_register_keywords(&bind_kws);
87
+ 	srv_register_keywords(&srv_kws);
88
+ 	cfg_register_keywords(&cfg_kws);
89
++
90
++#ifndef OPENSSL_NO_DH
91
++	ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
92
++#endif
93
+ }
94
+ 
95
+ __attribute__((destructor))
96
+-- 
97
+2.0.5
98
+

+ 29
- 0
net/haproxy/patches/0013-BUG-MINOR-cfgparse-fix-typo-in-option-httplog-error-.patch View File

@@ -0,0 +1,29 @@
1
+From 629b1c000b26f0031246b9b529680b275a14118f Mon Sep 17 00:00:00 2001
2
+From: William Lallemand <wlallemand@haproxy.com>
3
+Date: Thu, 28 May 2015 18:02:48 +0200
4
+Subject: [PATCH 13/14] BUG/MINOR: cfgparse: fix typo in 'option httplog' error
5
+ message
6
+
7
+The error message was displaying the wrong argument when 'option
8
+httplog' took a wrong argument.
9
+(cherry picked from commit 77063bc0c6ceb4257c4e2c08411811ecc48be1aa)
10
+---
11
+ src/cfgparse.c | 2 +-
12
+ 1 file changed, 1 insertion(+), 1 deletion(-)
13
+
14
+diff --git a/src/cfgparse.c b/src/cfgparse.c
15
+index e04eff8..3c3383d 100644
16
+--- a/src/cfgparse.c
17
++++ b/src/cfgparse.c
18
+@@ -3792,7 +3792,7 @@ stats_error_parsing:
19
+ 					curproxy->options2 |= PR_O2_CLFLOG;
20
+ 					logformat = clf_http_log_format;
21
+ 				} else {
22
+-					Alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[2]);
23
++					Alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
24
+ 					err_code |= ERR_ALERT | ERR_FATAL;
25
+ 					goto out;
26
+ 				}
27
+-- 
28
+2.0.5
29
+

+ 41
- 0
net/haproxy/patches/0014-BUG-MEDIUM-cfgparse-segfault-when-userlist-is-misuse.patch View File

@@ -0,0 +1,41 @@
1
+From faf3315f77c527e6e1d027deb7e853cdf6af5858 Mon Sep 17 00:00:00 2001
2
+From: William Lallemand <wlallemand@haproxy.com>
3
+Date: Thu, 28 May 2015 18:03:51 +0200
4
+Subject: [PATCH 14/14] BUG/MEDIUM: cfgparse: segfault when userlist is misused
5
+
6
+If the 'userlist' keyword parsing returns an error and no userlist were
7
+previously created. The parsing of 'user' and 'group' leads to NULL
8
+derefence.
9
+
10
+The userlist pointer is now tested to prevent this issue.
11
+(cherry picked from commit 4ac9f546120d42be8147e3d90588e7b9738af0cc)
12
+---
13
+ src/cfgparse.c | 5 +++++
14
+ 1 file changed, 5 insertions(+)
15
+
16
+diff --git a/src/cfgparse.c b/src/cfgparse.c
17
+index 3c3383d..392a78d 100644
18
+--- a/src/cfgparse.c
19
++++ b/src/cfgparse.c
20
+@@ -5668,6 +5668,9 @@ cfg_parse_users(const char *file, int linenum, char **args, int kwm)
21
+ 			goto out;
22
+ 		}
23
+ 
24
++		if (!userlist)
25
++			goto out;
26
++
27
+ 		for (ag = userlist->groups; ag; ag = ag->next)
28
+ 			if (!strcmp(ag->name, args[1])) {
29
+ 				Warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
30
+@@ -5718,6 +5721,8 @@ cfg_parse_users(const char *file, int linenum, char **args, int kwm)
31
+ 			err_code |= ERR_ALERT | ERR_FATAL;
32
+ 			goto out;
33
+ 		}
34
++		if (!userlist)
35
++			goto out;
36
+ 
37
+ 		for (newuser = userlist->users; newuser; newuser = newuser->next)
38
+ 			if (!strcmp(newuser->user, args[1])) {
39
+-- 
40
+2.0.5
41
+