~ubuntu-branches/ubuntu/wily/net-snmp/wily-proposed

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2012-6151.patch

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-04-08 08:17:14 UTC
  • Revision ID: package-import@ubuntu.com-20140408081714-31du0g3p3ggkwe9o
Tags: 5.7.2~dfsg-8.1ubuntu3
* SECURITY UPDATE: denial of service via AgentX subagent timeout
  - debian/patches/CVE-2012-6151.patch: track cancelled sessions in
    agent/mibgroup/agentx/{master.c,master_admin.c}, agent/snmp_agent.c,
    include/net-snmp/agent/snmp_agent.h.
  - CVE-2012-6151
* SECURITY UPDATE: denial of service when ICMP-MIB is in use
  - debian/patches/CVE-2014-2284.patch: fix ICMP mib table handling in
    agent/mibgroup/mibII/icmp.c, agent/mibgroup/mibII/kernel_linux.*.
  - CVE-2014-2284
* SECURITY UPDATE: denial of service in perl trap handler
  - debian/patches/CVE-2014-2285.patch: handle empty community string in
    perl/TrapReceiver/TrapReceiver.xs.
  - CVE-2014-2285

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Description: fix denial of service via AgentX subagent timeout
 
2
Origin: based on RedHat's backport of upstream commits. Thanks!
 
3
Origin: backport, http://sourceforge.net/p/net-snmp/code/ci/f9304c83f76202db0e684269ca1af32e43cd9db4
 
4
Origin: backport, http://sourceforge.net/p/net-snmp/code/ci/793d596838ff7cb48a73b675d62897c56c9e62df
 
5
Bug: http://sourceforge.net/p/net-snmp/bugs/2411/
 
6
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=731625
 
7
Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-6151
 
8
 
 
9
Index: net-snmp-5.7.2~dfsg/agent/mibgroup/agentx/master.c
 
10
===================================================================
 
11
--- net-snmp-5.7.2~dfsg.orig/agent/mibgroup/agentx/master.c     2012-10-09 18:28:58.000000000 -0400
 
12
+++ net-snmp-5.7.2~dfsg/agent/mibgroup/agentx/master.c  2014-03-11 09:16:01.212180291 -0400
 
13
@@ -219,7 +219,10 @@
 
14
     if (!cache) {
 
15
         DEBUGMSGTL(("agentx/master", "response too late on session %8p\n",
 
16
                     session));
 
17
-        return 0;
 
18
+        /* response is too late, free the cache */
 
19
+        if (magic)
 
20
+            netsnmp_free_delegated_cache((netsnmp_delegated_cache*) magic);
 
21
+        return 1;
 
22
     }
 
23
     requests = cache->requests;
 
24
 
 
25
@@ -606,6 +609,8 @@
 
26
     result = snmp_async_send(ax_session, pdu, agentx_got_response, cb_data);
 
27
     if (result == 0) {
 
28
         snmp_free_pdu(pdu);
 
29
+        if (cb_data)
 
30
+            netsnmp_free_delegated_cache((netsnmp_delegated_cache*) cb_data);
 
31
     }
 
32
 
 
33
     return SNMP_ERR_NOERROR;
 
34
Index: net-snmp-5.7.2~dfsg/agent/mibgroup/agentx/master_admin.c
 
35
===================================================================
 
36
--- net-snmp-5.7.2~dfsg.orig/agent/mibgroup/agentx/master_admin.c       2012-10-09 18:28:58.000000000 -0400
 
37
+++ net-snmp-5.7.2~dfsg/agent/mibgroup/agentx/master_admin.c    2014-03-11 09:15:22.624179258 -0400
 
38
@@ -133,11 +133,16 @@
 
39
          * requests, so that the delegated request will be completed and
 
40
          * further requests can be processed
 
41
          */
 
42
-        netsnmp_remove_delegated_requests_for_session(session);
 
43
+       while (netsnmp_remove_delegated_requests_for_session(session)) {
 
44
+               DEBUGMSGTL(("agentx/master", "Continue removing delegated reqests\n"));
 
45
+       }
 
46
+
 
47
         if (session->subsession != NULL) {
 
48
             netsnmp_session *subsession = session->subsession;
 
49
             for(; subsession; subsession = subsession->next) {
 
50
-                netsnmp_remove_delegated_requests_for_session(subsession);
 
51
+                while (netsnmp_remove_delegated_requests_for_session(subsession)) {
 
52
+                       DEBUGMSGTL(("agentx/master", "Continue removing delegated subsession reqests\n"));
 
53
+               }
 
54
             }
 
55
         }
 
56
                 
 
57
@@ -153,6 +158,7 @@
 
58
     for (sp = session->subsession; sp != NULL; sp = sp->next) {
 
59
 
 
60
         if (sp->sessid == sessid) {
 
61
+            netsnmp_remove_delegated_requests_for_session(sp);
 
62
             unregister_mibs_by_session(sp);
 
63
             unregister_index_by_session(sp);
 
64
             unregister_sysORTable_by_session(sp);
 
65
Index: net-snmp-5.7.2~dfsg/agent/snmp_agent.c
 
66
===================================================================
 
67
--- net-snmp-5.7.2~dfsg.orig/agent/snmp_agent.c 2012-10-09 18:28:58.000000000 -0400
 
68
+++ net-snmp-5.7.2~dfsg/agent/snmp_agent.c      2014-03-11 09:17:09.304182115 -0400
 
69
@@ -1446,6 +1446,7 @@
 
70
         netsnmp_free_cachemap(asp->cache_store);
 
71
         asp->cache_store = NULL;
 
72
     }
 
73
+    agent_snmp_session_release_cancelled(asp);
 
74
     SNMP_FREE(asp);
 
75
 }
 
76
 
 
77
@@ -1457,6 +1458,10 @@
 
78
 
 
79
     if (NULL == asp->treecache)
 
80
         return 0;
 
81
+
 
82
+    if (agent_snmp_session_is_cancelled(asp)) {
 
83
+        return 0;
 
84
+    }
 
85
     
 
86
     for (i = 0; i <= asp->treecache_num; i++) {
 
87
         for (request = asp->treecache[i].requests_begin; request;
 
88
@@ -1535,39 +1540,48 @@
 
89
 netsnmp_remove_delegated_requests_for_session(netsnmp_session *sess)
 
90
 {
 
91
     netsnmp_agent_session *asp;
 
92
-    int count = 0;
 
93
+    int total_count = 0;
 
94
     
 
95
     for (asp = agent_delegated_list; asp; asp = asp->next) {
 
96
         /*
 
97
          * check each request
 
98
          */
 
99
+        int i;
 
100
+        int count = 0;
 
101
         netsnmp_request_info *request;
 
102
-        for(request = asp->requests; request; request = request->next) {
 
103
-            /*
 
104
-             * check session
 
105
-             */
 
106
-            netsnmp_assert(NULL!=request->subtree);
 
107
-            if(request->subtree->session != sess)
 
108
-                continue;
 
109
+        for (i = 0; i <= asp->treecache_num; i++) {
 
110
+            for (request = asp->treecache[i].requests_begin; request;
 
111
+                 request = request->next) {
 
112
+                /*
 
113
+                 * check session
 
114
+                 */
 
115
+                netsnmp_assert(NULL!=request->subtree);
 
116
+                if(request->subtree->session != sess)
 
117
+                    continue;
 
118
 
 
119
-            /*
 
120
-             * matched! mark request as done
 
121
-             */
 
122
-            netsnmp_request_set_error(request, SNMP_ERR_GENERR);
 
123
-            ++count;
 
124
+                /*
 
125
+                 * matched! mark request as done
 
126
+                 */
 
127
+                netsnmp_request_set_error(request, SNMP_ERR_GENERR);
 
128
+                ++count;
 
129
+            }
 
130
+        }
 
131
+        if (count) {
 
132
+            agent_snmp_session_mark_cancelled(asp);
 
133
+            total_count += count;
 
134
         }
 
135
     }
 
136
 
 
137
     /*
 
138
      * if we found any, that request may be finished now
 
139
      */
 
140
-    if(count) {
 
141
+    if(total_count) {
 
142
         DEBUGMSGTL(("snmp_agent", "removed %d delegated request(s) for session "
 
143
-                    "%8p\n", count, sess));
 
144
-        netsnmp_check_outstanding_agent_requests();
 
145
+                    "%8p\n", total_count, sess));
 
146
+        netsnmp_check_delegated_requests();
 
147
     }
 
148
     
 
149
-    return count;
 
150
+    return total_count;
 
151
 }
 
152
 
 
153
 int
 
154
@@ -2739,19 +2753,11 @@
 
155
     return final_status;
 
156
 }
 
157
 
 
158
-/*
 
159
- * loop through our sessions known delegated sessions and check to see
 
160
- * if they've completed yet. If there are no more delegated sessions,
 
161
- * check for and process any queued requests
 
162
- */
 
163
 void
 
164
-netsnmp_check_outstanding_agent_requests(void)
 
165
+netsnmp_check_delegated_requests(void)
 
166
 {
 
167
     netsnmp_agent_session *asp, *prev_asp = NULL, *next_asp = NULL;
 
168
 
 
169
-    /*
 
170
-     * deal with delegated requests
 
171
-     */
 
172
     for (asp = agent_delegated_list; asp; asp = next_asp) {
 
173
         next_asp = asp->next;   /* save in case we clean up asp */
 
174
         if (!netsnmp_check_for_delegated(asp)) {
 
175
@@ -2790,6 +2796,22 @@
 
176
             prev_asp = asp;
 
177
         }
 
178
     }
 
179
+}
 
180
+
 
181
+/*
 
182
+ * loop through our sessions known delegated sessions and check to see
 
183
+ * if they've completed yet. If there are no more delegated sessions,
 
184
+ * check for and process any queued requests
 
185
+ */
 
186
+void
 
187
+netsnmp_check_outstanding_agent_requests(void)
 
188
+{
 
189
+    netsnmp_agent_session *asp;
 
190
+
 
191
+    /*
 
192
+     * deal with delegated requests
 
193
+     */
 
194
+    netsnmp_check_delegated_requests();
 
195
 
 
196
     /*
 
197
      * if we are processing a set and there are more delegated
 
198
@@ -2819,7 +2841,8 @@
 
199
 
 
200
             netsnmp_processing_set = netsnmp_agent_queued_list;
 
201
             DEBUGMSGTL(("snmp_agent", "SET request remains queued while "
 
202
-                        "delegated requests finish, asp = %8p\n", asp));
 
203
+                        "delegated requests finish, asp = %8p\n",
 
204
+                        agent_delegated_list));
 
205
             break;
 
206
         }
 
207
 #endif /* NETSNMP_NO_WRITE_SUPPORT */
 
208
@@ -2880,6 +2903,10 @@
 
209
     case SNMP_MSG_GETBULK:
 
210
     case SNMP_MSG_GETNEXT:
 
211
         netsnmp_check_all_requests_status(asp, 0);
 
212
+        if (agent_snmp_session_is_cancelled(asp)) {
 
213
+            DEBUGMSGTL(("snmp_agent","canceling next walk for asp %p\n", asp));
 
214
+            break;
 
215
+        }
 
216
         handle_getnext_loop(asp);
 
217
         if (netsnmp_check_for_delegated(asp) &&
 
218
             netsnmp_check_transaction_id(asp->pdu->transid) !=
 
219
@@ -3836,3 +3863,71 @@
 
220
 }
 
221
 #endif /* NETSNMP_FEATURE_REMOVE_SET_ALL_REQUESTS_ERROR */
 
222
 /** @} */
 
223
+
 
224
+
 
225
+/*
 
226
+ * Ugly hack to fix bug #950602 and preserve ABI
 
227
+ * (the official patch adds netsnmp_agent_session->flags).
 
228
+ * We must create parallel database of netsnmp_agent_sessions
 
229
+ * and put cancelled requests there instead of marking
 
230
+ * netsnmp_agent_session->flags.
 
231
+ */
 
232
+static netsnmp_agent_session **cancelled_agent_snmp_sessions;
 
233
+static int cancelled_agent_snmp_sessions_count;
 
234
+static int cancelled_agent_snmp_sessions_max;
 
235
+
 
236
+int
 
237
+agent_snmp_session_mark_cancelled(netsnmp_agent_session *session)
 
238
+{
 
239
+    DEBUGMSGTL(("agent:cancelled", "Cancelling session %p\n", session));
 
240
+    if (!session)
 
241
+        return 0;
 
242
+    if (cancelled_agent_snmp_sessions_count + 1 > cancelled_agent_snmp_sessions_max) {
 
243
+        netsnmp_agent_session **aux;
 
244
+        int max = cancelled_agent_snmp_sessions_max + 10;
 
245
+        aux = realloc(cancelled_agent_snmp_sessions, sizeof(netsnmp_agent_session*) * max);
 
246
+        if (!aux)
 
247
+            return SNMP_ERR_GENERR;
 
248
+        cancelled_agent_snmp_sessions = aux;
 
249
+        cancelled_agent_snmp_sessions_max = max;
 
250
+    }
 
251
+    cancelled_agent_snmp_sessions[cancelled_agent_snmp_sessions_count] = session;
 
252
+    cancelled_agent_snmp_sessions_count++;
 
253
+    return 0;
 
254
+}
 
255
+
 
256
+int
 
257
+agent_snmp_session_is_cancelled(netsnmp_agent_session *session)
 
258
+{
 
259
+    int i;
 
260
+    for (i=0; i<cancelled_agent_snmp_sessions_count; i++)
 
261
+        if (cancelled_agent_snmp_sessions[i] == session) {
 
262
+            DEBUGMSGTL(("agent:cancelled", "session %p is cancelled\n", session));
 
263
+            return TRUE;
 
264
+    }
 
265
+    return FALSE;
 
266
+}
 
267
+
 
268
+int
 
269
+agent_snmp_session_release_cancelled(netsnmp_agent_session *session)
 
270
+{
 
271
+    int i, j;
 
272
+
 
273
+    if (!session)
 
274
+        return 0;
 
275
+
 
276
+    DEBUGMSGTL(("agent:cancelled", "Removing session %p\n", session));
 
277
+
 
278
+    /* delete the session from cancelled_agent_snmp_sessions */
 
279
+    for (i=0, j=0; j<cancelled_agent_snmp_sessions_count; i++, j++)
 
280
+        if (cancelled_agent_snmp_sessions[j] == session)
 
281
+            i--; /* don't increase i in this loop iteration */
 
282
+        else
 
283
+            cancelled_agent_snmp_sessions[i] = cancelled_agent_snmp_sessions[j];
 
284
+
 
285
+    cancelled_agent_snmp_sessions_count = i;
 
286
+
 
287
+    for (; i< cancelled_agent_snmp_sessions_max; i++)
 
288
+        cancelled_agent_snmp_sessions[i] = NULL;
 
289
+    return 0;
 
290
+}
 
291
Index: net-snmp-5.7.2~dfsg/include/net-snmp/agent/snmp_agent.h
 
292
===================================================================
 
293
--- net-snmp-5.7.2~dfsg.orig/include/net-snmp/agent/snmp_agent.h        2012-10-09 18:28:58.000000000 -0400
 
294
+++ net-snmp-5.7.2~dfsg/include/net-snmp/agent/snmp_agent.h     2014-03-11 09:15:22.628179258 -0400
 
295
@@ -240,6 +240,7 @@
 
296
     int             init_master_agent(void);
 
297
     void            shutdown_master_agent(void);
 
298
     int             agent_check_and_process(int block);
 
299
+    void            netsnmp_check_delegated_requests(void);
 
300
     void            netsnmp_check_outstanding_agent_requests(void);
 
301
 
 
302
     int             netsnmp_request_set_error(netsnmp_request_info *request,