1 |
commit: b863adc76dbc98a303c0246c09f1038148f30451 |
2 |
Author: Lars Wendler <polynomial-c <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Jul 31 11:24:35 2014 +0000 |
4 |
Commit: Lars Wendler <polynomial-c <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Jul 31 11:24:35 2014 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/apache.git;a=commit;h=b863adc7 |
7 |
|
8 |
Added several security fixes (CVE-2014-0118, CVE-2014-0226 and CVE-2014-0231) |
9 |
|
10 |
--- |
11 |
2.2/patches/26_httpd-2.2.27-CVE-2014-0118.patch | 309 +++++++++++++++++++++ |
12 |
2.2/patches/27_httpd-2.2.27-CVE-2014-0226.patch | 137 +++++++++ |
13 |
2.2/patches/28_httpd-2.2.27-CVE-2014-0231.patch | 165 +++++++++++ |
14 |
....0-rc2.patch => 30_all_peruser_0.4.0-rc2.patch} | 2 +- |
15 |
4 files changed, 612 insertions(+), 1 deletion(-) |
16 |
|
17 |
diff --git a/2.2/patches/26_httpd-2.2.27-CVE-2014-0118.patch b/2.2/patches/26_httpd-2.2.27-CVE-2014-0118.patch |
18 |
new file mode 100644 |
19 |
index 0000000..6db06ba |
20 |
--- /dev/null |
21 |
+++ b/2.2/patches/26_httpd-2.2.27-CVE-2014-0118.patch |
22 |
@@ -0,0 +1,309 @@ |
23 |
+Author: jim |
24 |
+Date: Thu Jul 17 18:20:46 2014 |
25 |
+New Revision: 1611426 |
26 |
+ |
27 |
+URL: http://svn.apache.org/r1611426 |
28 |
+Log: |
29 |
+Merge r1610501 from trunk: |
30 |
+ |
31 |
+ *) SECURITY: CVE-2014-0118 (cve.mitre.org) |
32 |
+ mod_deflate: The DEFLATE input filter (inflates request bodies) now |
33 |
+ limits the length and compression ratio of inflated request bodies to avoid |
34 |
+ denial of sevice via highly compressed bodies. See directives |
35 |
+ DeflateInflateLimitRequestBody, DeflateInflateRatioLimit, |
36 |
+ and DeflateInflateRatioBurst. |
37 |
+ |
38 |
+Thanks to Giancarlo Pellegrino and Davide Balzarotti for reporting the issue. |
39 |
+ |
40 |
+Submitted By: ylavic, covener |
41 |
+Reviewed By: jorton, covener, jim |
42 |
+ |
43 |
+ |
44 |
+ |
45 |
+Submitted by: covener |
46 |
+Reviewed/backported by: jim |
47 |
+ |
48 |
+Modified: |
49 |
+ httpd/httpd/branches/2.2.x/ (props changed) |
50 |
+ httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c |
51 |
+ |
52 |
+Propchange: httpd/httpd/branches/2.2.x/ |
53 |
+------------------------------------------------------------------------------ |
54 |
+ Merged /httpd/httpd/trunk:r1610501 |
55 |
+ |
56 |
+Modified: httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c |
57 |
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c?rev=1611426&r1=1611425&r2=1611426&view=diff |
58 |
+============================================================================== |
59 |
+--- httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c (original) |
60 |
++++ httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c Thu Jul 17 18:20:46 2014 |
61 |
+@@ -37,6 +37,7 @@ |
62 |
+ #include "httpd.h" |
63 |
+ #include "http_config.h" |
64 |
+ #include "http_log.h" |
65 |
++#include "http_core.h" |
66 |
+ #include "apr_lib.h" |
67 |
+ #include "apr_strings.h" |
68 |
+ #include "apr_general.h" |
69 |
+@@ -51,6 +52,9 @@ |
70 |
+ static const char deflateFilterName[] = "DEFLATE"; |
71 |
+ module AP_MODULE_DECLARE_DATA deflate_module; |
72 |
+ |
73 |
++#define AP_INFLATE_RATIO_LIMIT 200 |
74 |
++#define AP_INFLATE_RATIO_BURST 3 |
75 |
++ |
76 |
+ typedef struct deflate_filter_config_t |
77 |
+ { |
78 |
+ int windowSize; |
79 |
+@@ -62,6 +66,12 @@ typedef struct deflate_filter_config_t |
80 |
+ char *note_output_name; |
81 |
+ } deflate_filter_config; |
82 |
+ |
83 |
++typedef struct deflate_dirconf_t { |
84 |
++ apr_off_t inflate_limit; |
85 |
++ int ratio_limit, |
86 |
++ ratio_burst; |
87 |
++} deflate_dirconf_t; |
88 |
++ |
89 |
+ /* RFC 1952 Section 2.3 defines the gzip header: |
90 |
+ * |
91 |
+ * +---+---+---+---+---+---+---+---+---+---+ |
92 |
+@@ -193,6 +203,14 @@ static void *create_deflate_server_confi |
93 |
+ return c; |
94 |
+ } |
95 |
+ |
96 |
++static void *create_deflate_dirconf(apr_pool_t *p, char *dummy) |
97 |
++{ |
98 |
++ deflate_dirconf_t *dc = apr_pcalloc(p, sizeof(*dc)); |
99 |
++ dc->ratio_limit = AP_INFLATE_RATIO_LIMIT; |
100 |
++ dc->ratio_burst = AP_INFLATE_RATIO_BURST; |
101 |
++ return dc; |
102 |
++} |
103 |
++ |
104 |
+ static const char *deflate_set_window_size(cmd_parms *cmd, void *dummy, |
105 |
+ const char *arg) |
106 |
+ { |
107 |
+@@ -284,6 +302,55 @@ static const char *deflate_set_compressi |
108 |
+ return NULL; |
109 |
+ } |
110 |
+ |
111 |
++ |
112 |
++static const char *deflate_set_inflate_limit(cmd_parms *cmd, void *dirconf, |
113 |
++ const char *arg) |
114 |
++{ |
115 |
++ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; |
116 |
++ char *errp; |
117 |
++ |
118 |
++ if (APR_SUCCESS != apr_strtoff(&dc->inflate_limit, arg, &errp, 10)) { |
119 |
++ return "DeflateInflateLimitRequestBody is not parsable."; |
120 |
++ } |
121 |
++ if (*errp || dc->inflate_limit < 0) { |
122 |
++ return "DeflateInflateLimitRequestBody requires a non-negative integer."; |
123 |
++ } |
124 |
++ |
125 |
++ return NULL; |
126 |
++} |
127 |
++ |
128 |
++static const char *deflate_set_inflate_ratio_limit(cmd_parms *cmd, |
129 |
++ void *dirconf, |
130 |
++ const char *arg) |
131 |
++{ |
132 |
++ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; |
133 |
++ int i; |
134 |
++ |
135 |
++ i = atoi(arg); |
136 |
++ if (i <= 0) |
137 |
++ return "DeflateInflateRatioLimit must be positive"; |
138 |
++ |
139 |
++ dc->ratio_limit = i; |
140 |
++ |
141 |
++ return NULL; |
142 |
++} |
143 |
++ |
144 |
++static const char *deflate_set_inflate_ratio_burst(cmd_parms *cmd, |
145 |
++ void *dirconf, |
146 |
++ const char *arg) |
147 |
++{ |
148 |
++ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; |
149 |
++ int i; |
150 |
++ |
151 |
++ i = atoi(arg); |
152 |
++ if (i <= 0) |
153 |
++ return "DeflateInflateRatioBurst must be positive"; |
154 |
++ |
155 |
++ dc->ratio_burst = i; |
156 |
++ |
157 |
++ return NULL; |
158 |
++} |
159 |
++ |
160 |
+ typedef struct deflate_ctx_t |
161 |
+ { |
162 |
+ z_stream stream; |
163 |
+@@ -294,8 +361,26 @@ typedef struct deflate_ctx_t |
164 |
+ unsigned char *validation_buffer; |
165 |
+ apr_size_t validation_buffer_length; |
166 |
+ int inflate_init; |
167 |
++ int ratio_hits; |
168 |
++ apr_off_t inflate_total; |
169 |
+ } deflate_ctx; |
170 |
+ |
171 |
++/* Check whether the (inflate) ratio exceeds the configured limit/burst. */ |
172 |
++static int check_ratio(request_rec *r, deflate_ctx *ctx, |
173 |
++ const deflate_dirconf_t *dc) |
174 |
++{ |
175 |
++ if (ctx->stream.total_in) { |
176 |
++ int ratio = ctx->stream.total_out / ctx->stream.total_in; |
177 |
++ if (ratio < dc->ratio_limit) { |
178 |
++ ctx->ratio_hits = 0; |
179 |
++ } |
180 |
++ else if (++ctx->ratio_hits > dc->ratio_burst) { |
181 |
++ return 0; |
182 |
++ } |
183 |
++ } |
184 |
++ return 1; |
185 |
++} |
186 |
++ |
187 |
+ /* Number of validation bytes (CRC and length) after the compressed data */ |
188 |
+ #define VALIDATION_SIZE 8 |
189 |
+ /* Do not update ctx->crc, see comment in flush_libz_buffer */ |
190 |
+@@ -744,6 +829,8 @@ static apr_status_t deflate_in_filter(ap |
191 |
+ int zRC; |
192 |
+ apr_status_t rv; |
193 |
+ deflate_filter_config *c; |
194 |
++ deflate_dirconf_t *dc; |
195 |
++ apr_off_t inflate_limit; |
196 |
+ |
197 |
+ /* just get out of the way of things we don't want. */ |
198 |
+ if (mode != AP_MODE_READBYTES) { |
199 |
+@@ -751,6 +838,7 @@ static apr_status_t deflate_in_filter(ap |
200 |
+ } |
201 |
+ |
202 |
+ c = ap_get_module_config(r->server->module_config, &deflate_module); |
203 |
++ dc = ap_get_module_config(r->per_dir_config, &deflate_module); |
204 |
+ |
205 |
+ if (!ctx) { |
206 |
+ char deflate_hdr[10]; |
207 |
+@@ -803,11 +891,13 @@ static apr_status_t deflate_in_filter(ap |
208 |
+ if (len != 10 || |
209 |
+ deflate_hdr[0] != deflate_magic[0] || |
210 |
+ deflate_hdr[1] != deflate_magic[1]) { |
211 |
++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Failed to inflate input: wrong/partial magic bytes"); |
212 |
+ return APR_EGENERAL; |
213 |
+ } |
214 |
+ |
215 |
+ /* We can't handle flags for now. */ |
216 |
+ if (deflate_hdr[3] != 0) { |
217 |
++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Failed to inflate input: cannot handle deflate flags"); |
218 |
+ return APR_EGENERAL; |
219 |
+ } |
220 |
+ |
221 |
+@@ -831,6 +921,12 @@ static apr_status_t deflate_in_filter(ap |
222 |
+ apr_brigade_cleanup(ctx->bb); |
223 |
+ } |
224 |
+ |
225 |
++ inflate_limit = dc->inflate_limit; |
226 |
++ if (inflate_limit == 0) { |
227 |
++ /* The core is checking the deflated body, we'll check the inflated */ |
228 |
++ inflate_limit = ap_get_limit_req_body(f->r); |
229 |
++ } |
230 |
++ |
231 |
+ if (APR_BRIGADE_EMPTY(ctx->proc_bb)) { |
232 |
+ rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes); |
233 |
+ |
234 |
+@@ -863,6 +959,17 @@ static apr_status_t deflate_in_filter(ap |
235 |
+ |
236 |
+ ctx->stream.next_out = ctx->buffer; |
237 |
+ len = c->bufferSize - ctx->stream.avail_out; |
238 |
++ |
239 |
++ ctx->inflate_total += len; |
240 |
++ if (inflate_limit && ctx->inflate_total > inflate_limit) { |
241 |
++ inflateEnd(&ctx->stream); |
242 |
++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, |
243 |
++ "Inflated content length of %" APR_OFF_T_FMT |
244 |
++ " is larger than the configured limit" |
245 |
++ " of %" APR_OFF_T_FMT, |
246 |
++ ctx->inflate_total, inflate_limit); |
247 |
++ return APR_ENOSPC; |
248 |
++ } |
249 |
+ |
250 |
+ ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); |
251 |
+ tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, |
252 |
+@@ -891,6 +998,26 @@ static apr_status_t deflate_in_filter(ap |
253 |
+ ctx->stream.next_out = ctx->buffer; |
254 |
+ len = c->bufferSize - ctx->stream.avail_out; |
255 |
+ |
256 |
++ ctx->inflate_total += len; |
257 |
++ if (inflate_limit && ctx->inflate_total > inflate_limit) { |
258 |
++ inflateEnd(&ctx->stream); |
259 |
++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, |
260 |
++ "Inflated content length of %" APR_OFF_T_FMT |
261 |
++ " is larger than the configured limit" |
262 |
++ " of %" APR_OFF_T_FMT, |
263 |
++ ctx->inflate_total, inflate_limit); |
264 |
++ return APR_ENOSPC; |
265 |
++ } |
266 |
++ |
267 |
++ if (!check_ratio(r, ctx, dc)) { |
268 |
++ inflateEnd(&ctx->stream); |
269 |
++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, |
270 |
++ "Inflated content ratio is larger than the " |
271 |
++ "configured limit %i by %i time(s)", |
272 |
++ dc->ratio_limit, dc->ratio_burst); |
273 |
++ return APR_EINVAL; |
274 |
++ } |
275 |
++ |
276 |
+ ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); |
277 |
+ tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, |
278 |
+ NULL, f->c->bucket_alloc); |
279 |
+@@ -1003,6 +1130,7 @@ static apr_status_t inflate_out_filter(a |
280 |
+ int zRC; |
281 |
+ apr_status_t rv; |
282 |
+ deflate_filter_config *c; |
283 |
++ deflate_dirconf_t *dc; |
284 |
+ |
285 |
+ /* Do nothing if asked to filter nothing. */ |
286 |
+ if (APR_BRIGADE_EMPTY(bb)) { |
287 |
+@@ -1010,6 +1138,7 @@ static apr_status_t inflate_out_filter(a |
288 |
+ } |
289 |
+ |
290 |
+ c = ap_get_module_config(r->server->module_config, &deflate_module); |
291 |
++ dc = ap_get_module_config(r->per_dir_config, &deflate_module); |
292 |
+ |
293 |
+ if (!ctx) { |
294 |
+ |
295 |
+@@ -1272,6 +1401,14 @@ static apr_status_t inflate_out_filter(a |
296 |
+ while (ctx->stream.avail_in != 0) { |
297 |
+ if (ctx->stream.avail_out == 0) { |
298 |
+ |
299 |
++ if (!check_ratio(r, ctx, dc)) { |
300 |
++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, |
301 |
++ "Inflated content ratio is larger than the " |
302 |
++ "configured limit %i by %i time(s)", |
303 |
++ dc->ratio_limit, dc->ratio_burst); |
304 |
++ return APR_EINVAL; |
305 |
++ } |
306 |
++ |
307 |
+ ctx->stream.next_out = ctx->buffer; |
308 |
+ len = c->bufferSize - ctx->stream.avail_out; |
309 |
+ |
310 |
+@@ -1346,12 +1483,20 @@ static const command_rec deflate_filter_ |
311 |
+ "Set the Deflate Memory Level (1-9)"), |
312 |
+ AP_INIT_TAKE1("DeflateCompressionLevel", deflate_set_compressionlevel, NULL, RSRC_CONF, |
313 |
+ "Set the Deflate Compression Level (1-9)"), |
314 |
++ AP_INIT_TAKE1("DeflateInflateLimitRequestBody", deflate_set_inflate_limit, NULL, OR_ALL, |
315 |
++ "Set a limit on size of inflated input"), |
316 |
++ AP_INIT_TAKE1("DeflateInflateRatioLimit", deflate_set_inflate_ratio_limit, NULL, OR_ALL, |
317 |
++ "Set the inflate ratio limit above which inflation is " |
318 |
++ "aborted (default: " APR_STRINGIFY(AP_INFLATE_RATIO_LIMIT) ")"), |
319 |
++ AP_INIT_TAKE1("DeflateInflateRatioBurst", deflate_set_inflate_ratio_burst, NULL, OR_ALL, |
320 |
++ "Set the maximum number of following inflate ratios above limit " |
321 |
++ "(default: " APR_STRINGIFY(AP_INFLATE_RATIO_BURST) ")"), |
322 |
+ {NULL} |
323 |
+ }; |
324 |
+ |
325 |
+ module AP_MODULE_DECLARE_DATA deflate_module = { |
326 |
+ STANDARD20_MODULE_STUFF, |
327 |
+- NULL, /* dir config creater */ |
328 |
++ create_deflate_dirconf, /* dir config creater */ |
329 |
+ NULL, /* dir merger --- default is to override */ |
330 |
+ create_deflate_server_config, /* server config */ |
331 |
+ NULL, /* merge server config */ |
332 |
|
333 |
diff --git a/2.2/patches/27_httpd-2.2.27-CVE-2014-0226.patch b/2.2/patches/27_httpd-2.2.27-CVE-2014-0226.patch |
334 |
new file mode 100644 |
335 |
index 0000000..51f974e |
336 |
--- /dev/null |
337 |
+++ b/2.2/patches/27_httpd-2.2.27-CVE-2014-0226.patch |
338 |
@@ -0,0 +1,137 @@ |
339 |
+Author: jorton |
340 |
+Date: Mon Jul 14 20:34:32 2014 |
341 |
+New Revision: 1610515 |
342 |
+ |
343 |
+URL: http://svn.apache.org/r1610515 |
344 |
+Log: |
345 |
+Merge 1610491 from trunk: |
346 |
+ |
347 |
+SECURITY (CVE-2014-0226): Fix a race condition in scoreboard handling, |
348 |
+which could lead to a heap buffer overflow. Thanks to Marek Kroemeke |
349 |
+working with HP's Zero Day Initiative for reporting this. |
350 |
+ |
351 |
+* include/scoreboard.h: Add ap_copy_scoreboard_worker. |
352 |
+ |
353 |
+* server/scoreboard.c (ap_copy_scoreboard_worker): New function. |
354 |
+ |
355 |
+* modules/generators/mod_status.c (status_handler): Use it. |
356 |
+ |
357 |
+Reviewed by: trawick, jorton, covener |
358 |
+Submitted by: jorton, trawick, covener |
359 |
+ |
360 |
+Modified: |
361 |
+ httpd/httpd/branches/2.2.x/ (props changed) |
362 |
+ httpd/httpd/branches/2.2.x/include/ap_mmn.h |
363 |
+ httpd/httpd/branches/2.2.x/include/scoreboard.h |
364 |
+ httpd/httpd/branches/2.2.x/modules/generators/mod_status.c |
365 |
+ httpd/httpd/branches/2.2.x/server/scoreboard.c |
366 |
+ |
367 |
+Propchange: httpd/httpd/branches/2.2.x/ |
368 |
+------------------------------------------------------------------------------ |
369 |
+ Merged /httpd/httpd/trunk:r1610491 |
370 |
+ |
371 |
+Modified: httpd/httpd/branches/2.2.x/include/ap_mmn.h |
372 |
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/include/ap_mmn.h?rev=1610515&r1=1610514&r2=1610515&view=diff |
373 |
+============================================================================== |
374 |
+--- httpd/httpd/branches/2.2.x/include/ap_mmn.h (original) |
375 |
++++ httpd/httpd/branches/2.2.x/include/ap_mmn.h Mon Jul 14 20:34:32 2014 |
376 |
+@@ -151,6 +151,7 @@ |
377 |
+ * 20051115.31 (2.2.23) Add forcerecovery to proxy_balancer_shared struct |
378 |
+ * 20051115.32 (2.2.24) Add ap_get_exec_line |
379 |
+ * 20051115.33 (2.2.24) Add ap_pregsub_ex() |
380 |
++ * 20051115.34 (2.2.28) Add ap_copy_scoreboard_worker() |
381 |
+ */ |
382 |
+ |
383 |
+ #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ |
384 |
+@@ -158,7 +159,7 @@ |
385 |
+ #ifndef MODULE_MAGIC_NUMBER_MAJOR |
386 |
+ #define MODULE_MAGIC_NUMBER_MAJOR 20051115 |
387 |
+ #endif |
388 |
+-#define MODULE_MAGIC_NUMBER_MINOR 33 /* 0...n */ |
389 |
++#define MODULE_MAGIC_NUMBER_MINOR 34 /* 0...n */ |
390 |
+ |
391 |
+ /** |
392 |
+ * Determine if the server's current MODULE_MAGIC_NUMBER is at least a |
393 |
+ |
394 |
+Modified: httpd/httpd/branches/2.2.x/include/scoreboard.h |
395 |
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/include/scoreboard.h?rev=1610515&r1=1610514&r2=1610515&view=diff |
396 |
+============================================================================== |
397 |
+--- httpd/httpd/branches/2.2.x/include/scoreboard.h (original) |
398 |
++++ httpd/httpd/branches/2.2.x/include/scoreboard.h Mon Jul 14 20:34:32 2014 |
399 |
+@@ -189,7 +189,24 @@ AP_DECLARE(int) ap_update_child_status_f |
400 |
+ int status, request_rec *r); |
401 |
+ void ap_time_process_request(ap_sb_handle_t *sbh, int status); |
402 |
+ |
403 |
++/** Return a pointer to the worker_score for a given child, thread pair. |
404 |
++ * @param child_num The child number. |
405 |
++ * @param thread_num The thread number. |
406 |
++ * @return A pointer to the worker_score structure. |
407 |
++ * @deprecated This function is deprecated, use ap_copy_scoreboard_worker instead. |
408 |
++ */ |
409 |
+ AP_DECLARE(worker_score *) ap_get_scoreboard_worker(int x, int y); |
410 |
++ |
411 |
++/** Copy the contents of a worker's scoreboard entry. The contents of |
412 |
++ * the worker_score structure are copied verbatim into the dest |
413 |
++ * structure. |
414 |
++ * @param dest Output parameter. |
415 |
++ * @param child_num The child number. |
416 |
++ * @param thread_num The thread number. |
417 |
++ */ |
418 |
++AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, |
419 |
++ int child_num, int thread_num); |
420 |
++ |
421 |
+ AP_DECLARE(process_score *) ap_get_scoreboard_process(int x); |
422 |
+ AP_DECLARE(global_score *) ap_get_scoreboard_global(void); |
423 |
+ AP_DECLARE(lb_score *) ap_get_scoreboard_lb(int lb_num); |
424 |
+ |
425 |
+Modified: httpd/httpd/branches/2.2.x/modules/generators/mod_status.c |
426 |
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/generators/mod_status.c?rev=1610515&r1=1610514&r2=1610515&view=diff |
427 |
+============================================================================== |
428 |
+--- httpd/httpd/branches/2.2.x/modules/generators/mod_status.c (original) |
429 |
++++ httpd/httpd/branches/2.2.x/modules/generators/mod_status.c Mon Jul 14 20:34:32 2014 |
430 |
+@@ -241,7 +241,7 @@ static int status_handler(request_rec *r |
431 |
+ #endif |
432 |
+ int short_report; |
433 |
+ int no_table_report; |
434 |
+- worker_score *ws_record; |
435 |
++ worker_score *ws_record = apr_palloc(r->pool, sizeof *ws_record); |
436 |
+ process_score *ps_record; |
437 |
+ char *stat_buffer; |
438 |
+ pid_t *pid_buffer, worker_pid; |
439 |
+@@ -333,7 +333,7 @@ static int status_handler(request_rec *r |
440 |
+ for (j = 0; j < thread_limit; ++j) { |
441 |
+ int indx = (i * thread_limit) + j; |
442 |
+ |
443 |
+- ws_record = ap_get_scoreboard_worker(i, j); |
444 |
++ ap_copy_scoreboard_worker(ws_record, i, j); |
445 |
+ res = ws_record->status; |
446 |
+ stat_buffer[indx] = status_flags[res]; |
447 |
+ |
448 |
+ |
449 |
+Modified: httpd/httpd/branches/2.2.x/server/scoreboard.c |
450 |
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/server/scoreboard.c?rev=1610515&r1=1610514&r2=1610515&view=diff |
451 |
+============================================================================== |
452 |
+--- httpd/httpd/branches/2.2.x/server/scoreboard.c (original) |
453 |
++++ httpd/httpd/branches/2.2.x/server/scoreboard.c Mon Jul 14 20:34:32 2014 |
454 |
+@@ -510,6 +510,21 @@ AP_DECLARE(worker_score *) ap_get_scoreb |
455 |
+ return &ap_scoreboard_image->servers[x][y]; |
456 |
+ } |
457 |
+ |
458 |
++AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, |
459 |
++ int child_num, |
460 |
++ int thread_num) |
461 |
++{ |
462 |
++ worker_score *ws = ap_get_scoreboard_worker(child_num, thread_num); |
463 |
++ |
464 |
++ memcpy(dest, ws, sizeof *ws); |
465 |
++ |
466 |
++ /* For extra safety, NUL-terminate the strings returned, though it |
467 |
++ * should be true those last bytes are always zero anyway. */ |
468 |
++ dest->client[sizeof(dest->client) - 1] = '\0'; |
469 |
++ dest->request[sizeof(dest->request) - 1] = '\0'; |
470 |
++ dest->vhost[sizeof(dest->vhost) - 1] = '\0'; |
471 |
++} |
472 |
++ |
473 |
+ AP_DECLARE(process_score *) ap_get_scoreboard_process(int x) |
474 |
+ { |
475 |
+ if ((x < 0) || (server_limit < x)) { |
476 |
|
477 |
diff --git a/2.2/patches/28_httpd-2.2.27-CVE-2014-0231.patch b/2.2/patches/28_httpd-2.2.27-CVE-2014-0231.patch |
478 |
new file mode 100644 |
479 |
index 0000000..e7911e0 |
480 |
--- /dev/null |
481 |
+++ b/2.2/patches/28_httpd-2.2.27-CVE-2014-0231.patch |
482 |
@@ -0,0 +1,165 @@ |
483 |
+Author: wrowe |
484 |
+Date: Wed Jul 16 20:56:51 2014 |
485 |
+New Revision: 1611185 |
486 |
+ |
487 |
+URL: http://svn.apache.org/r1611185 |
488 |
+Log: |
489 |
+SECURITY: CVE-2014-0231 |
490 |
+ |
491 |
+ mod_cgid: Fix a denial of service against CGI scripts that do |
492 |
+ not consume stdin that could lead to lingering HTTPD child processes |
493 |
+ filling up the scoreboard and eventually hanging the server. |
494 |
+ |
495 |
+Submitted by: Rainer Jung, Eric Covener, Yann Ylavic |
496 |
+Backports: r1610509, r1535125 |
497 |
+Reviewed by: covener, trawick, ylavic |
498 |
+ |
499 |
+Modified: |
500 |
+ httpd/httpd/branches/2.2.x/modules/generators/mod_cgid.c |
501 |
+ |
502 |
+Modified: httpd/httpd/branches/2.2.x/modules/generators/mod_cgid.c |
503 |
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/generators/mod_cgid.c?rev=1611185&r1=1611184&r2=1611185&view=diff |
504 |
+============================================================================== |
505 |
+--- httpd/httpd/branches/2.2.x/modules/generators/mod_cgid.c (original) |
506 |
++++ httpd/httpd/branches/2.2.x/modules/generators/mod_cgid.c Wed Jul 16 20:56:51 2014 |
507 |
+@@ -93,6 +93,10 @@ static const char *sockname; |
508 |
+ static pid_t parent_pid; |
509 |
+ static ap_unix_identity_t empty_ugid = { (uid_t)-1, (gid_t)-1, -1 }; |
510 |
+ |
511 |
++typedef struct { |
512 |
++ apr_interval_time_t timeout; |
513 |
++} cgid_dirconf; |
514 |
++ |
515 |
+ /* The APR other-child API doesn't tell us how the daemon exited |
516 |
+ * (SIGSEGV vs. exit(1)). The other-child maintenance function |
517 |
+ * needs to decide whether to restart the daemon after a failure |
518 |
+@@ -934,7 +938,14 @@ static void *merge_cgid_config(apr_pool_ |
519 |
+ return overrides->logname ? overrides : base; |
520 |
+ } |
521 |
+ |
522 |
++static void *create_cgid_dirconf(apr_pool_t *p, char *dummy) |
523 |
++{ |
524 |
++ cgid_dirconf *c = (cgid_dirconf *) apr_pcalloc(p, sizeof(cgid_dirconf)); |
525 |
++ return c; |
526 |
++} |
527 |
++ |
528 |
+ static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg) |
529 |
++ |
530 |
+ { |
531 |
+ server_rec *s = cmd->server; |
532 |
+ cgid_server_conf *conf = ap_get_module_config(s->module_config, |
533 |
+@@ -987,7 +998,16 @@ static const char *set_script_socket(cmd |
534 |
+ |
535 |
+ return NULL; |
536 |
+ } |
537 |
++static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg) |
538 |
++{ |
539 |
++ cgid_dirconf *dc = dummy; |
540 |
+ |
541 |
++ if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) { |
542 |
++ return "CGIDScriptTimeout has wrong format"; |
543 |
++ } |
544 |
++ |
545 |
++ return NULL; |
546 |
++} |
547 |
+ static const command_rec cgid_cmds[] = |
548 |
+ { |
549 |
+ AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF, |
550 |
+@@ -999,6 +1019,10 @@ static const command_rec cgid_cmds[] = |
551 |
+ AP_INIT_TAKE1("ScriptSock", set_script_socket, NULL, RSRC_CONF, |
552 |
+ "the name of the socket to use for communication with " |
553 |
+ "the cgi daemon."), |
554 |
++ AP_INIT_TAKE1("CGIDScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF, |
555 |
++ "The amount of time to wait between successful reads from " |
556 |
++ "the CGI script, in seconds."), |
557 |
++ |
558 |
+ {NULL} |
559 |
+ }; |
560 |
+ |
561 |
+@@ -1335,11 +1359,15 @@ static int cgid_handler(request_rec *r) |
562 |
+ apr_file_t *tempsock; |
563 |
+ struct cleanup_script_info *info; |
564 |
+ apr_status_t rv; |
565 |
++ cgid_dirconf *dc; |
566 |
+ |
567 |
+ if (strcmp(r->handler,CGI_MAGIC_TYPE) && strcmp(r->handler,"cgi-script")) |
568 |
+ return DECLINED; |
569 |
+ |
570 |
+ conf = ap_get_module_config(r->server->module_config, &cgid_module); |
571 |
++ dc = ap_get_module_config(r->per_dir_config, &cgid_module); |
572 |
++ |
573 |
++ |
574 |
+ is_included = !strcmp(r->protocol, "INCLUDED"); |
575 |
+ |
576 |
+ if ((argv0 = strrchr(r->filename, '/')) != NULL) |
577 |
+@@ -1412,6 +1440,12 @@ static int cgid_handler(request_rec *r) |
578 |
+ */ |
579 |
+ |
580 |
+ apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); |
581 |
++ if (dc->timeout > 0) { |
582 |
++ apr_file_pipe_timeout_set(tempsock, dc->timeout); |
583 |
++ } |
584 |
++ else { |
585 |
++ apr_file_pipe_timeout_set(tempsock, r->server->timeout); |
586 |
++ } |
587 |
+ apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); |
588 |
+ |
589 |
+ if ((argv0 = strrchr(r->filename, '/')) != NULL) |
590 |
+@@ -1487,6 +1521,10 @@ static int cgid_handler(request_rec *r) |
591 |
+ if (rv != APR_SUCCESS) { |
592 |
+ /* silly script stopped reading, soak up remaining message */ |
593 |
+ child_stopped_reading = 1; |
594 |
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, |
595 |
++ "Error writing request body to script %s", |
596 |
++ r->filename); |
597 |
++ |
598 |
+ } |
599 |
+ } |
600 |
+ apr_brigade_cleanup(bb); |
601 |
+@@ -1577,7 +1615,13 @@ static int cgid_handler(request_rec *r) |
602 |
+ return HTTP_MOVED_TEMPORARILY; |
603 |
+ } |
604 |
+ |
605 |
+- ap_pass_brigade(r->output_filters, bb); |
606 |
++ rv = ap_pass_brigade(r->output_filters, bb); |
607 |
++ if (rv != APR_SUCCESS) { |
608 |
++ /* APLOG_ERR because the core output filter message is at error, |
609 |
++ * but doesn't know it's passing CGI output |
610 |
++ */ |
611 |
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "Failed to flush CGI output to client"); |
612 |
++ } |
613 |
+ } |
614 |
+ |
615 |
+ if (nph) { |
616 |
+@@ -1707,6 +1751,8 @@ static int include_cmd(include_ctx_t *ct |
617 |
+ request_rec *r = f->r; |
618 |
+ cgid_server_conf *conf = ap_get_module_config(r->server->module_config, |
619 |
+ &cgid_module); |
620 |
++ cgid_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgid_module); |
621 |
++ |
622 |
+ struct cleanup_script_info *info; |
623 |
+ |
624 |
+ add_ssi_vars(r); |
625 |
+@@ -1736,6 +1782,13 @@ static int include_cmd(include_ctx_t *ct |
626 |
+ * get rid of the cleanup we registered when we created the socket. |
627 |
+ */ |
628 |
+ apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); |
629 |
++ if (dc->timeout > 0) { |
630 |
++ apr_file_pipe_timeout_set(tempsock, dc->timeout); |
631 |
++ } |
632 |
++ else { |
633 |
++ apr_file_pipe_timeout_set(tempsock, r->server->timeout); |
634 |
++ } |
635 |
++ |
636 |
+ apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); |
637 |
+ |
638 |
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pipe_create(tempsock, |
639 |
+@@ -1841,7 +1894,7 @@ static void register_hook(apr_pool_t *p) |
640 |
+ |
641 |
+ module AP_MODULE_DECLARE_DATA cgid_module = { |
642 |
+ STANDARD20_MODULE_STUFF, |
643 |
+- NULL, /* dir config creater */ |
644 |
++ create_cgid_dirconf, /* dir config creater */ |
645 |
+ NULL, /* dir merger --- default is to override */ |
646 |
+ create_cgid_config, /* server config */ |
647 |
+ merge_cgid_config, /* merge server config */ |
648 |
|
649 |
diff --git a/2.2/patches/20_all_peruser_0.4.0-rc2.patch b/2.2/patches/30_all_peruser_0.4.0-rc2.patch |
650 |
similarity index 99% |
651 |
rename from 2.2/patches/20_all_peruser_0.4.0-rc2.patch |
652 |
rename to 2.2/patches/30_all_peruser_0.4.0-rc2.patch |
653 |
index 6784c78..546d94a 100644 |
654 |
--- a/2.2/patches/20_all_peruser_0.4.0-rc2.patch |
655 |
+++ b/2.2/patches/30_all_peruser_0.4.0-rc2.patch |
656 |
@@ -30,7 +30,7 @@ diff -Nur httpd-2.2.16/modules/generators/mod_status.c httpd-2.2.16-peruser/modu |
657 |
int short_report; |
658 |
int no_table_report; |
659 |
+ int peruser_stats; |
660 |
- worker_score *ws_record; |
661 |
+ worker_score *ws_record = apr_palloc(r->pool, sizeof *ws_record); |
662 |
process_score *ps_record; |
663 |
char *stat_buffer; |
664 |
@@ -268,6 +271,7 @@ |