diff options
author | Seth Forshee <seth.forshee@canonical.com> | 2011-02-14 09:52:25 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-14 15:50:17 -0500 |
commit | d76dfc612b40b6a9de0a3fe57fe1fa3db7a1ae3b (patch) | |
tree | 169aca14bd1a3514452aeac5170214280937a6eb /drivers/net | |
parent | a3dc5e881a8a5199bf371fdd4530cfa18280ca83 (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')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 12 |
3 files changed, 30 insertions, 6 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c9bf074342ba..7a68a67c506a 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, ®); | 782 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
783 | orig_reg = reg; | ||
783 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | 784 | rt2x00_set_field32(®, 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 dd2164d4d57b..927a4a3e0eeb 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, ®); | 1987 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); |
1988 | orig_reg = reg; | ||
1988 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 1989 | rt2x00_set_field32(®, 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 5ff72deea8d4..6e9981a1dd7f 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, ®); | 1542 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
1543 | orig_reg = reg; | ||
1543 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 1544 | rt2x00_set_field32(®, 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); |