* [PATCH v2 1/2] can: dev: can_put_echo_skb(): use dev_kfree_skb_any()
[not found] <20260731-master-v2-0-204d772f2e36@qq.com>
@ 2026-07-31 8:23 ` Cunhao Lu
2026-07-31 8:37 ` sashiko-bot
2026-07-31 8:23 ` [PATCH v2 2/2] can: dev: can_put_echo_skb(): free skb on invalid echo index Cunhao Lu
1 sibling, 1 reply; 3+ messages in thread
From: Cunhao Lu @ 2026-07-31 8:23 UTC (permalink / raw)
To: Marc Kleine-Budde, Vincent Mailhol; +Cc: linux-can, linux-kernel, Cunhao Lu
can_put_echo_skb() is a public helper used by CAN drivers, so its callers
do not have a guaranteed IRQ context. kfree_skb() cannot be called from
hardware interrupt context or with hardware interrupts disabled.
Use dev_kfree_skb_any() for the existing skb drop paths so that they are
safe regardless of the caller's IRQ context.
Signed-off-by: Cunhao Lu <1579567540@qq.com>
---
drivers/net/can/dev/skb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 95fcdc1026f8..d7b5a5d17ff2 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -62,7 +62,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;
}
@@ -90,7 +90,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;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 2/2] can: dev: can_put_echo_skb(): free skb on invalid echo index
[not found] <20260731-master-v2-0-204d772f2e36@qq.com>
2026-07-31 8:23 ` [PATCH v2 1/2] can: dev: can_put_echo_skb(): use dev_kfree_skb_any() Cunhao Lu
@ 2026-07-31 8:23 ` Cunhao Lu
1 sibling, 0 replies; 3+ messages in thread
From: Cunhao Lu @ 2026-07-31 8:23 UTC (permalink / raw)
To: Marc Kleine-Budde, Vincent Mailhol
Cc: linux-can, linux-kernel, Cunhao Lu, stable
can_put_echo_skb() consumes the skb on all paths except when the echo index
is out of bounds. This leaves ownership with the caller on -EINVAL, unlike
the other error paths, and can leak the skb if the caller expects
consistent semantics.
Free the skb before returning -EINVAL so that all return paths consume it.
Fixes: 6411959c10fe ("can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds")
Cc: stable@vger.kernel.org
Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Cunhao Lu <1579567540@qq.com>
---
Changes in v2:
- Free the skb with dev_kfree_skb_any() on an invalid echo index.
- Collect Vincent's Reviewed-by tag
---
drivers/net/can/dev/skb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index d7b5a5d17ff2..c996cc2b417b 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -54,6 +54,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;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2 1/2] can: dev: can_put_echo_skb(): use dev_kfree_skb_any()
2026-07-31 8:23 ` [PATCH v2 1/2] can: dev: can_put_echo_skb(): use dev_kfree_skb_any() Cunhao Lu
@ 2026-07-31 8:37 ` sashiko-bot
0 siblings, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-07-31 8:37 UTC (permalink / raw)
To: Cunhao Lu
Cc: Oleksij Rempel, Oliver Hartkopp, linux-can, Marc Kleine-Budde,
Vincent Mailhol
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
Pre-existing issues:
- [High] The patch fails to make can_put_echo_skb() completely safe for hardware interrupt context because it overlooks the inline helper can_create_echo_skb().
- [High] The out-of-bounds error path in can_put_echo_skb() leaks the SKB.
- [High] Unsafe kfree_skb() usage remains in CAN SKB allocation helpers which are explicitly called from hardware interrupt handlers.
- [High] can_dev_dropped_skb() and can_dropped_invalid_skb() use kfree_skb() instead of dev_kfree_skb_any(), risking execution in IRQ-disabled contexts.
--
--- Patch [1]: [PATCH v2 1/2] can: dev: can_put_echo_skb(): use dev_kfree_skb_any() ---
commit af16d148470d669cda96f722b1dffb79b817c3f9
Author: Cunhao Lu <1579567540@qq.com>
can: dev: can_put_echo_skb(): use dev_kfree_skb_any()
can_put_echo_skb() is a public helper used by CAN drivers, so its callers
do not have a guaranteed IRQ context. kfree_skb() cannot be called from
hardware interrupt context or with hardware interrupts disabled.
Use dev_kfree_skb_any() for the existing skb drop paths so that they are
safe regardless of the caller's IRQ context.
> diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
> index 95fcdc1026f80..d7b5a5d17ff22 100644
> --- a/drivers/net/can/dev/skb.c
> +++ b/drivers/net/can/dev/skb.c
[Severity: High]
This isn't a bug introduced by this patch, but does the out-of-bounds error
path in can_put_echo_skb() leak the SKB?
If the bounds check fails, the function logs a BUG and returns without
freeing the skb:
drivers/net/can/dev/skb.c:can_put_echo_skb() {
if (idx >= priv->echo_skb_max) {
netdev_err(dev, "%s: BUG! ...\n", __func__, idx, priv->echo_skb_max);
return -EINVAL;
}
...
}
Many CAN driver callers assume can_put_echo_skb() takes ownership of the skb
and frees it on error. Does this lead to a memory leak when the bounds check
fails?
> @@ -62,7 +62,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;
> }
>
[Severity: High]
This is a pre-existing issue, but does this patch fail to make
can_put_echo_skb() completely safe for hardware interrupt context?
While dev_kfree_skb_any() is now used in the direct drop paths, the main
execution path calls the inline helper can_create_echo_skb():
drivers/net/can/dev/skb.c:can_put_echo_skb() {
...
if (!priv->echo_skb[idx]) {
skb = can_create_echo_skb(skb);
...
}
can_create_echo_skb() continues to invoke kfree_skb() on allocation failure
and consume_skb() on success:
include/linux/can/skb.h:can_create_echo_skb() {
...
kfree_skb(skb);
...
consume_skb(skb);
...
}
Since both are unsafe to call from hardirq context or with interrupts
disabled, does this defeat the purpose of the patch?
> @@ -90,7 +90,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;
> }
>
[Severity: High]
This is a pre-existing issue, but do can_dev_dropped_skb() and
can_dropped_invalid_skb() still risk execution in IRQ-disabled contexts?
These functions are called in the exact same ndo_start_xmit paths, right
before can_put_echo_skb(), and they still invoke kfree_skb() on their drop
paths:
include/linux/can/dev.h:can_dev_dropped_skb() {
...
invalid_skb:
kfree_skb(skb);
dev->stats.tx_dropped++;
return true;
}
drivers/net/can/dev/skb.c:can_dropped_invalid_skb() {
...
inval_skb:
kfree_skb(skb);
dev->stats.tx_dropped++;
return true;
}
This leaves the system vulnerable to the same crashes this patch attempts to
resolve.
[Severity: High]
This isn't a bug introduced by this patch, but do unsafe kfree_skb() calls
remain in CAN SKB allocation helpers that run in hardware interrupt handlers?
CAN drivers use alloc_can_skb(), alloc_canfd_skb(), and alloc_canxl_skb() in
their RX paths, which often run in hardirq context. If memory allocation for
the CAN SKB extension fails in can_skb_ext_add(), these helpers drop the
allocated SKB using kfree_skb():
drivers/net/can/dev/skb.c:alloc_can_skb() {
...
if (!csx) {
kfree_skb(skb);
goto out_error_cc;
}
...
}
Calling kfree_skb() in hardirq context is strictly forbidden and can trigger
warnings or panics. Should these also be updated to use dev_kfree_skb_any()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260731-master-v2-0-204d772f2e36@qq.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-31 8:37 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260731-master-v2-0-204d772f2e36@qq.com>
2026-07-31 8:23 ` [PATCH v2 1/2] can: dev: can_put_echo_skb(): use dev_kfree_skb_any() Cunhao Lu
2026-07-31 8:37 ` sashiko-bot
2026-07-31 8:23 ` [PATCH v2 2/2] can: dev: can_put_echo_skb(): free skb on invalid echo index Cunhao Lu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.