aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2007-12-19 22:24:16 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:02 -0500
commita23ace5f226aea6c8ba04794720502b1aad1dd92 (patch)
treee742f6a548f7773f8c89090748b7ac331d5ba61c
parent4293ea33c8a85c3b4401df5df82fc3e070ec0c8e (diff)
airo: sanitize handling of StatsRid
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.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 8eac7fb4521d..9b0714cea75e 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -706,9 +706,9 @@ typedef struct {
706} StatusRid; 706} StatusRid;
707 707
708typedef struct { 708typedef struct {
709 u16 len; 709 __le16 len;
710 u16 spacer; 710 __le16 spacer;
711 u32 vals[100]; 711 __le32 vals[100];
712} StatsRid; 712} StatsRid;
713 713
714 714
@@ -1889,13 +1889,10 @@ static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr, int lock)
1889 *s = le16_to_cpu(*s); 1889 *s = le16_to_cpu(*s);
1890 return rc; 1890 return rc;
1891} 1891}
1892static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {
1893 int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1894 u32 *i;
1895 1892
1896 sr->len = le16_to_cpu(sr->len); 1893static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
1897 for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i); 1894{
1898 return rc; 1895 return PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1899} 1896}
1900 1897
1901static void try_auto_wep(struct airo_info *ai) 1898static void try_auto_wep(struct airo_info *ai)
@@ -2260,9 +2257,10 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
2260 return 0; 2257 return 0;
2261} 2258}
2262 2259
2263static void airo_read_stats(struct airo_info *ai) { 2260static void airo_read_stats(struct airo_info *ai)
2261{
2264 StatsRid stats_rid; 2262 StatsRid stats_rid;
2265 u32 *vals = stats_rid.vals; 2263 __le32 *vals = stats_rid.vals;
2266 2264
2267 clear_bit(JOB_STATS, &ai->jobs); 2265 clear_bit(JOB_STATS, &ai->jobs);
2268 if (ai->power.event) { 2266 if (ai->power.event) {
@@ -2272,20 +2270,23 @@ static void airo_read_stats(struct airo_info *ai) {
2272 readStatsRid(ai, &stats_rid, RID_STATS, 0); 2270 readStatsRid(ai, &stats_rid, RID_STATS, 0);
2273 up(&ai->sem); 2271 up(&ai->sem);
2274 2272
2275 ai->stats.rx_packets = vals[43] + vals[44] + vals[45]; 2273 ai->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
2276 ai->stats.tx_packets = vals[39] + vals[40] + vals[41]; 2274 le32_to_cpu(vals[45]);
2277 ai->stats.rx_bytes = vals[92]; 2275 ai->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
2278 ai->stats.tx_bytes = vals[91]; 2276 le32_to_cpu(vals[41]);
2279 ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4]; 2277 ai->stats.rx_bytes = le32_to_cpu(vals[92]);
2280 ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors; 2278 ai->stats.tx_bytes = le32_to_cpu(vals[91]);
2281 ai->stats.multicast = vals[43]; 2279 ai->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
2282 ai->stats.collisions = vals[89]; 2280 le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
2281 ai->stats.tx_errors = le32_to_cpu(vals[42]) + ai->stats.tx_fifo_errors;
2282 ai->stats.multicast = le32_to_cpu(vals[43]);
2283 ai->stats.collisions = le32_to_cpu(vals[89]);
2283 2284
2284 /* detailed rx_errors: */ 2285 /* detailed rx_errors: */
2285 ai->stats.rx_length_errors = vals[3]; 2286 ai->stats.rx_length_errors = le32_to_cpu(vals[3]);
2286 ai->stats.rx_crc_errors = vals[4]; 2287 ai->stats.rx_crc_errors = le32_to_cpu(vals[4]);
2287 ai->stats.rx_frame_errors = vals[2]; 2288 ai->stats.rx_frame_errors = le32_to_cpu(vals[2]);
2288 ai->stats.rx_fifo_errors = vals[0]; 2289 ai->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
2289} 2290}
2290 2291
2291static struct net_device_stats *airo_get_stats(struct net_device *dev) 2292static struct net_device_stats *airo_get_stats(struct net_device *dev)
@@ -4741,14 +4742,16 @@ static int proc_stats_open( struct inode *inode, struct file *file ) {
4741 4742
4742static int proc_stats_rid_open( struct inode *inode, 4743static int proc_stats_rid_open( struct inode *inode,
4743 struct file *file, 4744 struct file *file,
4744 u16 rid ) { 4745 u16 rid )
4746{
4745 struct proc_data *data; 4747 struct proc_data *data;
4746 struct proc_dir_entry *dp = PDE(inode); 4748 struct proc_dir_entry *dp = PDE(inode);
4747 struct net_device *dev = dp->data; 4749 struct net_device *dev = dp->data;
4748 struct airo_info *apriv = dev->priv; 4750 struct airo_info *apriv = dev->priv;
4749 StatsRid stats; 4751 StatsRid stats;
4750 int i, j; 4752 int i, j;
4751 u32 *vals = stats.vals; 4753 __le32 *vals = stats.vals;
4754 int len = le16_to_cpu(stats.len);
4752 4755
4753 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4756 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4754 return -ENOMEM; 4757 return -ENOMEM;
@@ -4761,17 +4764,17 @@ static int proc_stats_rid_open( struct inode *inode,
4761 readStatsRid(apriv, &stats, rid, 1); 4764 readStatsRid(apriv, &stats, rid, 1);
4762 4765
4763 j = 0; 4766 j = 0;
4764 for(i=0; statsLabels[i]!=(char *)-1 && 4767 for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
4765 i*4<stats.len; i++){
4766 if (!statsLabels[i]) continue; 4768 if (!statsLabels[i]) continue;
4767 if (j+strlen(statsLabels[i])+16>4096) { 4769 if (j+strlen(statsLabels[i])+16>4096) {
4768 airo_print_warn(apriv->dev->name, 4770 airo_print_warn(apriv->dev->name,
4769 "Potentially disasterous buffer overflow averted!"); 4771 "Potentially disasterous buffer overflow averted!");
4770 break; 4772 break;
4771 } 4773 }
4772 j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]); 4774 j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
4775 le32_to_cpu(vals[i]));
4773 } 4776 }
4774 if (i*4>=stats.len){ 4777 if (i*4 >= len) {
4775 airo_print_warn(apriv->dev->name, "Got a short rid"); 4778 airo_print_warn(apriv->dev->name, "Got a short rid");
4776 } 4779 }
4777 data->readlen = j; 4780 data->readlen = j;
@@ -7624,7 +7627,7 @@ static void airo_read_wireless_stats(struct airo_info *local)
7624 StatusRid status_rid; 7627 StatusRid status_rid;
7625 StatsRid stats_rid; 7628 StatsRid stats_rid;
7626 CapabilityRid cap_rid; 7629 CapabilityRid cap_rid;
7627 u32 *vals = stats_rid.vals; 7630 __le32 *vals = stats_rid.vals;
7628 7631
7629 /* Get stats out of the card */ 7632 /* Get stats out of the card */
7630 clear_bit(JOB_WSTATS, &local->jobs); 7633 clear_bit(JOB_WSTATS, &local->jobs);
@@ -7659,12 +7662,15 @@ static void airo_read_wireless_stats(struct airo_info *local)
7659 7662
7660 /* Packets discarded in the wireless adapter due to wireless 7663 /* Packets discarded in the wireless adapter due to wireless
7661 * specific problems */ 7664 * specific problems */
7662 local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */ 7665 local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
7663 local->wstats.discard.code = vals[6];/* RxWepErr */ 7666 le32_to_cpu(vals[57]) +
7664 local->wstats.discard.fragment = vals[30]; 7667 le32_to_cpu(vals[58]); /* SSID Mismatch */
7665 local->wstats.discard.retries = vals[10]; 7668 local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
7666 local->wstats.discard.misc = vals[1] + vals[32]; 7669 local->wstats.discard.fragment = le32_to_cpu(vals[30]);
7667 local->wstats.miss.beacon = vals[34]; 7670 local->wstats.discard.retries = le32_to_cpu(vals[10]);
7671 local->wstats.discard.misc = le32_to_cpu(vals[1]) +
7672 le32_to_cpu(vals[32]);
7673 local->wstats.miss.beacon = le32_to_cpu(vals[34]);
7668} 7674}
7669 7675
7670static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) 7676static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)