lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250714175520.307467-1-andrey.lalaev@gmail.com>
Date: Mon, 14 Jul 2025 19:55:02 +0200
From: Andrei Lalaev <andrey.lalaev@...il.com>
To: mkl@...gutronix.de,
	mailhol.vincent@...adoo.fr
Cc: andrey.lalaev@...il.com,
	linux-kernel@...r.kernel.org,
	linux-can@...r.kernel.org
Subject: [RFC PATCH] can: gs_usb: fix kernel oops during restart

When CAN adapter in BUS_OFF state and "can_restart" is called,
it causes the following kernel oops:

  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
  Internal error: Oops: 0000000086000005 [#1] PREEMPT SMP
  CPU: 0 UID: 0 PID: 725 Comm: ip Not tainted 6.12.37-v8-16k+ #2
  Hardware name: Raspberry Pi 5 Model B Rev 1.0 (DT)
  pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
  pc : 0x0
  lr : can_restart+0x80/0xf8 [can_dev]
  sp : ffffc000844f3700
  x29: ffffc000844f3710 x28: ffffd06fcf3389f8 x27: 0000000000000000
  x26: ffff800080ba0000 x25: 0000000000000000 x24: ffffd06f58730268
  x23: 0000000000000000 x22: 0000000000000001 x21: ffff8001001ef210
  x20: ffffc000844f3a10 x19: ffff800080ba0000 x18: 0000000000000000
  x17: 0000000000000002 x16: 000000005b38ca14 x15: 0000000000000400
  x14: 0000000000000800 x13: 000000005b482df7 x12: ffff800002d84280
  x11: 000000005b482df7 x10: ffff800002d84290 x9 : ffffd06fcf01f6ec
  x8 : 0000000000000000 x7 : 0000000000000000 x6 : 000000000000003f
  x5 : ffffd06fcef8ab30 x4 : 0000000000000008 x3 : 016b3b57a19d7300
  x2 : 0000000000000088 x1 : 0000000000000001 x0 : ffff800080ba0000
  Call trace:
   0x0
   can_restart_now+0x4c/0x70 [can_dev]
   can_changelink+0x258/0x458 [can_dev]
   rtnl_newlink+0x52c/0xa38
   rtnetlink_rcv_msg+0x238/0x338
   netlink_rcv_skb+0x128/0x148
   rtnetlink_rcv+0x24/0x38
   netlink_unicast+0x24c/0x408
   netlink_sendmsg+0x288/0x378
   ____sys_sendmsg+0x1bc/0x2a0
   __sys_sendmsg+0x144/0x1a0
   __arm64_sys_sendmsg+0x30/0x48
   invoke_syscall+0x4c/0x110
   el0_svc_common+0x8c/0xf0
   do_el0_svc+0x28/0x40
   el0_svc+0x34/0xa0
   el0t_64_sync_handler+0x84/0x100
   el0t_64_sync+0x190/0x198

Provide a "do_set_mode" callback to overcome the issue.

Signed-off-by: Andrei Lalaev <andrey.lalaev@...il.com>
---

The issue can be easily reproduced:
    ip link set can0 type can bitrate 100000
    ip link set up can0
    cangen can0

Then I force "BUS_OFF" by connecting CAN_HIGH to CAN_LOW.
And restart the interface:
    ip link set can0 type can restart


My knowledge about CAN is pretty limited, so I am not sure
if it is a correct or complete solution.

Could someone with more experience in CAN or the gs_usb driver confirm
whether this should be addressed by implementing the do_set_mode in gs_usb,
or if there's a better approach?

Thanks in advance!
---
 drivers/net/can/usb/gs_usb.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index bb6335278e46..0d66d843c1e3 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -748,6 +748,18 @@ static int gs_usb_set_data_bittiming(struct net_device *netdev)
 				    GFP_KERNEL);
 }
 
+static int gs_usb_do_set_mode(struct net_device *netdev, enum can_mode mode)
+{
+	switch (mode) {
+	case CAN_MODE_START:
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 static void gs_usb_xmit_callback(struct urb *urb)
 {
 	struct gs_tx_context *txc = urb->context;
@@ -1278,6 +1290,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 	dev->can.clock.freq = le32_to_cpu(bt_const.fclk_can);
 	dev->can.bittiming_const = &dev->bt_const;
 	dev->can.do_set_bittiming = gs_usb_set_bittiming;
+	dev->can.do_set_mode = gs_usb_do_set_mode;
 
 	dev->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC;
 
-- 
2.50.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ