Commit edd5f60c authored by Daniel Starke's avatar Daniel Starke Committed by Greg Kroah-Hartman

tty: n_gsm: fix mux activation issues in gsm_config()

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: e1eaea46 ("tty: n_gsm line discipline")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarDaniel Starke <daniel.starke@siemens.com>
Link: https://lore.kernel.org/r/20220504081733.3494-2-daniel.starke@siemens.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fd442e5b
...@@ -2352,6 +2352,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm, ...@@ -2352,6 +2352,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm,
static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
{ {
int ret = 0;
int need_close = 0; int need_close = 0;
int need_restart = 0; int need_restart = 0;
...@@ -2419,10 +2420,13 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) ...@@ -2419,10 +2420,13 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
* FIXME: We need to separate activation/deactivation from adding * FIXME: We need to separate activation/deactivation from adding
* and removing from the mux array * and removing from the mux array
*/ */
if (need_restart) if (gsm->dead) {
gsm_activate_mux(gsm); ret = gsm_activate_mux(gsm);
if (gsm->initiator && need_close) if (ret)
gsm_dlci_begin_open(gsm->dlci[0]); return ret;
if (gsm->initiator)
gsm_dlci_begin_open(gsm->dlci[0]);
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment