aboutsummaryrefslogtreecommitdiff
path: root/www/apache22/files/patch-CVE-2014-0226__scoreboard.c
blob: 34d159754ffc09575e890fd8ceeb22eab2ef9705 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
SECURITY: CVE-2014-0226 (cve.mitre.org)

Fix a race condition in scoreboard handling,
which could lead to a heap buffer overflow.  Thanks to Marek Kroemeke
working with HP's Zero Day Initiative for reporting this.
* include/scoreboard.h: Add ap_copy_scoreboard_worker.
* server/scoreboard.c (ap_copy_scoreboard_worker): New function.
* modules/generators/mod_status.c (status_handler): Use it.

http://svn.apache.org/viewvc?view=revision&revision=1610515

--- ./include/scoreboard.h.orig	2007-12-08 17:59:08.000000000 +0100
+++ ./include/scoreboard.h	2014-07-24 21:07:40.000000000 +0200
@@ -189,7 +189,24 @@
                                                     int status, request_rec *r);
 void ap_time_process_request(ap_sb_handle_t *sbh, int status);
 
+/** Return a pointer to the worker_score for a given child, thread pair.
+ * @param child_num The child number.
+ * @param thread_num The thread number.
+ * @return A pointer to the worker_score structure.
+ * @deprecated This function is deprecated, use ap_copy_scoreboard_worker instead. 
+ */
 AP_DECLARE(worker_score *) ap_get_scoreboard_worker(int x, int y);
+
+/** Copy the contents of a worker's scoreboard entry.  The contents of
+ * the worker_score structure are copied verbatim into the dest
+ * structure.
+ * @param dest Output parameter.
+ * @param child_num The child number.
+ * @param thread_num The thread number.
+ */
+AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest,
+                                           int child_num, int thread_num);
+
 AP_DECLARE(process_score *) ap_get_scoreboard_process(int x);
 AP_DECLARE(global_score *) ap_get_scoreboard_global(void);
 AP_DECLARE(lb_score *) ap_get_scoreboard_lb(int lb_num);
--- ./server/scoreboard.c.orig	2012-07-24 15:46:40.000000000 +0200
+++ ./server/scoreboard.c	2014-07-24 21:07:40.000000000 +0200
@@ -510,6 +510,21 @@
     return &ap_scoreboard_image->servers[x][y];
 }
 
+AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, 
+                                           int child_num,
+                                           int thread_num)
+{
+    worker_score *ws = ap_get_scoreboard_worker(child_num, thread_num);
+
+    memcpy(dest, ws, sizeof *ws);
+
+    /* For extra safety, NUL-terminate the strings returned, though it
+     * should be true those last bytes are always zero anyway. */
+    dest->client[sizeof(dest->client) - 1] = '\0';
+    dest->request[sizeof(dest->request) - 1] = '\0';
+    dest->vhost[sizeof(dest->vhost) - 1] = '\0';
+}
+
 AP_DECLARE(process_score *) ap_get_scoreboard_process(int x)
 {
     if ((x < 0) || (server_limit < x)) {
--- ./modules/generators/mod_status.c.orig	2013-02-18 17:52:21.000000000 +0100
+++ ./modules/generators/mod_status.c	2014-07-24 21:07:40.000000000 +0200
@@ -241,7 +241,7 @@
 #endif
     int short_report;
     int no_table_report;
-    worker_score *ws_record;
+    worker_score *ws_record = apr_palloc(r->pool, sizeof *ws_record);
     process_score *ps_record;
     char *stat_buffer;
     pid_t *pid_buffer, worker_pid;
@@ -333,7 +333,7 @@
         for (j = 0; j < thread_limit; ++j) {
             int indx = (i * thread_limit) + j;
 
-            ws_record = ap_get_scoreboard_worker(i, j);
+            ap_copy_scoreboard_worker(ws_record, i, j);
             res = ws_record->status;
             stat_buffer[indx] = status_flags[res];