Gentoo Archives: gentoo-commits

From: Lars Wendler <polynomial-c@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/apache:master commit in: 2.2/patches/
Date: Thu, 31 Jul 2014 11:25:27
Message-Id: 1406805875.b863adc76dbc98a303c0246c09f1038148f30451.polynomial-c@gentoo
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 @@