aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2007-12-20 17:18:35 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:02 -0500
commit56d81bd3c76f3ac917a560c662a696aa5e29b980 (patch)
tree5ee5c7ac9268ff4434d857131597169957a18e3f
parenta23ace5f226aea6c8ba04794720502b1aad1dd92 (diff)
airo: sanitize handling of CapabilityRid
Don't byteswap any fields, annotate. That has caught a bug, BTW - will be handled in the next patch. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/airo.c132
1 files changed, 69 insertions, 63 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 9b0714cea75e..e139a18c6acd 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -718,32 +718,32 @@ typedef struct {
718} APListRid; 718} APListRid;
719 719
720typedef struct { 720typedef struct {
721 u16 len; 721 __le16 len;
722 char oui[3]; 722 char oui[3];
723 char zero; 723 char zero;
724 u16 prodNum; 724 __le16 prodNum;
725 char manName[32]; 725 char manName[32];
726 char prodName[16]; 726 char prodName[16];
727 char prodVer[8]; 727 char prodVer[8];
728 char factoryAddr[ETH_ALEN]; 728 char factoryAddr[ETH_ALEN];
729 char aironetAddr[ETH_ALEN]; 729 char aironetAddr[ETH_ALEN];
730 u16 radioType; 730 __le16 radioType;
731 u16 country; 731 __le16 country;
732 char callid[ETH_ALEN]; 732 char callid[ETH_ALEN];
733 char supportedRates[8]; 733 char supportedRates[8];
734 char rxDiversity; 734 char rxDiversity;
735 char txDiversity; 735 char txDiversity;
736 u16 txPowerLevels[8]; 736 __le16 txPowerLevels[8];
737 u16 hardVer; 737 __le16 hardVer;
738 u16 hardCap; 738 __le16 hardCap;
739 u16 tempRange; 739 __le16 tempRange;
740 u16 softVer; 740 __le16 softVer;
741 u16 softSubVer; 741 __le16 softSubVer;
742 u16 interfaceVer; 742 __le16 interfaceVer;
743 u16 softCap; 743 __le16 softCap;
744 u16 bootBlockVer; 744 __le16 bootBlockVer;
745 u16 requiredHard; 745 __le16 requiredHard;
746 u16 extSoftCap; 746 __le16 extSoftCap;
747} CapabilityRid; 747} CapabilityRid;
748 748
749 749
@@ -1877,17 +1877,10 @@ static int writeAPListRid(struct airo_info*ai, APListRid *aplr, int lock) {
1877 rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock); 1877 rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
1878 return rc; 1878 return rc;
1879} 1879}
1880static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr, int lock) {
1881 int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
1882 u16 *s;
1883 1880
1884 capr->len = le16_to_cpu(capr->len); 1881static int readCapabilityRid(struct airo_info *ai, CapabilityRid *capr, int lock)
1885 capr->prodNum = le16_to_cpu(capr->prodNum); 1882{
1886 capr->radioType = le16_to_cpu(capr->radioType); 1883 return PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
1887 capr->country = le16_to_cpu(capr->country);
1888 for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)
1889 *s = le16_to_cpu(*s);
1890 return rc;
1891} 1884}
1892 1885
1893static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) 1886static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
@@ -2773,8 +2766,9 @@ static int airo_test_wpa_capable(struct airo_info *ai)
2773 if (status != SUCCESS) return 0; 2766 if (status != SUCCESS) return 0;
2774 2767
2775 /* Only firmware versions 5.30.17 or better can do WPA */ 2768 /* Only firmware versions 5.30.17 or better can do WPA */
2776 if ((cap_rid.softVer > 0x530) 2769 if (le16_to_cpu(cap_rid.softVer) > 0x530
2777 || ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 17))) { 2770 || (le16_to_cpu(cap_rid.softVer) == 0x530
2771 && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
2778 airo_print_info("", "WPA is supported."); 2772 airo_print_info("", "WPA is supported.");
2779 return 1; 2773 return 1;
2780 } 2774 }
@@ -3809,7 +3803,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3809 else { 3803 else {
3810 kfree(ai->rssi); 3804 kfree(ai->rssi);
3811 ai->rssi = NULL; 3805 ai->rssi = NULL;
3812 if (cap_rid.softCap & 8) 3806 if (cap_rid.softCap & cpu_to_le16(8))
3813 ai->config.rmode |= RXMODE_NORMALIZED_RSSI; 3807 ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3814 else 3808 else
3815 airo_print_warn(ai->dev->name, "unknown received signal " 3809 airo_print_warn(ai->dev->name, "unknown received signal "
@@ -3819,9 +3813,9 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3819 ai->config.authType = AUTH_OPEN; 3813 ai->config.authType = AUTH_OPEN;
3820 ai->config.modulation = MOD_CCK; 3814 ai->config.modulation = MOD_CCK;
3821 3815
3822 if ((cap_rid.len>=sizeof(cap_rid)) && 3816 if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
3823 (cap_rid.extSoftCap & cpu_to_le16(1)) && 3817 (cap_rid.extSoftCap & cpu_to_le16(1)) &&
3824 (micsetup(ai) == SUCCESS)) { 3818 micsetup(ai) == SUCCESS) {
3825 ai->config.opmode |= MODE_MIC; 3819 ai->config.opmode |= MODE_MIC;
3826 set_bit(FLAG_MIC_CAPABLE, &ai->flags); 3820 set_bit(FLAG_MIC_CAPABLE, &ai->flags);
3827 } 3821 }
@@ -4717,12 +4711,12 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
4717 cap_rid.prodName, 4711 cap_rid.prodName,
4718 cap_rid.manName, 4712 cap_rid.manName,
4719 cap_rid.prodVer, 4713 cap_rid.prodVer,
4720 cap_rid.radioType, 4714 le16_to_cpu(cap_rid.radioType),
4721 cap_rid.country, 4715 le16_to_cpu(cap_rid.country),
4722 cap_rid.hardVer, 4716 le16_to_cpu(cap_rid.hardVer),
4723 (int)cap_rid.softVer, 4717 le16_to_cpu(cap_rid.softVer),
4724 (int)cap_rid.softSubVer, 4718 le16_to_cpu(cap_rid.softSubVer),
4725 (int)cap_rid.bootBlockVer ); 4719 le16_to_cpu(cap_rid.bootBlockVer));
4726 data->readlen = strlen( data->rbuffer ); 4720 data->readlen = strlen( data->rbuffer );
4727 return 0; 4721 return 0;
4728} 4722}
@@ -5734,20 +5728,24 @@ static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5734{ 5728{
5735 int quality = 0; 5729 int quality = 0;
5736 5730
5737 if ((status_rid->mode & 0x3f) == 0x3f && (cap_rid->hardCap & 8)) { 5731 if ((status_rid->mode & 0x3f) != 0x3f)
5738 if (memcmp(cap_rid->prodName, "350", 3)) 5732 return 0;
5739 if (status_rid->signalQuality > 0x20) 5733
5740 quality = 0; 5734 if (!(cap_rid->hardCap & cpu_to_le16(8)))
5741 else 5735 return 0;
5742 quality = 0x20 - status_rid->signalQuality; 5736
5737 if (memcmp(cap_rid->prodName, "350", 3))
5738 if (status_rid->signalQuality > 0x20)
5739 quality = 0;
5743 else 5740 else
5744 if (status_rid->signalQuality > 0xb0) 5741 quality = 0x20 - status_rid->signalQuality;
5745 quality = 0; 5742 else
5746 else if (status_rid->signalQuality < 0x10) 5743 if (status_rid->signalQuality > 0xb0)
5747 quality = 0xa0; 5744 quality = 0;
5748 else 5745 else if (status_rid->signalQuality < 0x10)
5749 quality = 0xb0 - status_rid->signalQuality; 5746 quality = 0xa0;
5750 } 5747 else
5748 quality = 0xb0 - status_rid->signalQuality;
5751 return quality; 5749 return quality;
5752} 5750}
5753 5751
@@ -6289,6 +6287,13 @@ static int airo_get_mode(struct net_device *dev,
6289 return 0; 6287 return 0;
6290} 6288}
6291 6289
6290static inline int valid_index(CapabilityRid *p, int index)
6291{
6292 if (index < 0)
6293 return 0;
6294 return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
6295}
6296
6292/*------------------------------------------------------------------*/ 6297/*------------------------------------------------------------------*/
6293/* 6298/*
6294 * Wireless Handler : set Encryption Key 6299 * Wireless Handler : set Encryption Key
@@ -6306,7 +6311,7 @@ static int airo_set_encode(struct net_device *dev,
6306 /* Is WEP supported ? */ 6311 /* Is WEP supported ? */
6307 readCapabilityRid(local, &cap_rid, 1); 6312 readCapabilityRid(local, &cap_rid, 1);
6308 /* Older firmware doesn't support this... 6313 /* Older firmware doesn't support this...
6309 if(!(cap_rid.softCap & 2)) { 6314 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6310 return -EOPNOTSUPP; 6315 return -EOPNOTSUPP;
6311 } */ 6316 } */
6312 readConfigRid(local, 1); 6317 readConfigRid(local, 1);
@@ -6326,7 +6331,7 @@ static int airo_set_encode(struct net_device *dev,
6326 return -EINVAL; 6331 return -EINVAL;
6327 } 6332 }
6328 /* Check the index (none -> use current) */ 6333 /* Check the index (none -> use current) */
6329 if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4:1))) 6334 if (!valid_index(&cap_rid, index))
6330 index = current_index; 6335 index = current_index;
6331 /* Set the length */ 6336 /* Set the length */
6332 if (dwrq->length > MIN_KEY_SIZE) 6337 if (dwrq->length > MIN_KEY_SIZE)
@@ -6356,7 +6361,7 @@ static int airo_set_encode(struct net_device *dev,
6356 } else { 6361 } else {
6357 /* Do we want to just set the transmit key index ? */ 6362 /* Do we want to just set the transmit key index ? */
6358 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 6363 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6359 if ((index >= 0) && (index < ((cap_rid.softCap & 0x80)?4:1))) { 6364 if (valid_index(&cap_rid, index)) {
6360 set_wep_key(local, index, NULL, 0, perm, 1); 6365 set_wep_key(local, index, NULL, 0, perm, 1);
6361 } else 6366 } else
6362 /* Don't complain if only change the mode */ 6367 /* Don't complain if only change the mode */
@@ -6391,7 +6396,7 @@ static int airo_get_encode(struct net_device *dev,
6391 6396
6392 /* Is it supported ? */ 6397 /* Is it supported ? */
6393 readCapabilityRid(local, &cap_rid, 1); 6398 readCapabilityRid(local, &cap_rid, 1);
6394 if(!(cap_rid.softCap & 2)) { 6399 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6395 return -EOPNOTSUPP; 6400 return -EOPNOTSUPP;
6396 } 6401 }
6397 readConfigRid(local, 1); 6402 readConfigRid(local, 1);
@@ -6413,7 +6418,7 @@ static int airo_get_encode(struct net_device *dev,
6413 memset(extra, 0, 16); 6418 memset(extra, 0, 16);
6414 6419
6415 /* Which key do we want ? -1 -> tx index */ 6420 /* Which key do we want ? -1 -> tx index */
6416 if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4 : 1))) 6421 if (!valid_index(&cap_rid, index))
6417 index = get_wep_key(local, 0xffff); 6422 index = get_wep_key(local, 0xffff);
6418 dwrq->flags |= index + 1; 6423 dwrq->flags |= index + 1;
6419 /* Copy the key to the user buffer */ 6424 /* Copy the key to the user buffer */
@@ -6445,7 +6450,7 @@ static int airo_set_encodeext(struct net_device *dev,
6445 /* Is WEP supported ? */ 6450 /* Is WEP supported ? */
6446 readCapabilityRid(local, &cap_rid, 1); 6451 readCapabilityRid(local, &cap_rid, 1);
6447 /* Older firmware doesn't support this... 6452 /* Older firmware doesn't support this...
6448 if(!(cap_rid.softCap & 2)) { 6453 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6449 return -EOPNOTSUPP; 6454 return -EOPNOTSUPP;
6450 } */ 6455 } */
6451 readConfigRid(local, 1); 6456 readConfigRid(local, 1);
@@ -6453,7 +6458,7 @@ static int airo_set_encodeext(struct net_device *dev,
6453 /* Determine and validate the key index */ 6458 /* Determine and validate the key index */
6454 idx = encoding->flags & IW_ENCODE_INDEX; 6459 idx = encoding->flags & IW_ENCODE_INDEX;
6455 if (idx) { 6460 if (idx) {
6456 if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1)) 6461 if (!valid_index(&cap_rid, idx - 1))
6457 return -EINVAL; 6462 return -EINVAL;
6458 idx--; 6463 idx--;
6459 } else 6464 } else
@@ -6527,7 +6532,7 @@ static int airo_get_encodeext(struct net_device *dev,
6527 6532
6528 /* Is it supported ? */ 6533 /* Is it supported ? */
6529 readCapabilityRid(local, &cap_rid, 1); 6534 readCapabilityRid(local, &cap_rid, 1);
6530 if(!(cap_rid.softCap & 2)) { 6535 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6531 return -EOPNOTSUPP; 6536 return -EOPNOTSUPP;
6532 } 6537 }
6533 readConfigRid(local, 1); 6538 readConfigRid(local, 1);
@@ -6538,7 +6543,7 @@ static int airo_get_encodeext(struct net_device *dev,
6538 6543
6539 idx = encoding->flags & IW_ENCODE_INDEX; 6544 idx = encoding->flags & IW_ENCODE_INDEX;
6540 if (idx) { 6545 if (idx) {
6541 if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1)) 6546 if (!valid_index(&cap_rid, idx - 1))
6542 return -EINVAL; 6547 return -EINVAL;
6543 idx--; 6548 idx--;
6544 } else 6549 } else
@@ -6716,7 +6721,7 @@ static int airo_set_txpow(struct net_device *dev,
6716 } 6721 }
6717 clear_bit (FLAG_RADIO_OFF, &local->flags); 6722 clear_bit (FLAG_RADIO_OFF, &local->flags);
6718 for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++) 6723 for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
6719 if ((vwrq->value==cap_rid.txPowerLevels[i])) { 6724 if (vwrq->value == le16_to_cpu(cap_rid.txPowerLevels[i])) {
6720 readConfigRid(local, 1); 6725 readConfigRid(local, 1);
6721 local->config.txPower = vwrq->value; 6726 local->config.txPower = vwrq->value;
6722 set_bit (FLAG_COMMIT, &local->flags); 6727 set_bit (FLAG_COMMIT, &local->flags);
@@ -6888,16 +6893,17 @@ static int airo_get_range(struct net_device *dev,
6888 range->min_frag = 256; 6893 range->min_frag = 256;
6889 range->max_frag = AIRO_DEF_MTU; 6894 range->max_frag = AIRO_DEF_MTU;
6890 6895
6891 if(cap_rid.softCap & 2) { 6896 if(cap_rid.softCap & cpu_to_le16(2)) {
6892 // WEP: RC4 40 bits 6897 // WEP: RC4 40 bits
6893 range->encoding_size[0] = 5; 6898 range->encoding_size[0] = 5;
6894 // RC4 ~128 bits 6899 // RC4 ~128 bits
6895 if (cap_rid.softCap & 0x100) { 6900 if (cap_rid.softCap & cpu_to_le16(0x100)) {
6896 range->encoding_size[1] = 13; 6901 range->encoding_size[1] = 13;
6897 range->num_encoding_sizes = 2; 6902 range->num_encoding_sizes = 2;
6898 } else 6903 } else
6899 range->num_encoding_sizes = 1; 6904 range->num_encoding_sizes = 1;
6900 range->max_encoding_tokens = (cap_rid.softCap & 0x80) ? 4 : 1; 6905 range->max_encoding_tokens =
6906 cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
6901 } else { 6907 } else {
6902 range->num_encoding_sizes = 0; 6908 range->num_encoding_sizes = 0;
6903 range->max_encoding_tokens = 0; 6909 range->max_encoding_tokens = 0;
@@ -6912,7 +6918,7 @@ static int airo_get_range(struct net_device *dev,
6912 6918
6913 /* Transmit Power - values are in mW */ 6919 /* Transmit Power - values are in mW */
6914 for(i = 0 ; i < 8 ; i++) { 6920 for(i = 0 ; i < 8 ; i++) {
6915 range->txpower[i] = cap_rid.txPowerLevels[i]; 6921 range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
6916 if(range->txpower[i] == 0) 6922 if(range->txpower[i] == 0)
6917 break; 6923 break;
6918 } 6924 }