aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorSeth Forshee <seth.forshee@canonical.com>2011-02-14 09:52:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-14 15:50:17 -0500
commitd76dfc612b40b6a9de0a3fe57fe1fa3db7a1ae3b (patch)
tree169aca14bd1a3514452aeac5170214280937a6eb /drivers/net/wireless
parenta3dc5e881a8a5199bf371fdd4530cfa18280ca83 (diff)
rt2x00: Check for errors from skb_pad() calls
Commit 739fd94 ("rt2x00: Pad beacon to multiple of 32 bits") added calls to skb_pad() without checking the return value, which could cause problems if any of those calls does happen to fail. Add checks to prevent this from happening. Signed-off-by: Seth Forshee <seth.forshee@canonical.com> Acked-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c12
3 files changed, 30 insertions, 6 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index c9bf074342b..7a68a67c506 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -773,13 +773,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
773 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 773 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
774 unsigned int beacon_base; 774 unsigned int beacon_base;
775 unsigned int padding_len; 775 unsigned int padding_len;
776 u32 reg; 776 u32 orig_reg, reg;
777 777
778 /* 778 /*
779 * Disable beaconing while we are reloading the beacon data, 779 * Disable beaconing while we are reloading the beacon data,
780 * otherwise we might be sending out invalid data. 780 * otherwise we might be sending out invalid data.
781 */ 781 */
782 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg); 782 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
783 orig_reg = reg;
783 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0); 784 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
784 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 785 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
785 786
@@ -810,7 +811,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
810 * Write entire beacon with TXWI and padding to register. 811 * Write entire beacon with TXWI and padding to register.
811 */ 812 */
812 padding_len = roundup(entry->skb->len, 4) - entry->skb->len; 813 padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
813 skb_pad(entry->skb, padding_len); 814 if (padding_len && skb_pad(entry->skb, padding_len)) {
815 ERROR(rt2x00dev, "Failure padding beacon, aborting\n");
816 /* skb freed by skb_pad() on failure */
817 entry->skb = NULL;
818 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
819 return;
820 }
821
814 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 822 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
815 rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, 823 rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
816 entry->skb->len + padding_len); 824 entry->skb->len + padding_len);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index dd2164d4d57..927a4a3e0ee 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1978,13 +1978,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
1978 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1978 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1979 unsigned int beacon_base; 1979 unsigned int beacon_base;
1980 unsigned int padding_len; 1980 unsigned int padding_len;
1981 u32 reg; 1981 u32 orig_reg, reg;
1982 1982
1983 /* 1983 /*
1984 * Disable beaconing while we are reloading the beacon data, 1984 * Disable beaconing while we are reloading the beacon data,
1985 * otherwise we might be sending out invalid data. 1985 * otherwise we might be sending out invalid data.
1986 */ 1986 */
1987 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg); 1987 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
1988 orig_reg = reg;
1988 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0); 1989 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
1989 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); 1990 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
1990 1991
@@ -2002,7 +2003,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
2002 * Write entire beacon with descriptor and padding to register. 2003 * Write entire beacon with descriptor and padding to register.
2003 */ 2004 */
2004 padding_len = roundup(entry->skb->len, 4) - entry->skb->len; 2005 padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
2005 skb_pad(entry->skb, padding_len); 2006 if (padding_len && skb_pad(entry->skb, padding_len)) {
2007 ERROR(rt2x00dev, "Failure padding beacon, aborting\n");
2008 /* skb freed by skb_pad() on failure */
2009 entry->skb = NULL;
2010 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, orig_reg);
2011 return;
2012 }
2013
2006 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 2014 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
2007 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, 2015 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
2008 entry_priv->desc, TXINFO_SIZE); 2016 entry_priv->desc, TXINFO_SIZE);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 5ff72deea8d..6e9981a1dd7 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1533,13 +1533,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1533 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1533 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1534 unsigned int beacon_base; 1534 unsigned int beacon_base;
1535 unsigned int padding_len; 1535 unsigned int padding_len;
1536 u32 reg; 1536 u32 orig_reg, reg;
1537 1537
1538 /* 1538 /*
1539 * Disable beaconing while we are reloading the beacon data, 1539 * Disable beaconing while we are reloading the beacon data,
1540 * otherwise we might be sending out invalid data. 1540 * otherwise we might be sending out invalid data.
1541 */ 1541 */
1542 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg); 1542 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
1543 orig_reg = reg;
1543 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0); 1544 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
1544 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); 1545 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1545 1546
@@ -1563,7 +1564,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1563 * Write entire beacon with descriptor and padding to register. 1564 * Write entire beacon with descriptor and padding to register.
1564 */ 1565 */
1565 padding_len = roundup(entry->skb->len, 4) - entry->skb->len; 1566 padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
1566 skb_pad(entry->skb, padding_len); 1567 if (padding_len && skb_pad(entry->skb, padding_len)) {
1568 ERROR(rt2x00dev, "Failure padding beacon, aborting\n");
1569 /* skb freed by skb_pad() on failure */
1570 entry->skb = NULL;
1571 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg);
1572 return;
1573 }
1574
1567 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 1575 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1568 rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, 1576 rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
1569 entry->skb->len + padding_len); 1577 entry->skb->len + padding_len);