2007-11-23 00:14:34

by Daniel Drake

[permalink] [raw]
Subject: [PATCH 2.6.24] zd1211rw: fix unaligned memory accesses comparing MAC addresses

Shaddy Baddah reported some unaligned accesses with the zd1211rw driver.
David Miller found an issue with comparison of ethernet addresses, and I
found a few others on top of that. This patch should remove most/all of the
unaligned accesses.

Signed-off-by: Daniel Drake <[email protected]>

---

A different patch will follow for 2.6.25 soon, probably using
compare_ether_addr_unaligned() if David accepts that patch.

Index: linux-2.6.24-rc3-git1/drivers/net/wireless/zd1211rw/zd_mac.c
===================================================================
--- linux-2.6.24-rc3-git1.orig/drivers/net/wireless/zd1211rw/zd_mac.c
+++ linux-2.6.24-rc3-git1/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -974,14 +974,14 @@ static int is_data_packet_for_us(struct
switch (ieee->iw_mode) {
case IW_MODE_ADHOC:
if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 ||
- compare_ether_addr(hdr->addr3, ieee->bssid) != 0)
+ memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) != 0)
return 0;
break;
case IW_MODE_AUTO:
case IW_MODE_INFRA:
if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) !=
IEEE80211_FCTL_FROMDS ||
- compare_ether_addr(hdr->addr2, ieee->bssid) != 0)
+ memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) != 0)
return 0;
break;
default:
@@ -989,9 +989,9 @@ static int is_data_packet_for_us(struct
return 0;
}

- return compare_ether_addr(hdr->addr1, netdev->dev_addr) == 0 ||
+ return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 ||
(is_multicast_ether_addr(hdr->addr1) &&
- compare_ether_addr(hdr->addr3, netdev->dev_addr) != 0) ||
+ memcmp(hdr->addr3, netdev->dev_addr, ETH_ALEN) != 0) ||
(netdev->flags & IFF_PROMISC);
}

@@ -1047,7 +1047,7 @@ static void update_qual_rssi(struct zd_m
hdr = (struct ieee80211_hdr_3addr *)buffer;
if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
return;
- if (compare_ether_addr(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid) != 0)
+ if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0)
return;

spin_lock_irqsave(&mac->lock, flags);


2007-11-24 13:41:22

by Ulrich Kunitz

[permalink] [raw]
Subject: Re: [PATCH 2.6.24] zd1211rw: fix unaligned memory accesses comparing MAC addresses

Daniel Drake wrote:

> Shaddy Baddah reported some unaligned accesses with the zd1211rw driver.
> David Miller found an issue with comparison of ethernet addresses, and I
> found a few others on top of that. This patch should remove most/all of the
> unaligned accesses.
>
> Signed-off-by: Daniel Drake <[email protected]>

This patch will probably not solve all the issues, because the IP
header will not be aligned. This is caused by the ZD1211 specific
five-byte PLCP header. See my other mail from today, which
includes a patch, which should solve the issue.

Uli

>
> ---
>
> A different patch will follow for 2.6.25 soon, probably using
> compare_ether_addr_unaligned() if David accepts that patch.
>
> Index: linux-2.6.24-rc3-git1/drivers/net/wireless/zd1211rw/zd_mac.c
> ===================================================================
> --- linux-2.6.24-rc3-git1.orig/drivers/net/wireless/zd1211rw/zd_mac.c
> +++ linux-2.6.24-rc3-git1/drivers/net/wireless/zd1211rw/zd_mac.c
> @@ -974,14 +974,14 @@ static int is_data_packet_for_us(struct
> switch (ieee->iw_mode) {
> case IW_MODE_ADHOC:
> if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 ||
> - compare_ether_addr(hdr->addr3, ieee->bssid) != 0)
> + memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) != 0)
> return 0;
> break;
> case IW_MODE_AUTO:
> case IW_MODE_INFRA:
> if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) !=
> IEEE80211_FCTL_FROMDS ||
> - compare_ether_addr(hdr->addr2, ieee->bssid) != 0)
> + memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) != 0)
> return 0;
> break;
> default:
> @@ -989,9 +989,9 @@ static int is_data_packet_for_us(struct
> return 0;
> }
>
> - return compare_ether_addr(hdr->addr1, netdev->dev_addr) == 0 ||
> + return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 ||
> (is_multicast_ether_addr(hdr->addr1) &&
> - compare_ether_addr(hdr->addr3, netdev->dev_addr) != 0) ||
> + memcmp(hdr->addr3, netdev->dev_addr, ETH_ALEN) != 0) ||
> (netdev->flags & IFF_PROMISC);
> }
>
> @@ -1047,7 +1047,7 @@ static void update_qual_rssi(struct zd_m
> hdr = (struct ieee80211_hdr_3addr *)buffer;
> if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
> return;
> - if (compare_ether_addr(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid) != 0)
> + if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0)
> return;
>
> spin_lock_irqsave(&mac->lock, flags);
> -
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

--
Uli Kunitz

2007-11-23 20:34:09

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2.6.24] zd1211rw: fix unaligned memory accesses comparing MAC addresses


On Fri, 2007-11-23 at 00:14 +0000, Daniel Drake wrote:
> Shaddy Baddah reported some unaligned accesses with the zd1211rw driver.
> David Miller found an issue with comparison of ethernet addresses, and I
> found a few others on top of that. This patch should remove most/all of the
> unaligned accesses.

Why are these unaligned to start with?

> Signed-off-by: Daniel Drake <[email protected]>
>
> ---
>
> A different patch will follow for 2.6.25 soon, probably using
> compare_ether_addr_unaligned() if David accepts that patch.
>
> Index: linux-2.6.24-rc3-git1/drivers/net/wireless/zd1211rw/zd_mac.c
> ===================================================================
> --- linux-2.6.24-rc3-git1.orig/drivers/net/wireless/zd1211rw/zd_mac.c
> +++ linux-2.6.24-rc3-git1/drivers/net/wireless/zd1211rw/zd_mac.c
> @@ -974,14 +974,14 @@ static int is_data_packet_for_us(struct
> switch (ieee->iw_mode) {
> case IW_MODE_ADHOC:
> if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 ||
> - compare_ether_addr(hdr->addr3, ieee->bssid) != 0)
> + memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) != 0)
> return 0;
> break;
> case IW_MODE_AUTO:
> case IW_MODE_INFRA:
> if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) !=
> IEEE80211_FCTL_FROMDS ||
> - compare_ether_addr(hdr->addr2, ieee->bssid) != 0)
> + memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) != 0)
> return 0;
> break;
> default:
> @@ -989,9 +989,9 @@ static int is_data_packet_for_us(struct
> return 0;
> }
>
> - return compare_ether_addr(hdr->addr1, netdev->dev_addr) == 0 ||
> + return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 ||
> (is_multicast_ether_addr(hdr->addr1) &&
> - compare_ether_addr(hdr->addr3, netdev->dev_addr) != 0) ||
> + memcmp(hdr->addr3, netdev->dev_addr, ETH_ALEN) != 0) ||
> (netdev->flags & IFF_PROMISC);
> }
>
> @@ -1047,7 +1047,7 @@ static void update_qual_rssi(struct zd_m
> hdr = (struct ieee80211_hdr_3addr *)buffer;
> if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
> return;
> - if (compare_ether_addr(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid) != 0)
> + if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0)
> return;
>
> spin_lock_irqsave(&mac->lock, flags);
> -
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part