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>
This commit is contained in:
parent
b0d4724b8e
commit
deb2701cf7
1 changed files with 8 additions and 12 deletions
|
@ -787,7 +787,6 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv,
|
||||||
netdev_err(netdev, "Error transmitting URB\n");
|
netdev_err(netdev, "Error transmitting URB\n");
|
||||||
usb_unanchor_urb(urb);
|
usb_unanchor_urb(urb);
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
kfree(buf);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1615,8 +1614,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
void *buf;
|
void *buf;
|
||||||
struct kvaser_msg *msg;
|
struct kvaser_msg *msg;
|
||||||
int i, err;
|
int i, err, ret = NETDEV_TX_OK;
|
||||||
int ret = NETDEV_TX_OK;
|
|
||||||
u8 *msg_tx_can_flags = NULL; /* GCC */
|
u8 *msg_tx_can_flags = NULL; /* GCC */
|
||||||
|
|
||||||
if (can_dropped_invalid_skb(netdev, skb))
|
if (can_dropped_invalid_skb(netdev, skb))
|
||||||
|
@ -1634,7 +1632,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
stats->tx_dropped++;
|
stats->tx_dropped++;
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
goto nobufmem;
|
goto freeurb;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = buf;
|
msg = buf;
|
||||||
|
@ -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 */
|
/* This should never happen; it implies a flow control bug */
|
||||||
if (!context) {
|
if (!context) {
|
||||||
netdev_warn(netdev, "cannot find free context\n");
|
netdev_warn(netdev, "cannot find free context\n");
|
||||||
|
|
||||||
|
kfree(buf);
|
||||||
ret = NETDEV_TX_BUSY;
|
ret = NETDEV_TX_BUSY;
|
||||||
goto releasebuf;
|
goto freeurb;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->priv = priv;
|
context->priv = priv;
|
||||||
|
@ -1719,16 +1719,12 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
|
||||||
else
|
else
|
||||||
netdev_warn(netdev, "Failed tx_urb %d\n", err);
|
netdev_warn(netdev, "Failed tx_urb %d\n", err);
|
||||||
|
|
||||||
goto releasebuf;
|
goto freeurb;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_free_urb(urb);
|
ret = NETDEV_TX_OK;
|
||||||
|
|
||||||
return NETDEV_TX_OK;
|
freeurb:
|
||||||
|
|
||||||
releasebuf:
|
|
||||||
kfree(buf);
|
|
||||||
nobufmem:
|
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue