aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/scan.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-10-30 17:09:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-10 15:11:56 -0500
commit2c706002fc147decdba2658ea48e4436faca3af2 (patch)
tree3e515fa59e6f7de045579f103cba09cd05293de7 /drivers/net/wireless/libertas/scan.c
parent9b1fbae4b242cf86a878771eb59dc600dde72ec8 (diff)
don't use net/ieee80211.h
Convert all the drivers using net/ieee80211.h to use linux/ieee80211.h. Contains a bugfix in libertas where the SSID parsing could overrun the buffer when the AP sends invalid information. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Dan Williams <dcbw@redhat.com> [airo, libertas] Acked-by: Pavel Roskin <proski@gnu.org> [orinoco] Acked-by: David Kilroy <kilroyd@googlemail.com> [orinoco] Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/scan.c')
-rw-r--r--drivers/net/wireless/libertas/scan.c77
1 files changed, 39 insertions, 38 deletions
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 5c34ac588189..93f74763a010 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -6,8 +6,8 @@
6 */ 6 */
7#include <linux/types.h> 7#include <linux/types.h>
8#include <linux/etherdevice.h> 8#include <linux/etherdevice.h>
9#include <linux/if_arp.h>
9#include <asm/unaligned.h> 10#include <asm/unaligned.h>
10
11#include <net/lib80211.h> 11#include <net/lib80211.h>
12 12
13#include "host.h" 13#include "host.h"
@@ -55,6 +55,8 @@
55//! Scan time specified in the channel TLV for each channel for active scans 55//! Scan time specified in the channel TLV for each channel for active scans
56#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100 56#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100
57 57
58#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
59
58static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy, 60static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
59 struct cmd_header *resp); 61 struct cmd_header *resp);
60 62
@@ -591,38 +593,36 @@ static int lbs_process_bss(struct bss_descriptor *bss,
591 593
592 /* process variable IE */ 594 /* process variable IE */
593 while (pos <= end - 2) { 595 while (pos <= end - 2) {
594 struct ieee80211_info_element * elem = (void *)pos; 596 if (pos + pos[1] > end) {
595
596 if (pos + elem->len > end) {
597 lbs_deb_scan("process_bss: error in processing IE, " 597 lbs_deb_scan("process_bss: error in processing IE, "
598 "bytes left < IE length\n"); 598 "bytes left < IE length\n");
599 break; 599 break;
600 } 600 }
601 601
602 switch (elem->id) { 602 switch (pos[0]) {
603 case MFIE_TYPE_SSID: 603 case WLAN_EID_SSID:
604 bss->ssid_len = min_t(int, 32, elem->len); 604 bss->ssid_len = min_t(int, IEEE80211_MAX_SSID_LEN, pos[1]);
605 memcpy(bss->ssid, elem->data, bss->ssid_len); 605 memcpy(bss->ssid, pos + 2, bss->ssid_len);
606 lbs_deb_scan("got SSID IE: '%s', len %u\n", 606 lbs_deb_scan("got SSID IE: '%s', len %u\n",
607 print_ssid(ssid, bss->ssid, bss->ssid_len), 607 print_ssid(ssid, bss->ssid, bss->ssid_len),
608 bss->ssid_len); 608 bss->ssid_len);
609 break; 609 break;
610 610
611 case MFIE_TYPE_RATES: 611 case WLAN_EID_SUPP_RATES:
612 n_basic_rates = min_t(uint8_t, MAX_RATES, elem->len); 612 n_basic_rates = min_t(uint8_t, MAX_RATES, pos[1]);
613 memcpy(bss->rates, elem->data, n_basic_rates); 613 memcpy(bss->rates, pos + 2, n_basic_rates);
614 got_basic_rates = 1; 614 got_basic_rates = 1;
615 lbs_deb_scan("got RATES IE\n"); 615 lbs_deb_scan("got RATES IE\n");
616 break; 616 break;
617 617
618 case MFIE_TYPE_FH_SET: 618 case WLAN_EID_FH_PARAMS:
619 pFH = (struct ieeetypes_fhparamset *) pos; 619 pFH = (struct ieeetypes_fhparamset *) pos;
620 memmove(&bss->phyparamset.fhparamset, pFH, 620 memmove(&bss->phyparamset.fhparamset, pFH,
621 sizeof(struct ieeetypes_fhparamset)); 621 sizeof(struct ieeetypes_fhparamset));
622 lbs_deb_scan("got FH IE\n"); 622 lbs_deb_scan("got FH IE\n");
623 break; 623 break;
624 624
625 case MFIE_TYPE_DS_SET: 625 case WLAN_EID_DS_PARAMS:
626 pDS = (struct ieeetypes_dsparamset *) pos; 626 pDS = (struct ieeetypes_dsparamset *) pos;
627 bss->channel = pDS->currentchan; 627 bss->channel = pDS->currentchan;
628 memcpy(&bss->phyparamset.dsparamset, pDS, 628 memcpy(&bss->phyparamset.dsparamset, pDS,
@@ -630,14 +630,14 @@ static int lbs_process_bss(struct bss_descriptor *bss,
630 lbs_deb_scan("got DS IE, channel %d\n", bss->channel); 630 lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
631 break; 631 break;
632 632
633 case MFIE_TYPE_CF_SET: 633 case WLAN_EID_CF_PARAMS:
634 pCF = (struct ieeetypes_cfparamset *) pos; 634 pCF = (struct ieeetypes_cfparamset *) pos;
635 memcpy(&bss->ssparamset.cfparamset, pCF, 635 memcpy(&bss->ssparamset.cfparamset, pCF,
636 sizeof(struct ieeetypes_cfparamset)); 636 sizeof(struct ieeetypes_cfparamset));
637 lbs_deb_scan("got CF IE\n"); 637 lbs_deb_scan("got CF IE\n");
638 break; 638 break;
639 639
640 case MFIE_TYPE_IBSS_SET: 640 case WLAN_EID_IBSS_PARAMS:
641 pibss = (struct ieeetypes_ibssparamset *) pos; 641 pibss = (struct ieeetypes_ibssparamset *) pos;
642 bss->atimwindow = le16_to_cpu(pibss->atimwindow); 642 bss->atimwindow = le16_to_cpu(pibss->atimwindow);
643 memmove(&bss->ssparamset.ibssparamset, pibss, 643 memmove(&bss->ssparamset.ibssparamset, pibss,
@@ -645,7 +645,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
645 lbs_deb_scan("got IBSS IE\n"); 645 lbs_deb_scan("got IBSS IE\n");
646 break; 646 break;
647 647
648 case MFIE_TYPE_COUNTRY: 648 case WLAN_EID_COUNTRY:
649 pcountryinfo = (struct ieeetypes_countryinfoset *) pos; 649 pcountryinfo = (struct ieeetypes_countryinfoset *) pos;
650 lbs_deb_scan("got COUNTRY IE\n"); 650 lbs_deb_scan("got COUNTRY IE\n");
651 if (pcountryinfo->len < sizeof(pcountryinfo->countrycode) 651 if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
@@ -662,7 +662,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
662 (int) (pcountryinfo->len + 2)); 662 (int) (pcountryinfo->len + 2));
663 break; 663 break;
664 664
665 case MFIE_TYPE_RATES_EX: 665 case WLAN_EID_EXT_SUPP_RATES:
666 /* only process extended supported rate if data rate is 666 /* only process extended supported rate if data rate is
667 * already found. Data rate IE should come before 667 * already found. Data rate IE should come before
668 * extended supported rate IE 668 * extended supported rate IE
@@ -673,50 +673,51 @@ static int lbs_process_bss(struct bss_descriptor *bss,
673 break; 673 break;
674 } 674 }
675 675
676 n_ex_rates = elem->len; 676 n_ex_rates = pos[1];
677 if (n_basic_rates + n_ex_rates > MAX_RATES) 677 if (n_basic_rates + n_ex_rates > MAX_RATES)
678 n_ex_rates = MAX_RATES - n_basic_rates; 678 n_ex_rates = MAX_RATES - n_basic_rates;
679 679
680 p = bss->rates + n_basic_rates; 680 p = bss->rates + n_basic_rates;
681 memcpy(p, elem->data, n_ex_rates); 681 memcpy(p, pos + 2, n_ex_rates);
682 break; 682 break;
683 683
684 case MFIE_TYPE_GENERIC: 684 case WLAN_EID_GENERIC:
685 if (elem->len >= 4 && 685 if (pos[1] >= 4 &&
686 elem->data[0] == 0x00 && elem->data[1] == 0x50 && 686 pos[2] == 0x00 && pos[3] == 0x50 &&
687 elem->data[2] == 0xf2 && elem->data[3] == 0x01) { 687 pos[4] == 0xf2 && pos[5] == 0x01) {
688 bss->wpa_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN); 688 bss->wpa_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN);
689 memcpy(bss->wpa_ie, elem, bss->wpa_ie_len); 689 memcpy(bss->wpa_ie, pos, bss->wpa_ie_len);
690 lbs_deb_scan("got WPA IE\n"); 690 lbs_deb_scan("got WPA IE\n");
691 lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie, elem->len); 691 lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie,
692 } else if (elem->len >= MARVELL_MESH_IE_LENGTH && 692 bss->wpa_ie_len);
693 elem->data[0] == 0x00 && elem->data[1] == 0x50 && 693 } else if (pos[1] >= MARVELL_MESH_IE_LENGTH &&
694 elem->data[2] == 0x43 && elem->data[3] == 0x04) { 694 pos[2] == 0x00 && pos[3] == 0x50 &&
695 pos[4] == 0x43 && pos[4] == 0x04) {
695 lbs_deb_scan("got mesh IE\n"); 696 lbs_deb_scan("got mesh IE\n");
696 bss->mesh = 1; 697 bss->mesh = 1;
697 } else { 698 } else {
698 lbs_deb_scan("got generic IE: %02x:%02x:%02x:%02x, len %d\n", 699 lbs_deb_scan("got generic IE: %02x:%02x:%02x:%02x, len %d\n",
699 elem->data[0], elem->data[1], 700 pos[2], pos[3],
700 elem->data[2], elem->data[3], 701 pos[4], pos[5],
701 elem->len); 702 pos[1]);
702 } 703 }
703 break; 704 break;
704 705
705 case MFIE_TYPE_RSN: 706 case WLAN_EID_RSN:
706 lbs_deb_scan("got RSN IE\n"); 707 lbs_deb_scan("got RSN IE\n");
707 bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN); 708 bss->rsn_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN);
708 memcpy(bss->rsn_ie, elem, bss->rsn_ie_len); 709 memcpy(bss->rsn_ie, pos, bss->rsn_ie_len);
709 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE", 710 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE",
710 bss->rsn_ie, elem->len); 711 bss->rsn_ie, bss->rsn_ie_len);
711 break; 712 break;
712 713
713 default: 714 default:
714 lbs_deb_scan("got IE 0x%04x, len %d\n", 715 lbs_deb_scan("got IE 0x%04x, len %d\n",
715 elem->id, elem->len); 716 pos[0], pos[1]);
716 break; 717 break;
717 } 718 }
718 719
719 pos += elem->len + 2; 720 pos += pos[1] + 2;
720 } 721 }
721 722
722 /* Timestamp */ 723 /* Timestamp */