From: Johan Hovold <johan@xxxxxxxxxx> commit cd20d59291d1790dc74248476e928f57fc455189 upstream. Registration of the ipoctal tty devices is unlikely to fail, but if it ever does, make sure not to deregister a never registered tty device (and dereference a NULL pointer) when the driver is later unbound. Fixes: 2afb41d9d30d ("Staging: ipack/devices/ipoctal: Check tty_register_device return value.") Cc: stable@xxxxxxxxxxxxxxx # 3.7 Acked-by: Samuel Iglesias Gonsalvez <siglesias@xxxxxxxxxx> Signed-off-by: Johan Hovold <johan@xxxxxxxxxx> Link: https://lore.kernel.org/r/20210917114622.5412-4-johan@xxxxxxxxxx Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/ipack/devices/ipoctal.c | 7 +++++++ 1 file changed, 7 insertions(+) --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -33,6 +33,7 @@ struct ipoctal_channel { unsigned int pointer_read; unsigned int pointer_write; struct tty_port tty_port; + bool tty_registered; union scc2698_channel __iomem *regs; union scc2698_block __iomem *block_regs; unsigned int board_id; @@ -397,9 +398,11 @@ static int ipoctal_inst_slot(struct ipoc i, NULL, channel, NULL); if (IS_ERR(tty_dev)) { dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); + tty_port_free_xmit_buf(&channel->tty_port); tty_port_destroy(&channel->tty_port); continue; } + channel->tty_registered = true; } /* @@ -699,6 +702,10 @@ static void __ipoctal_remove(struct ipoc for (i = 0; i < NR_CHANNELS; i++) { struct ipoctal_channel *channel = &ipoctal->channel[i]; + + if (!channel->tty_registered) + continue; + tty_unregister_device(ipoctal->tty_drv, i); tty_port_free_xmit_buf(&channel->tty_port); tty_port_destroy(&channel->tty_port);