can327_ldisc_open() publishes the private structure to the tty layer before registering the net_device: tty->disc_data = elm; err = register_candev(elm->dev); if (err) { free_candev(elm->dev); return err; } register_candev() fails with -ENOMEM from register_netdevice() when the device name node or the kobject cannot be allocated. The error path then frees the net_device and the can327 structure in its private area, while tty->disc_data still points at the freed memory. Publish the pointer only after the device is registered, so the error path has nothing to unwind. slcan does the same after its own patch, as do ppp_async and nci_uart. The stale pointer is not observable today: tty_set_termios_ldisc() clears tty->disc_data before .open() runs and again when a failed ldisc change falls back, and the ldisc entry points are serialised against .open() by tty_ldisc_ref() (async) and tty_ldisc_ref_wait() (syscall). The change removes a trap for the next modification of these functions. The success path was tested by attaching N_CAN327 to a pty under QEMU: the ldisc opens, creates the net_device and SIOCGIFNAME returns its name. The register_candev() failure path cannot be forced from userspace and is only compile tested. Assisted-by: LLM Signed-off-by: Chaosheng Qu --- drivers/net/can/can327.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c index 90f5e35f3c8f..d40dadbb5733 100644 --- a/drivers/net/can/can327.c +++ b/drivers/net/can/can327.c @@ -1037,7 +1037,6 @@ static int can327_ldisc_open(struct tty_struct *tty) /* Mark ldisc channel as alive */ elm->tty = tty; - tty->disc_data = elm; /* Let 'er rip */ err = register_candev(elm->dev); @@ -1046,6 +1045,8 @@ static int can327_ldisc_open(struct tty_struct *tty) return err; } + tty->disc_data = elm; + netdev_info(elm->dev, "can327 on %s.\n", tty->name); return 0; -- 2.43.0