aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-10-14 07:41:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-15 15:57:34 -0400
commit9ebad4ab87f2ffa6eca825327721e647c7457264 (patch)
treed991c017031d7da8b58bc707809a12eef7320557 /net/wireless
parent94a40c0c6bcc47ceba12e0247c5a23fb1e6c81e4 (diff)
radiotap: fix vendor namespace parsing
There's a bug with radiotap vendor namespace parsing if you don't register for the given namespace extensions. Fix this by passing only the unknown vendor namespaces and the registered data to frontends, but not both. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/radiotap.c58
1 files changed, 32 insertions, 26 deletions
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index c774bc0f155e..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
201{ 201{
202 while (1) { 202 while (1) {
203 int hit = 0; 203 int hit = 0;
204 int pad, align, size, subns, vnslen; 204 int pad, align, size, subns;
205 uint32_t oui; 205 uint32_t oui;
206 206
207 /* if no more EXT bits, that's it */ 207 /* if no more EXT bits, that's it */
@@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
261 if (pad) 261 if (pad)
262 iterator->_arg += align - pad; 262 iterator->_arg += align - pad;
263 263
264 if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
265 int vnslen;
266
267 if ((unsigned long)iterator->_arg + size -
268 (unsigned long)iterator->_rtheader >
269 (unsigned long)iterator->_max_length)
270 return -EINVAL;
271
272 oui = (*iterator->_arg << 16) |
273 (*(iterator->_arg + 1) << 8) |
274 *(iterator->_arg + 2);
275 subns = *(iterator->_arg + 3);
276
277 find_ns(iterator, oui, subns);
278
279 vnslen = get_unaligned_le16(iterator->_arg + 4);
280 iterator->_next_ns_data = iterator->_arg + size + vnslen;
281 if (!iterator->current_namespace)
282 size += vnslen;
283 }
284
264 /* 285 /*
265 * this is what we will return to user, but we need to 286 * this is what we will return to user, but we need to
266 * move on first so next call has something fresh to test 287 * move on first so next call has something fresh to test
@@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
287 /* these special ones are valid in each bitmap word */ 308 /* these special ones are valid in each bitmap word */
288 switch (iterator->_arg_index % 32) { 309 switch (iterator->_arg_index % 32) {
289 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: 310 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
290 iterator->_bitmap_shifter >>= 1;
291 iterator->_arg_index++;
292
293 iterator->_reset_on_ext = 1; 311 iterator->_reset_on_ext = 1;
294 312
295 vnslen = get_unaligned_le16(iterator->this_arg + 4);
296 iterator->_next_ns_data = iterator->_arg + vnslen;
297 oui = (*iterator->this_arg << 16) |
298 (*(iterator->this_arg + 1) << 8) |
299 *(iterator->this_arg + 2);
300 subns = *(iterator->this_arg + 3);
301
302 find_ns(iterator, oui, subns);
303
304 iterator->is_radiotap_ns = 0; 313 iterator->is_radiotap_ns = 0;
305 /* allow parsers to show this information */ 314 /*
315 * If parser didn't register this vendor
316 * namespace with us, allow it to show it
317 * as 'raw. Do do that, set argument index
318 * to vendor namespace.
319 */
306 iterator->this_arg_index = 320 iterator->this_arg_index =
307 IEEE80211_RADIOTAP_VENDOR_NAMESPACE; 321 IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
308 iterator->this_arg_size += vnslen; 322 if (!iterator->current_namespace)
309 if ((unsigned long)iterator->this_arg + 323 hit = 1;
310 iterator->this_arg_size - 324 goto next_entry;
311 (unsigned long)iterator->_rtheader >
312 (unsigned long)(unsigned long)iterator->_max_length)
313 return -EINVAL;
314 hit = 1;
315 break;
316 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: 325 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
317 iterator->_bitmap_shifter >>= 1;
318 iterator->_arg_index++;
319
320 iterator->_reset_on_ext = 1; 326 iterator->_reset_on_ext = 1;
321 iterator->current_namespace = &radiotap_ns; 327 iterator->current_namespace = &radiotap_ns;
322 iterator->is_radiotap_ns = 1; 328 iterator->is_radiotap_ns = 1;
323 break; 329 goto next_entry;
324 case IEEE80211_RADIOTAP_EXT: 330 case IEEE80211_RADIOTAP_EXT:
325 /* 331 /*
326 * bit 31 was set, there is more 332 * bit 31 was set, there is more