aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmed S. Darwish <ahmed.darwish@valeo.com>2015-02-26 10:20:11 -0500
committerMarc Kleine-Budde <mkl@pengutronix.de>2015-03-09 05:22:24 -0400
commitdeb2701cf704a2fd03a8b598bf73df3edb08818d (patch)
treea0481cbc08a3c1ac2ec0eb400b06207dffa9b39b
parentb0d4724b8e4ce2a60ee4e097ec50c3759ec2090a (diff)
can: kvaser_usb: Avoid double free on URB submission failures
Upon a URB submission failure, the driver calls usb_free_urb() but then manually frees the URB buffer by itself. Meanwhile usb_free_urb() has alredy freed out that transfer buffer since we're the only code path holding a reference to this URB. Remove two of such invalid manual free(). Signed-off-by: Ahmed S. Darwish <ahmed.darwish@valeo.com> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--drivers/net/can/usb/kvaser_usb.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 2928f7003041..d986fe83c40d 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -787,7 +787,6 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv,
787 netdev_err(netdev, "Error transmitting URB\n"); 787 netdev_err(netdev, "Error transmitting URB\n");
788 usb_unanchor_urb(urb); 788 usb_unanchor_urb(urb);
789 usb_free_urb(urb); 789 usb_free_urb(urb);
790 kfree(buf);
791 return err; 790 return err;
792 } 791 }
793 792
@@ -1615,8 +1614,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
1615 struct urb *urb; 1614 struct urb *urb;
1616 void *buf; 1615 void *buf;
1617 struct kvaser_msg *msg; 1616 struct kvaser_msg *msg;
1618 int i, err; 1617 int i, err, ret = NETDEV_TX_OK;
1619 int ret = NETDEV_TX_OK;
1620 u8 *msg_tx_can_flags = NULL; /* GCC */ 1618 u8 *msg_tx_can_flags = NULL; /* GCC */
1621 1619
1622 if (can_dropped_invalid_skb(netdev, skb)) 1620 if (can_dropped_invalid_skb(netdev, skb))
@@ -1634,7 +1632,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
1634 if (!buf) { 1632 if (!buf) {
1635 stats->tx_dropped++; 1633 stats->tx_dropped++;
1636 dev_kfree_skb(skb); 1634 dev_kfree_skb(skb);
1637 goto nobufmem; 1635 goto freeurb;
1638 } 1636 }
1639 1637
1640 msg = buf; 1638 msg = buf;
@@ -1681,8 +1679,10 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
1681 /* This should never happen; it implies a flow control bug */ 1679 /* This should never happen; it implies a flow control bug */
1682 if (!context) { 1680 if (!context) {
1683 netdev_warn(netdev, "cannot find free context\n"); 1681 netdev_warn(netdev, "cannot find free context\n");
1682
1683 kfree(buf);
1684 ret = NETDEV_TX_BUSY; 1684 ret = NETDEV_TX_BUSY;
1685 goto releasebuf; 1685 goto freeurb;
1686 } 1686 }
1687 1687
1688 context->priv = priv; 1688 context->priv = priv;
@@ -1719,16 +1719,12 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
1719 else 1719 else
1720 netdev_warn(netdev, "Failed tx_urb %d\n", err); 1720 netdev_warn(netdev, "Failed tx_urb %d\n", err);
1721 1721
1722 goto releasebuf; 1722 goto freeurb;
1723 } 1723 }
1724 1724
1725 usb_free_urb(urb); 1725 ret = NETDEV_TX_OK;
1726
1727 return NETDEV_TX_OK;
1728 1726
1729releasebuf: 1727freeurb:
1730 kfree(buf);
1731nobufmem:
1732 usb_free_urb(urb); 1728 usb_free_urb(urb);
1733 return ret; 1729 return ret;
1734} 1730}