Skip to content

Commit

Permalink
can: kvaser_usb: Avoid double free on URB submission failures
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: linux-stable <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
  • Loading branch information
Ahmed S. Darwish authored and marckleinebudde committed Mar 9, 2015
1 parent b0d4724 commit deb2701
Showing 1 changed file with 8 additions and 12 deletions.
20 changes: 8 additions & 12 deletions drivers/net/can/usb/kvaser_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,6 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv,
netdev_err(netdev, "Error transmitting URB\n");
usb_unanchor_urb(urb);
usb_free_urb(urb);
kfree(buf);
return err;
}

Expand Down Expand Up @@ -1615,8 +1614,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
struct urb *urb;
void *buf;
struct kvaser_msg *msg;
int i, err;
int ret = NETDEV_TX_OK;
int i, err, ret = NETDEV_TX_OK;
u8 *msg_tx_can_flags = NULL; /* GCC */

if (can_dropped_invalid_skb(netdev, skb))
Expand All @@ -1634,7 +1632,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (!buf) {
stats->tx_dropped++;
dev_kfree_skb(skb);
goto nobufmem;
goto freeurb;
}

msg = buf;
Expand Down Expand Up @@ -1681,8 +1679,10 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
/* This should never happen; it implies a flow control bug */
if (!context) {
netdev_warn(netdev, "cannot find free context\n");

kfree(buf);
ret = NETDEV_TX_BUSY;
goto releasebuf;
goto freeurb;
}

context->priv = priv;
Expand Down Expand Up @@ -1719,16 +1719,12 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
else
netdev_warn(netdev, "Failed tx_urb %d\n", err);

goto releasebuf;
goto freeurb;
}

usb_free_urb(urb);

return NETDEV_TX_OK;
ret = NETDEV_TX_OK;

releasebuf:
kfree(buf);
nobufmem:
freeurb:
usb_free_urb(urb);
return ret;
}
Expand Down

0 comments on commit deb2701

Please sign in to comment.