Gentoo Archives: gentoo-commits

From: "Anthony G. Basile (blueness)" <blueness@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in www-servers/monkeyd/files: monkeyd-fix-DoS-headers-parser.patch
Date: Wed, 05 Jun 2013 20:45:50
Message-Id: 20130605204545.9511020081@flycatcher.gentoo.org
1 blueness 13/06/05 20:45:45
2
3 Added: monkeyd-fix-DoS-headers-parser.patch
4 Log:
5 Fix DoS bug on headers parser, bug #472400, CVE-2013-3843
6
7 (Portage version: 2.1.11.62/cvs/Linux x86_64, signed Manifest commit with key 0xF52D4BBA)
8
9 Revision Changes Path
10 1.1 www-servers/monkeyd/files/monkeyd-fix-DoS-headers-parser.patch
11
12 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/www-servers/monkeyd/files/monkeyd-fix-DoS-headers-parser.patch?rev=1.1&view=markup
13 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/www-servers/monkeyd/files/monkeyd-fix-DoS-headers-parser.patch?rev=1.1&content-type=text/plain
14
15 Index: monkeyd-fix-DoS-headers-parser.patch
16 ===================================================================
17 From 95d646e5de252bfaa8b68c39d0f48e5d82965d41 Mon Sep 17 00:00:00 2001
18 From: Eduardo Silva <edsiper@×××××.com>
19 Date: Wed, 5 Jun 2013 12:18:39 -0600
20 Subject: [PATCH] Fix #182: DoS bug on headers parser
21
22 This patch fix the root cause for a problem described in Ticket #182,
23 actually if a header is malformed like a Header Key without a value, the
24 ToC parser used to continue processing the next header line.
25
26 The solution applied is to improve the ToC generator where it adds extra
27 validations for at least one colon and forcing each header line to contain
28 a value or empty space, otherwise the server will trigger a Bad Request
29 response to the client and close the connection.
30
31 Signed-off-by: Eduardo Silva <edsiper@×××××.com>
32 ---
33 src/mk_method.c | 11 ++++++++++-
34 src/mk_request.c | 36 +++++++++++++++++++++++++++++-------
35 2 files changed, 39 insertions(+), 8 deletions(-)
36
37 diff --git a/src/mk_method.c b/src/mk_method.c
38 index 4a0698a..b35e893 100644
39 --- a/src/mk_method.c
40 +++ b/src/mk_method.c
41 @@ -45,16 +45,25 @@
42
43 long int mk_method_validate_content_length(const char *body, int body_len)
44 {
45 + int crlf;
46 struct headers_toc toc;
47 long int len;
48 mk_pointer tmp;
49
50 + crlf = mk_string_search(body, MK_CRLF, MK_STR_INSENSITIVE);
51 + if (crlf < 0) {
52 + return -1;
53 + }
54 +
55 /*
56 * obs: Table of Content (toc) is created when the full
57 * request has arrived, this function cannot be used from
58 * mk_http_pending_request().
59 */
60 - mk_request_header_toc_parse(&toc, body, body_len);
61 + if (mk_request_header_toc_parse(&toc, body + crlf + mk_crlf.len,
62 + body_len - mk_crlf.len - crlf) < 0) {
63 + return -1;
64 + }
65 tmp = mk_request_header_get(&toc,
66 mk_rh_content_length.data,
67 mk_rh_content_length.len);
68 diff --git a/src/mk_request.c b/src/mk_request.c
69 index 5c1f07e..083aba8 100644
70 --- a/src/mk_request.c
71 +++ b/src/mk_request.c
72 @@ -121,13 +121,32 @@ static void mk_request_free(struct session_request *sr)
73
74 int mk_request_header_toc_parse(struct headers_toc *toc, const char *data, int len)
75 {
76 - int i;
77 + int i = 0;
78 + int header_len;
79 + int colon;
80 + char *q;
81 char *p = (char *) data;
82 - char *l = 0;
83 + char *l = p;
84
85 toc->length = 0;
86 +
87 + if (*p == '\r') goto out;
88 for (i = 0; l < (data + len) && p && i < MK_HEADERS_TOC_LEN; i++) {
89 - l = strstr(p, MK_CRLF);
90 + if (*p == '\r') goto out;
91 +
92 + colon = -1;
93 + for (q = p; *q != '\r'; ++q) {
94 + if (*q == ':') {
95 + colon = (q - p);
96 + }
97 + }
98 +
99 + l = (q);
100 + header_len = (l - p) - mk_crlf.len;
101 + if ((colon == -1) || (header_len == colon) || (*++q != '\n')) {
102 + return -1;
103 + }
104 +
105 if (l) {
106 toc->rows[i].init = p;
107 toc->rows[i].end = l;
108 @@ -140,6 +159,7 @@ int mk_request_header_toc_parse(struct headers_toc *toc, const char *data, int l
109 }
110 }
111
112 + out:
113 return toc->length;
114 }
115
116 @@ -237,13 +257,15 @@ static int mk_request_header_process(struct session_request *sr)
117
118 /* Creating Table of Content (index) for HTTP headers */
119 sr->headers_len = sr->body.len - (prot_end + mk_crlf.len);
120 - mk_request_header_toc_parse(&sr->headers_toc, headers, sr->headers_len);
121 + if (mk_request_header_toc_parse(&sr->headers_toc, headers, sr->headers_len) < 0) {
122 + MK_TRACE("Invalid headers");
123 + return -1;
124 + }
125
126 /* Host */
127 host = mk_request_header_get(&sr->headers_toc,
128 mk_rh_host.data,
129 mk_rh_host.len);
130 -
131 if (host.data) {
132 if ((pos_sep = mk_string_char_search_r(host.data, ':', host.len)) >= 0) {
133 /* TCP port should not be higher than 65535 */
134 @@ -321,8 +343,8 @@ static int mk_request_header_process(struct session_request *sr)
135 sr->keep_alive = MK_TRUE;
136 sr->close_now = MK_FALSE;
137 }
138 - else if(mk_string_search_n(sr->connection.data, "Close",
139 - MK_STR_INSENSITIVE, sr->connection.len) >= 0) {
140 + else if (mk_string_search_n(sr->connection.data, "Close",
141 + MK_STR_INSENSITIVE, sr->connection.len) >= 0) {
142 sr->keep_alive = MK_FALSE;
143 sr->close_now = MK_TRUE;
144 }
145 --
146 1.7.4.1