When I called p54_parse_eeprom() on a hand-coded structure
I managed to make a small mistake with wrap->len which caused
a segfault a few lines down when trying to read entry->len.
This patch changes the validation code to avoid such problems.
Signed-off-by: Johannes Berg <[email protected]>
---
drivers/net/wireless/p54common.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
--- everything.orig/drivers/net/wireless/p54common.c 2008-02-29 23:00:30.000000000 +0100
+++ everything/drivers/net/wireless/p54common.c 2008-02-29 23:27:55.000000000 +0100
@@ -206,18 +206,23 @@ int p54_parse_eeprom(struct ieee80211_hw
struct p54_common *priv = dev->priv;
struct eeprom_pda_wrap *wrap = NULL;
struct pda_entry *entry;
- int i = 0;
unsigned int data_len, entry_len;
void *tmp;
int err;
+ u8 *end = (u8 *)eeprom + len;
wrap = (struct eeprom_pda_wrap *) eeprom;
entry = (void *)wrap->data + le16_to_cpu(wrap->len);
- i += 2;
- i += le16_to_cpu(entry->len)*2;
- while (i < len) {
+
+ /* verify that at least the entry length/code fits */
+ while ((u8 *)entry <= end - sizeof(*entry)) {
entry_len = le16_to_cpu(entry->len);
data_len = ((entry_len - 1) << 1);
+
+ /* abort if entry exceeds whole structure */
+ if ((u8 *)entry + sizeof(*entry) + data_len > end)
+ break;
+
switch (le16_to_cpu(entry->code)) {
case PDR_MAC_ADDRESS:
SET_IEEE80211_PERM_ADDR(dev, entry->data);
@@ -289,7 +294,8 @@ int p54_parse_eeprom(struct ieee80211_hw
priv->version = *(u8 *)(entry->data + 1);
break;
case PDR_END:
- i = len;
+ /* make it overrun */
+ entry_len = len;
break;
default:
printk(KERN_INFO "p54: unknown eeprom code : 0x%x\n",
@@ -298,8 +304,6 @@ int p54_parse_eeprom(struct ieee80211_hw
}
entry = (void *)entry + (entry_len + 1)*2;
- i += 2;
- i += entry_len*2;
}
if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) {
Hi again Johannes,
Le vendredi 29 f=E9vrier 2008, Johannes Berg a =E9crit=A0:
> When I called p54_parse_eeprom() on a hand-coded structure
> I managed to make a small mistake with wrap->len which caused
> a segfault a few lines down when trying to read entry->len.
> This patch changes the validation code to avoid such problems.
>
> Signed-off-by: Johannes Berg <[email protected]>
I confirm this patch works, thanks Johannes. Tested with an Inventel UR=
054g=20
dongle.
Tested-by: Florian Fainelli <[email protected]>
> > When I called p54_parse_eeprom() on a hand-coded structure
> > I managed to make a small mistake with wrap->len which caused
> > a segfault a few lines down when trying to read entry->len.
> > This patch changes the validation code to avoid such problems.
> >
> > Signed-off-by: Johannes Berg <[email protected]>
>
> I confirm this patch works, thanks Johannes. Tested with an Inventel UR054g
> dongle.
>
> Tested-by: Florian Fainelli <[email protected]>
Great, thanks for testing.
John, please merge both these patches.
johannes