From: Daniel Starke daniel.starke@siemens.com
stable inclusion from stable-v5.10.117 commit 6d47eceaf311ea7fdefa55975ef005556eecfa60 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5L66B
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit edd5f60c340086891fab094ad61270d6c80f9ca4 upstream.
The current implementation activates the mux if it was restarted and opens the control channel if the mux was previously closed and we are now acting as initiator instead of responder, which is the default setting. This has two issues. 1) No mux is activated if we keep all default values and only switch to initiator. The control channel is not allocated but will be opened next which results in a NULL pointer dereference. 2) Switching the configuration after it was once configured while keeping the initiator value the same will not reopen the control channel if it was closed due to parameter incompatibilities. The mux remains dead.
Fix 1) by always activating the mux if it is dead after configuration. Fix 2) by always opening the control channel after mux activation.
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/20220504081733.3494-2-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com --- drivers/tty/n_gsm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index aafc3bb60e52..b05b7862778c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2276,6 +2276,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm,
static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) { + int ret = 0; int need_close = 0; int need_restart = 0;
@@ -2343,10 +2344,13 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) * FIXME: We need to separate activation/deactivation from adding * and removing from the mux array */ - if (need_restart) - gsm_activate_mux(gsm); - if (gsm->initiator && need_close) - gsm_dlci_begin_open(gsm->dlci[0]); + if (gsm->dead) { + ret = gsm_activate_mux(gsm); + if (ret) + return ret; + if (gsm->initiator) + gsm_dlci_begin_open(gsm->dlci[0]); + } return 0; }