mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
Merge patch series "can: skb: make echo skb freeing safe in any IRQ context"
Cunhao Lu <1579567540@qq.com> says: can_put_echo_skb() and the CAN skb allocation helpers may release skbs in hardware interrupt context or while hardware interrupts are disabled. This series makes the affected public helper paths safe in either context and fixes the invalid echo-index skb leak. Link: https://patch.msgid.link/tencent_CD05F020BAFB2537F5D1F4CBB425588EA80A@qq.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
commit
d3592ab8a1
|
|
@ -55,6 +55,7 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
if (idx >= priv->echo_skb_max) {
|
||||
netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
|
||||
__func__, idx, priv->echo_skb_max);
|
||||
dev_kfree_skb_any(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +64,7 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
(skb->protocol != htons(ETH_P_CAN) &&
|
||||
skb->protocol != htons(ETH_P_CANFD) &&
|
||||
skb->protocol != htons(ETH_P_CANXL))) {
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +92,7 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
} else {
|
||||
/* locking problem with netif_stop_queue() ?? */
|
||||
netdev_err(dev, "%s: BUG! echo_skb %d is occupied!\n", __func__, idx);
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +229,7 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
|
|||
|
||||
csx = can_skb_ext_add(skb);
|
||||
if (!csx) {
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
goto out_error_cc;
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +260,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,
|
|||
|
||||
csx = can_skb_ext_add(skb);
|
||||
if (!csx) {
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
goto out_error_fd;
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +298,7 @@ struct sk_buff *alloc_canxl_skb(struct net_device *dev,
|
|||
|
||||
csx = can_skb_ext_add(skb);
|
||||
if (!csx) {
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
goto out_error_xl;
|
||||
}
|
||||
|
||||
|
|
@ -403,7 +404,7 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
|
|||
return false;
|
||||
|
||||
inval_skb:
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
dev->stats.tx_dropped++;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_buff *s
|
|||
return can_dropped_invalid_skb(dev, skb);
|
||||
|
||||
invalid_skb:
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
dev->stats.tx_dropped++;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,12 +78,12 @@ static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb)
|
|||
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (unlikely(!nskb)) {
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
can_skb_set_owner(nskb, skb->sk);
|
||||
consume_skb(skb);
|
||||
dev_consume_skb_any(skb);
|
||||
return nskb;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user