Commit 9ebad4ab87f2ffa6eca825327721e647c7457264
Committed by
John W. Linville
1 parent
94a40c0c6b
Exists in
master
and in
39 other branches
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 |