summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2026-01-15 13:13:01 +0100
committerPaolo Abeni <pabeni@redhat.com>2026-01-15 13:13:01 +0100
commit851822aec1a3359ecb7a4767d7f4a32336043c2f (patch)
tree8158d1ebef93caf727b73fd63c7727d0057ac6b6 /net
parent5ce234a8fe05798b5e6c1dff674776dab933b43b (diff)
parent1809c82aa073a11b7d335ae932d81ce51a588a4a (diff)
Merge tag 'linux-can-fixes-for-6.19-20260115' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2026-01-15 this is a pull request of 4 patches for net/main, it super-seeds the "can 2026-01-14" pull request. The dev refcount leak in patch #3 is fixed. The first 3 patches are by Oliver Hartkopp and revert the approach to instantly reject unsupported CAN frames introduced in net-next-for-v6.19 and replace it by placing the needed data into the CAN specific ml_priv. The last patch is by Tetsuo Handa and fixes a J1939 refcount leak for j1939_session in session deactivation upon receiving the second RTS. linux-can-fixes-for-6.19-20260115 * tag 'linux-can-fixes-for-6.19-20260115' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can: net: can: j1939: j1939_xtp_rx_rts_session_active(): deactivate session upon receiving the second rts can: raw: instantly reject disabled CAN frames can: propagate CAN device capabilities via ml_priv Revert "can: raw: instantly reject unsupported CAN frames" ==================== Link: https://patch.msgid.link/20260115090603.1124860-1-mkl@pengutronix.de Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/can/j1939/transport.c10
-rw-r--r--net/can/raw.c51
2 files changed, 19 insertions, 42 deletions
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index 613a911dda10..8656ab388c83 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -1695,8 +1695,16 @@ static int j1939_xtp_rx_rts_session_active(struct j1939_session *session,
j1939_session_timers_cancel(session);
j1939_session_cancel(session, J1939_XTP_ABORT_BUSY);
- if (session->transmission)
+ if (session->transmission) {
j1939_session_deactivate_activate_next(session);
+ } else if (session->state == J1939_SESSION_WAITING_ABORT) {
+ /* Force deactivation for the receiver.
+ * If we rely on the timer starting in j1939_session_cancel,
+ * a second RTS call here will cancel that timer and fail
+ * to restart it because the state is already WAITING_ABORT.
+ */
+ j1939_session_deactivate_activate_next(session);
+ }
return -EBUSY;
}
diff --git a/net/can/raw.c b/net/can/raw.c
index be1ef7cf4204..12293363413c 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -49,8 +49,8 @@
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/can.h>
+#include <linux/can/can-ml.h>
#include <linux/can/core.h>
-#include <linux/can/dev.h> /* for can_is_canxl_dev_mtu() */
#include <linux/can/skb.h>
#include <linux/can/raw.h>
#include <net/sock.h>
@@ -892,58 +892,21 @@ static void raw_put_canxl_vcid(struct raw_sock *ro, struct sk_buff *skb)
}
}
-static inline bool raw_dev_cc_enabled(struct net_device *dev,
- struct can_priv *priv)
-{
- /* The CANXL-only mode disables error-signalling on the CAN bus
- * which is needed to send CAN CC/FD frames
- */
- if (priv)
- return !can_dev_in_xl_only_mode(priv);
-
- /* virtual CAN interfaces always support CAN CC */
- return true;
-}
-
-static inline bool raw_dev_fd_enabled(struct net_device *dev,
- struct can_priv *priv)
-{
- /* check FD ctrlmode on real CAN interfaces */
- if (priv)
- return (priv->ctrlmode & CAN_CTRLMODE_FD);
-
- /* check MTU for virtual CAN FD interfaces */
- return (READ_ONCE(dev->mtu) >= CANFD_MTU);
-}
-
-static inline bool raw_dev_xl_enabled(struct net_device *dev,
- struct can_priv *priv)
-{
- /* check XL ctrlmode on real CAN interfaces */
- if (priv)
- return (priv->ctrlmode & CAN_CTRLMODE_XL);
-
- /* check MTU for virtual CAN XL interfaces */
- return can_is_canxl_dev_mtu(READ_ONCE(dev->mtu));
-}
-
static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff *skb,
struct net_device *dev)
{
- struct can_priv *priv = safe_candev_priv(dev);
-
/* Classical CAN */
- if (can_is_can_skb(skb) && raw_dev_cc_enabled(dev, priv))
+ if (can_is_can_skb(skb) && can_cap_enabled(dev, CAN_CAP_CC))
return CAN_MTU;
/* CAN FD */
if (ro->fd_frames && can_is_canfd_skb(skb) &&
- raw_dev_fd_enabled(dev, priv))
+ can_cap_enabled(dev, CAN_CAP_FD))
return CANFD_MTU;
/* CAN XL */
if (ro->xl_frames && can_is_canxl_skb(skb) &&
- raw_dev_xl_enabled(dev, priv))
+ can_cap_enabled(dev, CAN_CAP_XL))
return CANXL_MTU;
return 0;
@@ -982,6 +945,12 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
if (!dev)
return -ENXIO;
+ /* no sending on a CAN device in read-only mode */
+ if (can_cap_enabled(dev, CAN_CAP_RO)) {
+ err = -EACCES;
+ goto put_dev;
+ }
+
skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv),
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)