diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-03-04 23:20:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-03-04 23:20:58 -0500 |
commit | 27d0483aa1ef66a8877d71b63bb97f46ab0246b2 (patch) | |
tree | ca84a9db8c79b789d40d2d9ae30d0349fd3562fc /drivers/net/wireless/p54common.c | |
parent | 665c1ef8369138dad7773da6407fe77ccff87deb (diff) | |
parent | dea75bdfa57f75a7a7ec2961ec28db506c18e5db (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (22 commits)
[IPCONFIG]: The kernel gets no IP from some DHCP servers
b43legacy: Fix module init message
rndis_wlan: fix broken data copy
libertas: compare the current command with response
libertas: fix sanity check on sequence number in command response
p54: fix eeprom parser length sanity checks
p54: fix EEPROM structure endianness
ssb: Add pcibios_enable_device() return value check
rc80211-pid: fix rate adjustment
[ESP]: Add select on AUTHENC
[TCP]: Improve ipv4 established hash function.
[NETPOLL]: Revert two bogus cleanups that broke netconsole.
[PPPOL2TP]: Add missing sock_put() in pppol2tp_tunnel_closeall()
Subject: [PPPOL2TP] add missing sock_put() in pppol2tp_recv_dequeue()
[BLUETOOTH]: l2cap info_timer delete fix in hci_conn_del
[NET]: Fix race in generic address resolution.
iucv: fix build error on !SMP
[TCP]: Must count fack_count also when skipping
[TUN]: Fix RTNL-locking in tun/tap driver
[SCTP]: Use proc_create to setup de->proc_fops.
...
Diffstat (limited to 'drivers/net/wireless/p54common.c')
-rw-r--r-- | drivers/net/wireless/p54common.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c index 5cda49aff3a8..d191e055a788 100644 --- a/drivers/net/wireless/p54common.c +++ b/drivers/net/wireless/p54common.c | |||
@@ -166,18 +166,23 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
166 | struct p54_common *priv = dev->priv; | 166 | struct p54_common *priv = dev->priv; |
167 | struct eeprom_pda_wrap *wrap = NULL; | 167 | struct eeprom_pda_wrap *wrap = NULL; |
168 | struct pda_entry *entry; | 168 | struct pda_entry *entry; |
169 | int i = 0; | ||
170 | unsigned int data_len, entry_len; | 169 | unsigned int data_len, entry_len; |
171 | void *tmp; | 170 | void *tmp; |
172 | int err; | 171 | int err; |
172 | u8 *end = (u8 *)eeprom + len; | ||
173 | 173 | ||
174 | wrap = (struct eeprom_pda_wrap *) eeprom; | 174 | wrap = (struct eeprom_pda_wrap *) eeprom; |
175 | entry = (void *)wrap->data + wrap->len; | 175 | entry = (void *)wrap->data + le16_to_cpu(wrap->len); |
176 | i += 2; | 176 | |
177 | i += le16_to_cpu(entry->len)*2; | 177 | /* verify that at least the entry length/code fits */ |
178 | while (i < len) { | 178 | while ((u8 *)entry <= end - sizeof(*entry)) { |
179 | entry_len = le16_to_cpu(entry->len); | 179 | entry_len = le16_to_cpu(entry->len); |
180 | data_len = ((entry_len - 1) << 1); | 180 | data_len = ((entry_len - 1) << 1); |
181 | |||
182 | /* abort if entry exceeds whole structure */ | ||
183 | if ((u8 *)entry + sizeof(*entry) + data_len > end) | ||
184 | break; | ||
185 | |||
181 | switch (le16_to_cpu(entry->code)) { | 186 | switch (le16_to_cpu(entry->code)) { |
182 | case PDR_MAC_ADDRESS: | 187 | case PDR_MAC_ADDRESS: |
183 | SET_IEEE80211_PERM_ADDR(dev, entry->data); | 188 | SET_IEEE80211_PERM_ADDR(dev, entry->data); |
@@ -249,13 +254,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
249 | priv->version = *(u8 *)(entry->data + 1); | 254 | priv->version = *(u8 *)(entry->data + 1); |
250 | break; | 255 | break; |
251 | case PDR_END: | 256 | case PDR_END: |
252 | i = len; | 257 | /* make it overrun */ |
258 | entry_len = len; | ||
253 | break; | 259 | break; |
254 | } | 260 | } |
255 | 261 | ||
256 | entry = (void *)entry + (entry_len + 1)*2; | 262 | entry = (void *)entry + (entry_len + 1)*2; |
257 | i += 2; | ||
258 | i += entry_len*2; | ||
259 | } | 263 | } |
260 | 264 | ||
261 | if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) { | 265 | if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) { |