aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2007-12-17 16:11:57 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:08:58 -0500
commit0dd2212fb6872d8f5dd90391a12fb3fcb877c7c1 (patch)
tree75166515117c968f4c1bc77b0a944db30ed97988 /drivers/net/wireless/airo.c
parent593c2b9cf28355c6c409d71594bed797279d01f5 (diff)
airo: sanitize handling of SSID_rid
* store SSID_rid without conversions * sanitize proc_SSID_on_close() (and avoid access past the end of buffer, while we are at it) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/airo.c')
-rw-r--r--drivers/net/wireless/airo.c103
1 files changed, 49 insertions, 54 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 76cd1036e2d2..c4ae44142a67 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -510,12 +510,12 @@ typedef struct {
510 510
511/* These structures are from the Aironet's PC4500 Developers Manual */ 511/* These structures are from the Aironet's PC4500 Developers Manual */
512typedef struct { 512typedef struct {
513 u16 len; 513 __le16 len;
514 u8 ssid[32]; 514 u8 ssid[32];
515} Ssid; 515} Ssid;
516 516
517typedef struct { 517typedef struct {
518 u16 len; 518 __le16 len;
519 Ssid ssids[3]; 519 Ssid ssids[3];
520} SsidRid; 520} SsidRid;
521 521
@@ -1789,28 +1789,16 @@ static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lo
1789 return rc; 1789 return rc;
1790} 1790}
1791 1791
1792static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) { 1792static int readSsidRid(struct airo_info*ai, SsidRid *ssidr)
1793 int i; 1793{
1794 int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1); 1794 return PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
1795
1796 ssidr->len = le16_to_cpu(ssidr->len);
1797 for(i = 0; i < 3; i++) {
1798 ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);
1799 }
1800 return rc;
1801} 1795}
1802static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock) {
1803 int rc;
1804 int i;
1805 SsidRid ssidr = *pssidr;
1806 1796
1807 ssidr.len = cpu_to_le16(ssidr.len); 1797static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock)
1808 for(i = 0; i < 3; i++) { 1798{
1809 ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len); 1799 return PC4500_writerid(ai, RID_SSID, pssidr, sizeof(*pssidr), lock);
1810 }
1811 rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), lock);
1812 return rc;
1813} 1800}
1801
1814static int readConfigRid(struct airo_info*ai, int lock) { 1802static int readConfigRid(struct airo_info*ai, int lock) {
1815 int rc; 1803 int rc;
1816 u16 *s; 1804 u16 *s;
@@ -3886,13 +3874,13 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3886 if ( ssids[0] ) { 3874 if ( ssids[0] ) {
3887 int i; 3875 int i;
3888 for( i = 0; i < 3 && ssids[i]; i++ ) { 3876 for( i = 0; i < 3 && ssids[i]; i++ ) {
3889 mySsid.ssids[i].len = strlen(ssids[i]); 3877 size_t len = strlen(ssids[i]);
3890 if ( mySsid.ssids[i].len > 32 ) 3878 if (len > 32)
3891 mySsid.ssids[i].len = 32; 3879 len = 32;
3892 memcpy(mySsid.ssids[i].ssid, ssids[i], 3880 mySsid.ssids[i].len = cpu_to_le16(len);
3893 mySsid.ssids[i].len); 3881 memcpy(mySsid.ssids[i].ssid, ssids[i], len);
3894 } 3882 }
3895 mySsid.len = sizeof(mySsid); 3883 mySsid.len = cpu_to_le16(sizeof(mySsid));
3896 } 3884 }
3897 3885
3898 status = writeConfigRid(ai, lock); 3886 status = writeConfigRid(ai, lock);
@@ -5123,34 +5111,38 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
5123 return 0; 5111 return 0;
5124} 5112}
5125 5113
5126static void proc_SSID_on_close( struct inode *inode, struct file *file ) { 5114static void proc_SSID_on_close(struct inode *inode, struct file *file)
5115{
5127 struct proc_data *data = (struct proc_data *)file->private_data; 5116 struct proc_data *data = (struct proc_data *)file->private_data;
5128 struct proc_dir_entry *dp = PDE(inode); 5117 struct proc_dir_entry *dp = PDE(inode);
5129 struct net_device *dev = dp->data; 5118 struct net_device *dev = dp->data;
5130 struct airo_info *ai = dev->priv; 5119 struct airo_info *ai = dev->priv;
5131 SsidRid SSID_rid; 5120 SsidRid SSID_rid;
5132 int i; 5121 int i;
5133 int offset = 0; 5122 char *p = data->wbuffer;
5123 char *end = p + data->writelen;
5134 5124
5135 if ( !data->writelen ) return; 5125 if (!data->writelen)
5126 return;
5136 5127
5137 memset( &SSID_rid, 0, sizeof( SSID_rid ) ); 5128 *end = '\n'; /* sentinel; we have space for it */
5138 5129
5139 for( i = 0; i < 3; i++ ) { 5130 memset(&SSID_rid, 0, sizeof(SSID_rid));
5140 int j; 5131
5141 for( j = 0; j+offset < data->writelen && j < 32 && 5132 for (i = 0; i < 3 && p < end; i++) {
5142 data->wbuffer[offset+j] != '\n'; j++ ) { 5133 int j = 0;
5143 SSID_rid.ssids[i].ssid[j] = data->wbuffer[offset+j]; 5134 /* copy up to 32 characters from this line */
5144 } 5135 while (*p != '\n' && j < 32)
5145 if ( j == 0 ) break; 5136 SSID_rid.ssids[i].ssid[j++] = *p++;
5146 SSID_rid.ssids[i].len = j; 5137 if (j == 0)
5147 offset += j; 5138 break;
5148 while( data->wbuffer[offset] != '\n' && 5139 SSID_rid.ssids[i].len = cpu_to_le16(j);
5149 offset < data->writelen ) offset++; 5140 /* skip to the beginning of the next line */
5150 offset++; 5141 while (*p++ != '\n')
5142 ;
5151 } 5143 }
5152 if (i) 5144 if (i)
5153 SSID_rid.len = sizeof(SSID_rid); 5145 SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5154 disable_MAC(ai, 1); 5146 disable_MAC(ai, 1);
5155 writeSsidRid(ai, &SSID_rid, 1); 5147 writeSsidRid(ai, &SSID_rid, 1);
5156 enable_MAC(ai, 1); 5148 enable_MAC(ai, 1);
@@ -5345,7 +5337,8 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
5345 return 0; 5337 return 0;
5346} 5338}
5347 5339
5348static int proc_SSID_open( struct inode *inode, struct file *file ) { 5340static int proc_SSID_open(struct inode *inode, struct file *file)
5341{
5349 struct proc_data *data; 5342 struct proc_data *data;
5350 struct proc_dir_entry *dp = PDE(inode); 5343 struct proc_dir_entry *dp = PDE(inode);
5351 struct net_device *dev = dp->data; 5344 struct net_device *dev = dp->data;
@@ -5363,7 +5356,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5363 } 5356 }
5364 data->writelen = 0; 5357 data->writelen = 0;
5365 data->maxwritelen = 33*3; 5358 data->maxwritelen = 33*3;
5366 if ((data->wbuffer = kzalloc( 33*3, GFP_KERNEL )) == NULL) { 5359 /* allocate maxwritelen + 1; we'll want a sentinel */
5360 if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
5367 kfree (data->rbuffer); 5361 kfree (data->rbuffer);
5368 kfree (file->private_data); 5362 kfree (file->private_data);
5369 return -ENOMEM; 5363 return -ENOMEM;
@@ -5372,14 +5366,15 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5372 5366
5373 readSsidRid(ai, &SSID_rid); 5367 readSsidRid(ai, &SSID_rid);
5374 ptr = data->rbuffer; 5368 ptr = data->rbuffer;
5375 for( i = 0; i < 3; i++ ) { 5369 for (i = 0; i < 3; i++) {
5376 int j; 5370 int j;
5377 if ( !SSID_rid.ssids[i].len ) break; 5371 size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
5378 for( j = 0; j < 32 && 5372 if (!len)
5379 j < SSID_rid.ssids[i].len && 5373 break;
5380 SSID_rid.ssids[i].ssid[j]; j++ ) { 5374 if (len > 32)
5375 len = 32;
5376 for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
5381 *ptr++ = SSID_rid.ssids[i].ssid[j]; 5377 *ptr++ = SSID_rid.ssids[i].ssid[j];
5382 }
5383 *ptr++ = '\n'; 5378 *ptr++ = '\n';
5384 } 5379 }
5385 *ptr = '\0'; 5380 *ptr = '\0';
@@ -5895,9 +5890,9 @@ static int airo_set_essid(struct net_device *dev,
5895 memset(SSID_rid.ssids[index].ssid, 0, 5890 memset(SSID_rid.ssids[index].ssid, 0,
5896 sizeof(SSID_rid.ssids[index].ssid)); 5891 sizeof(SSID_rid.ssids[index].ssid));
5897 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length); 5892 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5898 SSID_rid.ssids[index].len = dwrq->length; 5893 SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
5899 } 5894 }
5900 SSID_rid.len = sizeof(SSID_rid); 5895 SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5901 /* Write it to the card */ 5896 /* Write it to the card */
5902 disable_MAC(local, 1); 5897 disable_MAC(local, 1);
5903 writeSsidRid(local, &SSID_rid, 1); 5898 writeSsidRid(local, &SSID_rid, 1);