Commit 9ebad4ab87f2ffa6eca825327721e647c7457264

Authored by Johannes Berg
Committed by John W. Linville
1 parent 94a40c0c6b

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>

Showing 1 changed file with 32 additions and 26 deletions Side-by-side Diff

net/wireless/radiotap.c
... ... @@ -201,7 +201,7 @@
201 201 {
202 202 while (1) {
203 203 int hit = 0;
204   - int pad, align, size, subns, vnslen;
  204 + int pad, align, size, subns;
205 205 uint32_t oui;
206 206  
207 207 /* if no more EXT bits, that's it */
... ... @@ -261,6 +261,27 @@
261 261 if (pad)
262 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 286 * this is what we will return to user, but we need to
266 287 * move on first so next call has something fresh to test
267 288  
268 289  
269 290  
270 291  
271 292  
... ... @@ -287,40 +308,25 @@
287 308 /* these special ones are valid in each bitmap word */
288 309 switch (iterator->_arg_index % 32) {
289 310 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
290   - iterator->_bitmap_shifter >>= 1;
291   - iterator->_arg_index++;
292   -
293 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 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 320 iterator->this_arg_index =
307 321 IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
308   - iterator->this_arg_size += vnslen;
309   - if ((unsigned long)iterator->this_arg +
310   - iterator->this_arg_size -
311   - (unsigned long)iterator->_rtheader >
312   - (unsigned long)(unsigned long)iterator->_max_length)
313   - return -EINVAL;
314   - hit = 1;
315   - break;
  322 + if (!iterator->current_namespace)
  323 + hit = 1;
  324 + goto next_entry;
316 325 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
317   - iterator->_bitmap_shifter >>= 1;
318   - iterator->_arg_index++;
319   -
320 326 iterator->_reset_on_ext = 1;
321 327 iterator->current_namespace = &radiotap_ns;
322 328 iterator->is_radiotap_ns = 1;
323   - break;
  329 + goto next_entry;
324 330 case IEEE80211_RADIOTAP_EXT:
325 331 /*
326 332 * bit 31 was set, there is more