summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Starke <daniel.starke@siemens.com>2022-04-14 02:42:09 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-05-09 09:05:07 +0200
commit26f127f6d9385e32c0a5720e5358ae7f28bbd33a (patch)
treef74e3c23feb7efc8c0ecea3f883bd72f778acde6 /drivers
parentf26c271492b6ec15c8bd274fd220b7835f5ebc3d (diff)
tty: n_gsm: fix mux cleanup after unregister tty device
commit 284260f278b706364fb4c88a7b56ba5298d5973c upstream. Internally, we manage the alive state of the mux channels and mux itself with the field member 'dead'. This makes it possible to notify the user if the accessed underlying link is already gone. On the other hand, however, removing the virtual ttys before terminating the channels may result in peer messages being received without any internal target. Move the mux cleanup procedure from gsmld_detach_gsm() to gsmld_close() to fix this by keeping the virtual ttys open until the mux has been cleaned up. Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Cc: stable@vger.kernel.org Signed-off-by: Daniel Starke <daniel.starke@siemens.com> Link: https://lore.kernel.org/r/20220414094225.4527-4-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/n_gsm.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 87ea44108938..0513c243b20c 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2410,7 +2410,6 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
WARN_ON(tty != gsm->tty);
for (i = 1; i < NUM_DLCI; i++)
tty_unregister_device(gsm_tty_driver, base + i);
- gsm_cleanup_mux(gsm, false);
tty_kref_put(gsm->tty);
gsm->tty = NULL;
}
@@ -2478,6 +2477,12 @@ static void gsmld_close(struct tty_struct *tty)
{
struct gsm_mux *gsm = tty->disc_data;
+ /* The ldisc locks and closes the port before calling our close. This
+ * means we have no way to do a proper disconnect. We will not bother
+ * to do one.
+ */
+ gsm_cleanup_mux(gsm, false);
+
gsmld_detach_gsm(tty, gsm);
gsmld_flush_buffer(tty);