- [PATCH 14/16] BUG/MINOR: http: remove stupid HTTP_METH_NONE entry - [PATCH 15/16] BUG/MAJOR: http: don't call http_send_name_header() - [PATCH 16/16] BUG/MINOR: tools: make str2sa_range() report Signed-off-by: heil <heil@terminal-consulting.de>lilik-openwrt-22.03
@ -0,0 +1,78 @@ | |||
From bcd033699c5a4904967652de4980e4f35f17ee34 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Thu, 3 Sep 2015 17:15:21 +0200 | |||
Subject: [PATCH 14/16] BUG/MINOR: http: remove stupid HTTP_METH_NONE entry | |||
When converting the "method" fetch to a string, we used to get an empty | |||
string if the first character was not an upper case. This was caused by | |||
the lookup function which returns HTTP_METH_NONE when a lookup is not | |||
possible, and this method being mapped to an empty string in the array. | |||
This is a totally stupid mechanism, there's no reason for having the | |||
result depend on the first char. In fact the message parser already | |||
checks that the syntax matches an HTTP token so we can only land there | |||
with a valid token, hence only HTTP_METH_OTHER should be returned. | |||
This fix should be backported to all actively supported branches. | |||
(cherry picked from commit b7ce424be2bc9df73a3b971fa9dd6daea0332bf1) | |||
--- | |||
include/types/proto_http.h | 1 - | |||
src/proto_http.c | 11 ++++------- | |||
2 files changed, 4 insertions(+), 8 deletions(-) | |||
diff --git a/include/types/proto_http.h b/include/types/proto_http.h | |||
index a5a5d31..dbce972 100644 | |||
--- a/include/types/proto_http.h | |||
+++ b/include/types/proto_http.h | |||
@@ -219,7 +219,6 @@ enum { | |||
/* Known HTTP methods */ | |||
enum http_meth_t { | |||
- HTTP_METH_NONE = 0, | |||
HTTP_METH_OPTIONS, | |||
HTTP_METH_GET, | |||
HTTP_METH_HEAD, | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index 02dc42b..46694cb 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -361,12 +361,11 @@ const struct http_method_desc http_methods[26][3] = { | |||
[0] = { .meth = HTTP_METH_TRACE , .len=5, .text="TRACE" }, | |||
}, | |||
/* rest is empty like this : | |||
- * [1] = { .meth = HTTP_METH_NONE , .len=0, .text="" }, | |||
+ * [0] = { .meth = HTTP_METH_OTHER , .len=0, .text="" }, | |||
*/ | |||
}; | |||
const struct http_method_name http_known_methods[HTTP_METH_OTHER] = { | |||
- [HTTP_METH_NONE] = { "", 0 }, | |||
[HTTP_METH_OPTIONS] = { "OPTIONS", 7 }, | |||
[HTTP_METH_GET] = { "GET", 3 }, | |||
[HTTP_METH_HEAD] = { "HEAD", 4 }, | |||
@@ -793,8 +792,8 @@ struct chunk *http_error_message(struct session *s, int msgnum) | |||
} | |||
/* | |||
- * returns HTTP_METH_NONE if there is nothing valid to read (empty or non-text | |||
- * string), HTTP_METH_OTHER for unknown methods, or the identified method. | |||
+ * returns a known method among HTTP_METH_* or HTTP_METH_OTHER for all unknown | |||
+ * ones. | |||
*/ | |||
enum http_meth_t find_http_meth(const char *str, const int len) | |||
{ | |||
@@ -810,10 +809,8 @@ enum http_meth_t find_http_meth(const char *str, const int len) | |||
if (likely(memcmp(str, h->text, h->len) == 0)) | |||
return h->meth; | |||
}; | |||
- return HTTP_METH_OTHER; | |||
} | |||
- return HTTP_METH_NONE; | |||
- | |||
+ return HTTP_METH_OTHER; | |||
} | |||
/* Parse the URI from the given transaction (which is assumed to be in request | |||
-- | |||
2.4.6 | |||
@ -0,0 +1,49 @@ | |||
From 3f34b5539e7ba31e44055d853b9ba496e73e0bae Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Mon, 7 Sep 2015 19:32:33 +0200 | |||
Subject: [PATCH 15/16] BUG/MAJOR: http: don't call http_send_name_header() | |||
after an error | |||
A crash was reported when using the "famous" http-send-name-header | |||
directive. This time it's a bit tricky, it requires a certain number of | |||
conditions to be met including maxconn on a server, queuing, timeout in | |||
the queue and cookie-based persistence. | |||
The problem is that in stream.c, before calling http_send_name_header(), | |||
we check a number of conditions to know if we have to replace the header | |||
name. But prior to reaching this place, it's possible for | |||
sess_update_stream_int() to fail and change the stream-int's state to | |||
SI_ST_CLO, send an error 503 to the client, and flush all buffers. But | |||
http_send_name_header() can only be called with valid buffer contents | |||
matching the http_msg's description. So when it rewinds the stream to | |||
modify the header, buf->o becomes negative by the size of the incoming | |||
request and is used as the argument to memmove() which basically | |||
displaces 4GB of memory off a few bytes to write the new name, resulting | |||
in a core and a core file that's really not fun to play with. | |||
The solution obviously consists in refraining from calling this nasty | |||
function when the stream interface is already closed. | |||
This bug also affects 1.5 and possibly 1.4, so the fix must be backported | |||
there. | |||
(cherry picked from commit 9c03b33329cb4924716edc1c851913a18b0670dc) | |||
--- | |||
src/session.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/session.c b/src/session.c | |||
index 6d62e36..7520a85 100644 | |||
--- a/src/session.c | |||
+++ b/src/session.c | |||
@@ -2293,7 +2293,7 @@ struct task *process_session(struct task *t) | |||
/* Now we can add the server name to a header (if requested) */ | |||
/* check for HTTP mode and proxy server_name_hdr_name != NULL */ | |||
- if ((s->si[1].state >= SI_ST_CON) && | |||
+ if ((s->si[1].state >= SI_ST_CON) && (s->si[1].state < SI_ST_CLO) && | |||
(s->be->server_id_hdr_name != NULL) && | |||
(s->be->mode == PR_MODE_HTTP) && | |||
objt_server(s->target)) { | |||
-- | |||
2.4.6 | |||
@ -0,0 +1,36 @@ | |||
From 36456071ea34546d98d3b66a696cd4c4c4643de5 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Tue, 8 Sep 2015 16:01:25 +0200 | |||
Subject: [PATCH 16/16] BUG/MINOR: tools: make str2sa_range() report | |||
unresolvable addresses | |||
If an environment variable is used in an address, and is not set, it's | |||
silently considered as ":" or "0.0.0.0:0" which is not correct as it | |||
can hide environment issues and lead to unexpected behaviours. Let's | |||
report this case when it happens. | |||
This fix should be backported to 1.5. | |||
(cherry picked from commit 9f69f46d1f1b1d116c00b4b0483c519747f977b7) | |||
--- | |||
src/standard.c | 5 +++++ | |||
1 file changed, 5 insertions(+) | |||
diff --git a/src/standard.c b/src/standard.c | |||
index f57724c..9299882 100644 | |||
--- a/src/standard.c | |||
+++ b/src/standard.c | |||
@@ -709,6 +709,11 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char | |||
goto out; | |||
} | |||
+ if (!*str2) { | |||
+ memprintf(err, "'%s' resolves to an empty address (environment variable missing?)\n", str); | |||
+ goto out; | |||
+ } | |||
+ | |||
memset(&ss, 0, sizeof(ss)); | |||
if (strncmp(str2, "unix@", 5) == 0) { | |||
-- | |||
2.4.6 | |||