BUG/MINOR: http_fetch: fix possible uninit sockaddr in fetch_url_ip/port
Check the return value of url2sa in smp_fetch_url_ip/port. If negative,
the address result is uninitialized and the sample fetch is aborted.
Also, the sockaddr is prelimiary zero'ed before calling url2sa to ensure
that it is not used by upper functions even if the sample returns 0.
Without the check, the value returned by the url_ip/url_port fetches is
unspecified. This can be triggered with the following curl :
$ curl -iv --request-target "xxx://127.0.0.1:20080/" http://127.0.0.1:20080/
This should be backported to all stable branches. However, note that
between the 1.8 and 2.0, the targetted functions have been extracted
from proto_http.c to http_fetch.c.
This should fix in part coverity report from the github issue #1244.
(cherry picked from commit c89d5337ee5064091ceab7b2d967f99071dc39eb)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 6e5795d610be8491525b781b53ef474fbe4a0341)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit f4edd378d2c6bd8e3ebcaf29204cdade7f8c8266)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/http_fetch.c b/src/http_fetch.c
index 1b4bc0a..0b16c51 100644
--- a/src/http_fetch.c
+++ b/src/http_fetch.c
@@ -1073,6 +1073,8 @@
struct http_txn *txn;
struct sockaddr_storage addr;
+ memset(&addr, 0, sizeof(addr));
+
if (smp->px->options2 & PR_O2_USE_HTX) {
/* HTX version */
struct htx *htx = smp_prefetch_htx(smp, chn, 1);
@@ -1081,14 +1083,16 @@
if (!htx)
return 0;
sl = http_get_stline(htx);
- url2sa(HTX_SL_REQ_UPTR(sl), HTX_SL_REQ_ULEN(sl), &addr, NULL);
+ if (url2sa(HTX_SL_REQ_UPTR(sl), HTX_SL_REQ_ULEN(sl), &addr, NULL) < 0)
+ return 0;
}
else {
/* LEGACY version */
CHECK_HTTP_MESSAGE_FIRST(chn);
txn = smp->strm->txn;
- url2sa(ci_head(chn) + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &addr, NULL);
+ if (url2sa(ci_head(chn) + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &addr, NULL) < 0)
+ return 0;
}
if (((struct sockaddr_in *)&addr)->sin_family != AF_INET)
@@ -1106,6 +1110,8 @@
struct http_txn *txn;
struct sockaddr_storage addr;
+ memset(&addr, 0, sizeof(addr));
+
if (smp->px->options2 & PR_O2_USE_HTX) {
/* HTX version */
struct htx *htx = smp_prefetch_htx(smp, chn, 1);
@@ -1114,14 +1120,16 @@
if (!htx)
return 0;
sl = http_get_stline(htx);
- url2sa(HTX_SL_REQ_UPTR(sl), HTX_SL_REQ_ULEN(sl), &addr, NULL);
+ if (url2sa(HTX_SL_REQ_UPTR(sl), HTX_SL_REQ_ULEN(sl), &addr, NULL) < 0)
+ return 0;
}
else {
/* LEGACY version */
CHECK_HTTP_MESSAGE_FIRST(chn);
txn = smp->strm->txn;
- url2sa(ci_head(chn) + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &addr, NULL);
+ if (url2sa(ci_head(chn) + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &addr, NULL) < 0)
+ return 0;
}
if (((struct sockaddr_in *)&addr)->sin_family != AF_INET)
return 0;