0001-BUG-MAJOR-fix-listening-IP-address-storage-for-front.patch 0002-BUG-MINOR-fix-listening-IP-address-storage-for-front.patch 0003-DOC-Fix-typo-so-fetch-is-properly-parsed-by-Cyril-s-.patch 0004-BUG-MAJOR-http-fix-breakage-of-reqdeny-causing-rando.patch 0005-BUG-MEDIUM-stick-tables-fix-breakage-in-table-conver.patch 0006-BUG-MEDIUM-dns-unbreak-DNS-resolver-after-header-fix.patch 0007-BUILD-fix-build-on-Solaris-11.patch 0008-CLEANUP-connection-fix-double-negation-on-memcmp.patch 0009-BUG-MEDIUM-stats-show-servers-state-may-show-an-serv.patch 0010-BUG-MEDIUM-fix-risk-of-segfault-with-show-tls-keys.patch 0011-BUG-MEDIUM-sticktables-segfault-in-some-configuratio.patch 0012-BUG-MEDIUM-lua-converters-doesn-t-work.patch 0013-BUG-MINOR-http-add-header-header-name-copied-twice.patch 0014-BUG-MEDIUM-http-add-header-buffer-overwritten.patch OBS-URL: https://build.opensuse.org/package/show/server:http/haproxy?expand=0&rev=129
152 lines
5.9 KiB
Diff
152 lines
5.9 KiB
Diff
From 66dd99c4c9d828c2c2f7295b7db66f7ff6f2fa8e Mon Sep 17 00:00:00 2001
|
|
From: Vincent Bernat <vincent@bernat.im>
|
|
Date: Wed, 18 May 2016 16:17:44 +0200
|
|
Subject: [PATCH 01/14] BUG/MAJOR: fix listening IP address storage for
|
|
frontends
|
|
|
|
When compiled with GCC 6, the IP address specified for a frontend was
|
|
ignored and HAProxy was listening on all addresses instead. This is
|
|
caused by an incomplete copy of a "struct sockaddr_storage".
|
|
|
|
With the GNU Libc, "struct sockaddr_storage" is defined as this:
|
|
|
|
struct sockaddr_storage
|
|
{
|
|
sa_family_t ss_family;
|
|
unsigned long int __ss_align;
|
|
char __ss_padding[(128 - (2 * sizeof (unsigned long int)))];
|
|
};
|
|
|
|
Doing an aggregate copy (ss1 = ss2) is different than using memcpy():
|
|
only members of the aggregate have to be copied. Notably, padding can be
|
|
or not be copied. In GCC 6, some optimizations use this fact and if a
|
|
"struct sockaddr_storage" contains a "struct sockaddr_in", the port and
|
|
the address are part of the padding (between sa_family and __ss_align)
|
|
and can be not copied over.
|
|
|
|
Therefore, we replace any aggregate copy by a memcpy(). There is another
|
|
place using the same pattern. We also fix a function receiving a "struct
|
|
sockaddr_storage" by copy instead of by reference. Since it only needs a
|
|
read-only copy, the function is converted to request a reference.
|
|
|
|
(cherry picked from commit 6e61589573f49b20a7184c9d297af1fc7d9184d8)
|
|
---
|
|
include/proto/proto_http.h | 2 +-
|
|
src/cfgparse.c | 2 +-
|
|
src/connection.c | 2 +-
|
|
src/hlua.c | 2 +-
|
|
src/proto_http.c | 12 ++++++------
|
|
src/proto_tcp.c | 2 +-
|
|
6 files changed, 11 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
|
|
index a1b0cb3..4ed96e3 100644
|
|
--- a/include/proto/proto_http.h
|
|
+++ b/include/proto/proto_http.h
|
|
@@ -110,7 +110,7 @@ void http_set_status(unsigned int status, struct stream *s);
|
|
int http_transform_header_str(struct stream* s, struct http_msg *msg, const char* name,
|
|
unsigned int name_len, const char *str, struct my_regex *re,
|
|
int action);
|
|
-void inet_set_tos(int fd, struct sockaddr_storage from, int tos);
|
|
+void inet_set_tos(int fd, const struct sockaddr_storage *from, int tos);
|
|
void http_perform_server_redirect(struct stream *s, struct stream_interface *si);
|
|
void http_return_srv_error(struct stream *s, struct stream_interface *si);
|
|
void http_capture_bad_message(struct error_snapshot *es, struct stream *s,
|
|
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
|
index 97ec2e1..c118bd4 100644
|
|
--- a/src/cfgparse.c
|
|
+++ b/src/cfgparse.c
|
|
@@ -285,7 +285,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
|
|
}
|
|
|
|
/* OK the address looks correct */
|
|
- ss = *ss2;
|
|
+ memcpy(&ss, ss2, sizeof(ss));
|
|
|
|
for (; port <= end; port++) {
|
|
l = (struct listener *)calloc(1, sizeof(struct listener));
|
|
diff --git a/src/connection.c b/src/connection.c
|
|
index b926e9f..991cae3 100644
|
|
--- a/src/connection.c
|
|
+++ b/src/connection.c
|
|
@@ -744,7 +744,7 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec
|
|
const char pp2_signature[] = PP2_SIGNATURE;
|
|
int ret = 0;
|
|
struct proxy_hdr_v2 *hdr = (struct proxy_hdr_v2 *)buf;
|
|
- struct sockaddr_storage null_addr = {0};
|
|
+ struct sockaddr_storage null_addr = { .ss_family = 0 };
|
|
struct sockaddr_storage *src = &null_addr;
|
|
struct sockaddr_storage *dst = &null_addr;
|
|
|
|
diff --git a/src/hlua.c b/src/hlua.c
|
|
index 5ea3a83..edd288d 100644
|
|
--- a/src/hlua.c
|
|
+++ b/src/hlua.c
|
|
@@ -4790,7 +4790,7 @@ __LJMP static int hlua_txn_set_tos(lua_State *L)
|
|
tos = MAY_LJMP(luaL_checkinteger(L, 2));
|
|
|
|
if ((cli_conn = objt_conn(htxn->s->sess->origin)) && conn_ctrl_ready(cli_conn))
|
|
- inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, tos);
|
|
+ inet_set_tos(cli_conn->t.sock.fd, &cli_conn->addr.from, tos);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/src/proto_http.c b/src/proto_http.c
|
|
index 9de1a17..59cd5d2 100644
|
|
--- a/src/proto_http.c
|
|
+++ b/src/proto_http.c
|
|
@@ -3403,15 +3403,15 @@ int http_handle_stats(struct stream *s, struct channel *req)
|
|
/* Sets the TOS header in IPv4 and the traffic class header in IPv6 packets
|
|
* (as per RFC3260 #4 and BCP37 #4.2 and #5.2).
|
|
*/
|
|
-void inet_set_tos(int fd, struct sockaddr_storage from, int tos)
|
|
+void inet_set_tos(int fd, const struct sockaddr_storage *from, int tos)
|
|
{
|
|
#ifdef IP_TOS
|
|
- if (from.ss_family == AF_INET)
|
|
+ if (from->ss_family == AF_INET)
|
|
setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
|
|
#endif
|
|
#ifdef IPV6_TCLASS
|
|
- if (from.ss_family == AF_INET6) {
|
|
- if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&from)->sin6_addr))
|
|
+ if (from->ss_family == AF_INET6) {
|
|
+ if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)from)->sin6_addr))
|
|
/* v4-mapped addresses need IP_TOS */
|
|
setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
|
|
else
|
|
@@ -3577,7 +3577,7 @@ resume_execution:
|
|
|
|
case ACT_HTTP_SET_TOS:
|
|
if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
|
|
- inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos);
|
|
+ inet_set_tos(cli_conn->t.sock.fd, &cli_conn->addr.from, rule->arg.tos);
|
|
break;
|
|
|
|
case ACT_HTTP_SET_MARK:
|
|
@@ -3860,7 +3860,7 @@ resume_execution:
|
|
|
|
case ACT_HTTP_SET_TOS:
|
|
if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
|
|
- inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos);
|
|
+ inet_set_tos(cli_conn->t.sock.fd, &cli_conn->addr.from, rule->arg.tos);
|
|
break;
|
|
|
|
case ACT_HTTP_SET_MARK:
|
|
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
|
|
index cce0acb..59cfea2 100644
|
|
--- a/src/proto_tcp.c
|
|
+++ b/src/proto_tcp.c
|
|
@@ -435,7 +435,7 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
|
|
struct sockaddr_storage sa;
|
|
|
|
ret = 1;
|
|
- sa = src->source_addr;
|
|
+ memcpy(&sa, &src->source_addr, sizeof(sa));
|
|
|
|
do {
|
|
/* note: in case of retry, we may have to release a previously
|
|
--
|
|
2.6.6
|
|
|