[arch-commits] Commit in haproxy/trunk (CVE-2016-5360-reqdeny.patch PKGBUILD)

Johannes Löthberg demize at archlinux.org
Fri Jun 10 06:23:09 UTC 2016


    Date: Friday, June 10, 2016 @ 08:23:08
  Author: demize
Revision: 179093

Patch CVE-2016-5360

http://www.openwall.com/lists/oss-security/2016/06/09/5

Added:
  haproxy/trunk/CVE-2016-5360-reqdeny.patch
Modified:
  haproxy/trunk/PKGBUILD

-----------------------------+
 CVE-2016-5360-reqdeny.patch |  117 ++++++++++++++++++++++++++++++++++++++++++
 PKGBUILD                    |    9 ++-
 2 files changed, 123 insertions(+), 3 deletions(-)

Added: CVE-2016-5360-reqdeny.patch
===================================================================
--- CVE-2016-5360-reqdeny.patch	                        (rev 0)
+++ CVE-2016-5360-reqdeny.patch	2016-06-10 06:23:08 UTC (rev 179093)
@@ -0,0 +1,117 @@
+From: Willy Tarreau <w at 1wt.eu>
+Date: Wed, 25 May 2016 14:23:59 +0000 (+0200)
+Subject: BUG/MAJOR: http: fix breakage of "reqdeny" causing random crashes
+X-Git-Url: http://git.haproxy.org/?p=haproxy-1.6.git;a=commitdiff_plain;h=60f01f8c89e4fb2723d5a9f2046286e699567e0b;hp=0c60f3790d6f177f123d4ae63d5f17868c789d12
+
+BUG/MAJOR: http: fix breakage of "reqdeny" causing random crashes
+
+Commit 108b1dd ("MEDIUM: http: configurable http result codes for
+http-request deny") introduced in 1.6-dev2 was incomplete. It introduced
+a new field "rule_deny_status" into struct http_txn, which is filled only
+by actions "http-request deny" and "http-request tarpit". It's then used
+in the deny code path to emit the proper error message, but is used
+uninitialized when the deny comes from a "reqdeny" rule, causing random
+behaviours ranging from returning a 200, an empty response, or crashing
+the process. Often upon startup only 200 was returned but after the fields
+are used the crash happens. This can be sped up using -dM.
+
+There's no need at all for storing this status in the http_txn struct
+anyway since it's used immediately after being set. Let's store it in
+a temporary variable instead which is passed as an argument to function
+http_req_get_intercept_rule().
+
+As an extra benefit, removing it from struct http_txn reduced the size
+of this struct by 8 bytes.
+
+This fix must be backported to 1.6 where the bug was detected. Special
+thanks to Falco Schmutz for his detailed report including an exploitable
+core and a reproducer.
+(cherry picked from commit 58727ec088e55f739b146cff3baa955f8d1b2a3e)
+---
+
+diff --git a/include/types/proto_http.h b/include/types/proto_http.h
+index e5e9667..c3a73ef 100644
+--- a/include/types/proto_http.h
++++ b/include/types/proto_http.h
+@@ -362,7 +362,6 @@ struct http_txn {
+ 	unsigned int flags;             /* transaction flags */
+ 	enum http_meth_t meth;          /* HTTP method */
+ 	/* 1 unused byte here */
+-	short rule_deny_status;         /* HTTP status from rule when denying */
+ 	short status;                   /* HTTP status from the server, negative if from proxy */
+ 
+ 	char *uri;                      /* first line if log needed, NULL otherwise */
+diff --git a/src/proto_http.c b/src/proto_http.c
+index 59cd5d2..6eac62b 100644
+--- a/src/proto_http.c
++++ b/src/proto_http.c
+@@ -3490,10 +3490,12 @@ static int http_transform_header(struct stream* s, struct http_msg *msg,
+  * further processing of the request (auth, deny, ...), and defaults to
+  * HTTP_RULE_RES_STOP if it executed all rules or stopped on an allow, or
+  * HTTP_RULE_RES_CONT if the last rule was reached. It may set the TX_CLTARPIT
+- * on txn->flags if it encounters a tarpit rule.
++ * on txn->flags if it encounters a tarpit rule. If <deny_status> is not NULL
++ * and a deny/tarpit rule is matched, it will be filled with this rule's deny
++ * status.
+  */
+ enum rule_result
+-http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct stream *s)
++http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct stream *s, int *deny_status)
+ {
+ 	struct session *sess = strm_sess(s);
+ 	struct http_txn *txn = s->txn;
+@@ -3539,12 +3541,14 @@ resume_execution:
+ 			return HTTP_RULE_RES_STOP;
+ 
+ 		case ACT_ACTION_DENY:
+-			txn->rule_deny_status = rule->deny_status;
++			if (deny_status)
++				*deny_status = rule->deny_status;
+ 			return HTTP_RULE_RES_DENY;
+ 
+ 		case ACT_HTTP_REQ_TARPIT:
+ 			txn->flags |= TX_CLTARPIT;
+-			txn->rule_deny_status = rule->deny_status;
++			if (deny_status)
++				*deny_status = rule->deny_status;
+ 			return HTTP_RULE_RES_DENY;
+ 
+ 		case ACT_HTTP_REQ_AUTH:
+@@ -4303,6 +4307,7 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
+ 	struct redirect_rule *rule;
+ 	struct cond_wordlist *wl;
+ 	enum rule_result verdict;
++	int deny_status = HTTP_ERR_403;
+ 
+ 	if (unlikely(msg->msg_state < HTTP_MSG_BODY)) {
+ 		/* we need more data */
+@@ -4323,7 +4328,7 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
+ 
+ 	/* evaluate http-request rules */
+ 	if (!LIST_ISEMPTY(&px->http_req_rules)) {
+-		verdict = http_req_get_intercept_rule(px, &px->http_req_rules, s);
++		verdict = http_req_get_intercept_rule(px, &px->http_req_rules, s, &deny_status);
+ 
+ 		switch (verdict) {
+ 		case HTTP_RULE_RES_YIELD: /* some data miss, call the function later. */
+@@ -4369,7 +4374,7 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
+ 
+ 		/* parse the whole stats request and extract the relevant information */
+ 		http_handle_stats(s, req);
+-		verdict = http_req_get_intercept_rule(px, &px->uri_auth->http_req_rules, s);
++		verdict = http_req_get_intercept_rule(px, &px->uri_auth->http_req_rules, s, &deny_status);
+ 		/* not all actions implemented: deny, allow, auth */
+ 
+ 		if (verdict == HTTP_RULE_RES_DENY) /* stats http-request deny */
+@@ -4500,9 +4505,9 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
+ 		manage_client_side_cookies(s, req);
+ 
+ 	txn->flags |= TX_CLDENY;
+-	txn->status = http_err_codes[txn->rule_deny_status];
++	txn->status = http_err_codes[deny_status];
+ 	s->logs.tv_request = now;
+-	stream_int_retnclose(&s->si[0], http_error_message(s, txn->rule_deny_status));
++	stream_int_retnclose(&s->si[0], http_error_message(s, deny_status));
+ 	stream_inc_http_err_ctr(s);
+ 	sess->fe->fe_counters.denied_req++;
+ 	if (sess->fe != s->be)

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2016-06-10 06:21:51 UTC (rev 179092)
+++ PKGBUILD	2016-06-10 06:23:08 UTC (rev 179093)
@@ -4,7 +4,7 @@
 
 pkgname=haproxy
 pkgver=1.6.5
-pkgrel=3
+pkgrel=4
 
 pkgdesc='Reliable, high performance TCP/HTTP load balancer'
 url='http://haproxy.org/'
@@ -19,16 +19,19 @@
 
 source=(http://haproxy.org/download/${pkgver%.*}/src/haproxy-$pkgver.tar.gz
         haproxy.cfg
-        gcc6-fix.patch)
+        gcc6-fix.patch
+        CVE-2016-5360-reqdeny.patch)
 
 md5sums=('5290f278c04e682e42ab71fed26fc082'
          '02241a8ca257d12f7eb131e2d7da3f3b'
-         'c4b4fba82b6f33270ed57514ed3f53e8')
+         'c4b4fba82b6f33270ed57514ed3f53e8'
+         '24c814e197627f30b41f89ae10b8520f')
 
 prepare() {
   cd haproxy-$pkgver
   sed -i 's:/usr/sbin/haproxy:/usr/bin/haproxy:' src/haproxy-systemd-wrapper.c
   patch -p1 -i "$srcdir"/gcc6-fix.patch
+  patch -p1 -i "$srcdir"/CVE-2016-5360-reqdeny.patch
 }
 
 build() {



More information about the arch-commits mailing list