summaryrefslogtreecommitdiff
blob: 51f974e6a4a4251b2ea72310cc8d9e7e60fad5bd (plain)
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
Author: jorton
Date: Mon Jul 14 20:34:32 2014
New Revision: 1610515

URL: http://svn.apache.org/r1610515
Log:
Merge 1610491 from trunk:

SECURITY (CVE-2014-0226): 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.

Reviewed by: trawick, jorton, covener
Submitted by: jorton, trawick, covener

Modified:
    httpd/httpd/branches/2.2.x/   (props changed)
    httpd/httpd/branches/2.2.x/include/ap_mmn.h
    httpd/httpd/branches/2.2.x/include/scoreboard.h
    httpd/httpd/branches/2.2.x/modules/generators/mod_status.c
    httpd/httpd/branches/2.2.x/server/scoreboard.c

Propchange: httpd/httpd/branches/2.2.x/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk:r1610491

Modified: httpd/httpd/branches/2.2.x/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/include/ap_mmn.h?rev=1610515&r1=1610514&r2=1610515&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/include/ap_mmn.h (original)
+++ httpd/httpd/branches/2.2.x/include/ap_mmn.h Mon Jul 14 20:34:32 2014
@@ -151,6 +151,7 @@
  * 20051115.31 (2.2.23) Add forcerecovery to proxy_balancer_shared struct
  * 20051115.32 (2.2.24) Add ap_get_exec_line
  * 20051115.33 (2.2.24) Add ap_pregsub_ex()
+ * 20051115.34 (2.2.28) Add ap_copy_scoreboard_worker()
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */
@@ -158,7 +159,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20051115
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 33                    /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 34                    /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/branches/2.2.x/include/scoreboard.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/include/scoreboard.h?rev=1610515&r1=1610514&r2=1610515&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/include/scoreboard.h (original)
+++ httpd/httpd/branches/2.2.x/include/scoreboard.h Mon Jul 14 20:34:32 2014
@@ -189,7 +189,24 @@ AP_DECLARE(int) ap_update_child_status_f
                                                     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);

Modified: httpd/httpd/branches/2.2.x/modules/generators/mod_status.c
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
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/generators/mod_status.c (original)
+++ httpd/httpd/branches/2.2.x/modules/generators/mod_status.c Mon Jul 14 20:34:32 2014
@@ -241,7 +241,7 @@ static int status_handler(request_rec *r
 #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 @@ static int status_handler(request_rec *r
         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];
 

Modified: httpd/httpd/branches/2.2.x/server/scoreboard.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/server/scoreboard.c?rev=1610515&r1=1610514&r2=1610515&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/server/scoreboard.c (original)
+++ httpd/httpd/branches/2.2.x/server/scoreboard.c Mon Jul 14 20:34:32 2014
@@ -510,6 +510,21 @@ AP_DECLARE(worker_score *) ap_get_scoreb
     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)) {