From: Greg Kroah-Hartman Date: Tue, 3 May 2022 13:43:05 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v5.4.192~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7cca91e34853a43e3d8b248c45fd44863a50de09;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: tty-n_gsm-fix-incorrect-ua-handling.patch tty-n_gsm-fix-insufficient-txframe-size.patch tty-n_gsm-fix-missing-explicit-ldisc-flush.patch tty-n_gsm-fix-reset-fifo-race-condition.patch tty-n_gsm-fix-software-flow-control-handling.patch tty-n_gsm-fix-wrong-command-frame-length-field-encoding.patch tty-n_gsm-fix-wrong-command-retry-handling.patch tty-n_gsm-fix-wrong-dlci-release-order.patch --- diff --git a/queue-5.10/series b/queue-5.10/series index 13132ec09ca..00638a24c07 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -118,3 +118,11 @@ tty-n_gsm-fix-mux-cleanup-after-unregister-tty-device.patch tty-n_gsm-fix-wrong-signal-octet-encoding-in-convergence-layer-type-2.patch tty-n_gsm-fix-malformed-counter-for-out-of-frame-data.patch netfilter-nft_socket-only-do-sk-lookups-when-indev-is-available.patch +tty-n_gsm-fix-insufficient-txframe-size.patch +tty-n_gsm-fix-wrong-dlci-release-order.patch +tty-n_gsm-fix-missing-explicit-ldisc-flush.patch +tty-n_gsm-fix-wrong-command-retry-handling.patch +tty-n_gsm-fix-wrong-command-frame-length-field-encoding.patch +tty-n_gsm-fix-reset-fifo-race-condition.patch +tty-n_gsm-fix-incorrect-ua-handling.patch +tty-n_gsm-fix-software-flow-control-handling.patch diff --git a/queue-5.10/tty-n_gsm-fix-incorrect-ua-handling.patch b/queue-5.10/tty-n_gsm-fix-incorrect-ua-handling.patch new file mode 100644 index 00000000000..6e3143e14d5 --- /dev/null +++ b/queue-5.10/tty-n_gsm-fix-incorrect-ua-handling.patch @@ -0,0 +1,38 @@ +From ff9166c623704337bd6fe66fce2838d9768a6634 Mon Sep 17 00:00:00 2001 +From: Daniel Starke +Date: Thu, 14 Apr 2022 02:42:25 -0700 +Subject: tty: n_gsm: fix incorrect UA handling + +From: Daniel Starke + +commit ff9166c623704337bd6fe66fce2838d9768a6634 upstream. + +n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. +See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 +The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to +the newer 27.010 here. Chapter 5.4.4.2 states that any received unnumbered +acknowledgment (UA) with its poll/final (PF) bit set to 0 shall be +discarded. Currently, all UA frame are handled in the same way regardless +of the PF bit. This does not comply with the standard. +Remove the UA case in gsm_queue() to process only UA frames with PF bit set +to 1 to abide the standard. + +Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Starke +Link: https://lore.kernel.org/r/20220414094225.4527-20-daniel.starke@siemens.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_gsm.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -1817,7 +1817,6 @@ static void gsm_queue(struct gsm_mux *gs + gsm_response(gsm, address, UA); + gsm_dlci_close(dlci); + break; +- case UA: + case UA|PF: + if (cr == 0 || dlci == NULL) + break; diff --git a/queue-5.10/tty-n_gsm-fix-insufficient-txframe-size.patch b/queue-5.10/tty-n_gsm-fix-insufficient-txframe-size.patch new file mode 100644 index 00000000000..67bd79a60af --- /dev/null +++ b/queue-5.10/tty-n_gsm-fix-insufficient-txframe-size.patch @@ -0,0 +1,52 @@ +From 535bf600de75a859698892ee873521a48d289ec1 Mon Sep 17 00:00:00 2001 +From: Daniel Starke +Date: Thu, 14 Apr 2022 02:42:13 -0700 +Subject: tty: n_gsm: fix insufficient txframe size + +From: Daniel Starke + +commit 535bf600de75a859698892ee873521a48d289ec1 upstream. + +n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. +See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 +The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to +the newer 27.010 here. Chapter 5.7.2 states that the maximum frame size +(N1) refers to the length of the information field (i.e. user payload). +However, 'txframe' stores the whole frame including frame header, checksum +and start/end flags. We also need to consider the byte stuffing overhead. +Define constant for the protocol overhead and adjust the 'txframe' size +calculation accordingly to reserve enough space for a complete mux frame +including byte stuffing for advanced option mode. Note that no byte +stuffing is applied to the start and end flag. +Also use MAX_MTU instead of MAX_MRU as this buffer is used for data +transmission. + +Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Starke +Link: https://lore.kernel.org/r/20220414094225.4527-8-daniel.starke@siemens.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_gsm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -72,6 +72,8 @@ module_param(debug, int, 0600); + */ + #define MAX_MRU 1500 + #define MAX_MTU 1500 ++/* SOF, ADDR, CTRL, LEN1, LEN2, ..., FCS, EOF */ ++#define PROT_OVERHEAD 7 + #define GSM_NET_TX_TIMEOUT (HZ*10) + + /** +@@ -2191,7 +2193,7 @@ static struct gsm_mux *gsm_alloc_mux(voi + kfree(gsm); + return NULL; + } +- gsm->txframe = kmalloc(2 * MAX_MRU + 2, GFP_KERNEL); ++ gsm->txframe = kmalloc(2 * (MAX_MTU + PROT_OVERHEAD - 1), GFP_KERNEL); + if (gsm->txframe == NULL) { + kfree(gsm->buf); + kfree(gsm); diff --git a/queue-5.10/tty-n_gsm-fix-missing-explicit-ldisc-flush.patch b/queue-5.10/tty-n_gsm-fix-missing-explicit-ldisc-flush.patch new file mode 100644 index 00000000000..0357e1b1f88 --- /dev/null +++ b/queue-5.10/tty-n_gsm-fix-missing-explicit-ldisc-flush.patch @@ -0,0 +1,35 @@ +From 17eac652028501df7ea296b1d9b9c134db262b7d Mon Sep 17 00:00:00 2001 +From: Daniel Starke +Date: Thu, 14 Apr 2022 02:42:15 -0700 +Subject: tty: n_gsm: fix missing explicit ldisc flush + +From: Daniel Starke + +commit 17eac652028501df7ea296b1d9b9c134db262b7d upstream. + +In gsm_cleanup_mux() the muxer is closed down and all queues are removed. +However, removing the queues is done without explicit control of the +underlying buffers. Flush those before freeing up our queues to ensure +that all outgoing queues are cleared consistently. Otherwise, a new mux +connection establishment attempt may time out while the underlying tty is +still busy sending out the remaining data from the previous connection. + +Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Starke +Link: https://lore.kernel.org/r/20220414094225.4527-10-daniel.starke@siemens.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_gsm.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -2079,6 +2079,7 @@ static void gsm_cleanup_mux(struct gsm_m + gsm_dlci_release(gsm->dlci[i]); + mutex_unlock(&gsm->mutex); + /* Now wipe the queues */ ++ tty_ldisc_flush(gsm->tty); + list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) + kfree(txq); + INIT_LIST_HEAD(&gsm->tx_list); diff --git a/queue-5.10/tty-n_gsm-fix-reset-fifo-race-condition.patch b/queue-5.10/tty-n_gsm-fix-reset-fifo-race-condition.patch new file mode 100644 index 00000000000..2d2949e9575 --- /dev/null +++ b/queue-5.10/tty-n_gsm-fix-reset-fifo-race-condition.patch @@ -0,0 +1,61 @@ +From 73029a4d7161f8b6c0934553145ef574d2d0c645 Mon Sep 17 00:00:00 2001 +From: Daniel Starke +Date: Thu, 14 Apr 2022 02:42:22 -0700 +Subject: tty: n_gsm: fix reset fifo race condition + +From: Daniel Starke + +commit 73029a4d7161f8b6c0934553145ef574d2d0c645 upstream. + +gsmtty_write() and gsm_dlci_data_output() properly guard the fifo access. +However, gsm_dlci_close() and gsmtty_flush_buffer() modifies the fifo but +do not guard this. +Add a guard here to prevent race conditions on parallel writes to the fifo. + +Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Starke +Link: https://lore.kernel.org/r/20220414094225.4527-17-daniel.starke@siemens.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_gsm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -1422,13 +1422,17 @@ static int gsm_control_wait(struct gsm_m + + static void gsm_dlci_close(struct gsm_dlci *dlci) + { ++ unsigned long flags; ++ + del_timer(&dlci->t1); + if (debug & 8) + pr_debug("DLCI %d goes closed.\n", dlci->addr); + dlci->state = DLCI_CLOSED; + if (dlci->addr != 0) { + tty_port_tty_hangup(&dlci->port, false); ++ spin_lock_irqsave(&dlci->lock, flags); + kfifo_reset(&dlci->fifo); ++ spin_unlock_irqrestore(&dlci->lock, flags); + /* Ensure that gsmtty_open() can return. */ + tty_port_set_initialized(&dlci->port, 0); + wake_up_interruptible(&dlci->port.open_wait); +@@ -3078,13 +3082,17 @@ static int gsmtty_chars_in_buffer(struct + static void gsmtty_flush_buffer(struct tty_struct *tty) + { + struct gsm_dlci *dlci = tty->driver_data; ++ unsigned long flags; ++ + if (dlci->state == DLCI_CLOSED) + return; + /* Caution needed: If we implement reliable transport classes + then the data being transmitted can't simply be junked once + it has first hit the stack. Until then we can just blow it + away */ ++ spin_lock_irqsave(&dlci->lock, flags); + kfifo_reset(&dlci->fifo); ++ spin_unlock_irqrestore(&dlci->lock, flags); + /* Need to unhook this DLCI from the transmit queue logic */ + } + diff --git a/queue-5.10/tty-n_gsm-fix-software-flow-control-handling.patch b/queue-5.10/tty-n_gsm-fix-software-flow-control-handling.patch new file mode 100644 index 00000000000..48841bebd89 --- /dev/null +++ b/queue-5.10/tty-n_gsm-fix-software-flow-control-handling.patch @@ -0,0 +1,86 @@ +From f4f7d63287217ba25e5c80f5faae5e4f7118790e Mon Sep 17 00:00:00 2001 +From: Daniel Starke +Date: Fri, 22 Apr 2022 00:10:25 -0700 +Subject: tty: n_gsm: fix software flow control handling + +From: Daniel Starke + +commit f4f7d63287217ba25e5c80f5faae5e4f7118790e upstream. + +n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. +See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 +The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to +the newer 27.010 here. Chapter 5.4.8.1 states that XON/XOFF characters +shall be used instead of Fcon/Fcoff command in advanced option mode to +handle flow control. Chapter 5.4.8.2 describes how XON/XOFF characters +shall be handled. Basic option mode only used Fcon/Fcoff commands and no +XON/XOFF characters. These are treated as data bytes here. +The current implementation uses the gsm_mux field 'constipated' to handle +flow control from the remote peer and the gsm_dlci field 'constipated' to +handle flow control from each DLCI. The later is unrelated to this patch. +The gsm_mux field is correctly set for Fcon/Fcoff commands in +gsm_control_message(). However, the same is not true for XON/XOFF +characters in gsm1_receive(). +Disable software flow control handling in the tty to allow explicit +handling by n_gsm. +Add the missing handling in advanced option mode for gsm_mux in +gsm1_receive() to comply with the standard. + +This patch depends on the following commit: +Commit 8838b2af23ca ("tty: n_gsm: fix SW flow control encoding/handling") + +Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Starke +Link: https://lore.kernel.org/r/20220422071025.5490-3-daniel.starke@siemens.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_gsm.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -232,6 +232,7 @@ struct gsm_mux { + int initiator; /* Did we initiate connection */ + bool dead; /* Has the mux been shut down */ + struct gsm_dlci *dlci[NUM_DLCI]; ++ int old_c_iflag; /* termios c_iflag value before attach */ + bool constipated; /* Asked by remote to shut up */ + + spinlock_t tx_lock; +@@ -1960,6 +1961,16 @@ static void gsm0_receive(struct gsm_mux + + static void gsm1_receive(struct gsm_mux *gsm, unsigned char c) + { ++ /* handle XON/XOFF */ ++ if ((c & ISO_IEC_646_MASK) == XON) { ++ gsm->constipated = true; ++ return; ++ } else if ((c & ISO_IEC_646_MASK) == XOFF) { ++ gsm->constipated = false; ++ /* Kick the link in case it is idling */ ++ gsm_data_kick(gsm, NULL); ++ return; ++ } + if (c == GSM1_SOF) { + /* EOF is only valid in frame if we have got to the data state + and received at least one byte (the FCS) */ +@@ -2378,6 +2389,9 @@ static int gsmld_attach_gsm(struct tty_s + int ret, i; + + gsm->tty = tty_kref_get(tty); ++ /* Turn off tty XON/XOFF handling to handle it explicitly. */ ++ gsm->old_c_iflag = tty->termios.c_iflag; ++ tty->termios.c_iflag &= (IXON | IXOFF); + ret = gsm_activate_mux(gsm); + if (ret != 0) + tty_kref_put(gsm->tty); +@@ -2418,6 +2432,8 @@ static void gsmld_detach_gsm(struct tty_ + WARN_ON(tty != gsm->tty); + for (i = 1; i < NUM_DLCI; i++) + tty_unregister_device(gsm_tty_driver, base + i); ++ /* Restore tty XON/XOFF handling. */ ++ gsm->tty->termios.c_iflag = gsm->old_c_iflag; + tty_kref_put(gsm->tty); + gsm->tty = NULL; + } diff --git a/queue-5.10/tty-n_gsm-fix-wrong-command-frame-length-field-encoding.patch b/queue-5.10/tty-n_gsm-fix-wrong-command-frame-length-field-encoding.patch new file mode 100644 index 00000000000..e5e4648acf3 --- /dev/null +++ b/queue-5.10/tty-n_gsm-fix-wrong-command-frame-length-field-encoding.patch @@ -0,0 +1,76 @@ +From 398867f59f956985f4c324f173eff7b946e14bd8 Mon Sep 17 00:00:00 2001 +From: Daniel Starke +Date: Thu, 14 Apr 2022 02:42:17 -0700 +Subject: tty: n_gsm: fix wrong command frame length field encoding + +From: Daniel Starke + +commit 398867f59f956985f4c324f173eff7b946e14bd8 upstream. + +n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. +See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 +The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to +the newer 27.010 here. Chapter 5.4.6.1 states that each command frame shall +be made up from type, length and value. Looking for example in chapter +5.4.6.3.5 at the description for the encoding of a flow control on command +it becomes obvious, that the type and length field is always present +whereas the value may be zero bytes long. The current implementation omits +the length field if the value is not present. This is wrong. +Correct this by always sending the length in gsm_control_transmit(). +So far only the modem status command (MSC) has included a value and encoded +its length directly. Therefore, also change gsmtty_modem_update(). + +Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Starke +Link: https://lore.kernel.org/r/20220414094225.4527-12-daniel.starke@siemens.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_gsm.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -1297,11 +1297,12 @@ static void gsm_control_response(struct + + static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl) + { +- struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 1, gsm->ftype); ++ struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 2, gsm->ftype); + if (msg == NULL) + return; +- msg->data[0] = (ctrl->cmd << 1) | 2 | EA; /* command */ +- memcpy(msg->data + 1, ctrl->data, ctrl->len); ++ msg->data[0] = (ctrl->cmd << 1) | CR | EA; /* command */ ++ msg->data[1] = (ctrl->len << 1) | EA; ++ memcpy(msg->data + 2, ctrl->data, ctrl->len); + gsm_data_queue(gsm->dlci[0], msg); + } + +@@ -2882,19 +2883,17 @@ static struct tty_ldisc_ops tty_ldisc_pa + + static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk) + { +- u8 modembits[5]; ++ u8 modembits[3]; + struct gsm_control *ctrl; + int len = 2; + +- if (brk) ++ modembits[0] = (dlci->addr << 2) | 2 | EA; /* DLCI, Valid, EA */ ++ modembits[1] = (gsm_encode_modem(dlci) << 1) | EA; ++ if (brk) { ++ modembits[2] = (brk << 4) | 2 | EA; /* Length, Break, EA */ + len++; +- +- modembits[0] = len << 1 | EA; /* Data bytes */ +- modembits[1] = dlci->addr << 2 | 3; /* DLCI, EA, 1 */ +- modembits[2] = gsm_encode_modem(dlci) << 1 | EA; +- if (brk) +- modembits[3] = brk << 4 | 2 | EA; /* Valid, EA */ +- ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len + 1); ++ } ++ ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len); + if (ctrl == NULL) + return -ENOMEM; + return gsm_control_wait(dlci->gsm, ctrl); diff --git a/queue-5.10/tty-n_gsm-fix-wrong-command-retry-handling.patch b/queue-5.10/tty-n_gsm-fix-wrong-command-retry-handling.patch new file mode 100644 index 00000000000..332979f710a --- /dev/null +++ b/queue-5.10/tty-n_gsm-fix-wrong-command-retry-handling.patch @@ -0,0 +1,66 @@ +From d0bcdffcad5a22f202e3bf37190c0dd8c080ea92 Mon Sep 17 00:00:00 2001 +From: Daniel Starke +Date: Thu, 14 Apr 2022 02:42:16 -0700 +Subject: tty: n_gsm: fix wrong command retry handling + +From: Daniel Starke + +commit d0bcdffcad5a22f202e3bf37190c0dd8c080ea92 upstream. + +n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. +See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 +The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to +the newer 27.010 here. Chapter 5.7.3 states that the valid range for the +maximum number of retransmissions (N2) is from 0 to 255 (both including). +gsm_config() fails to limit this range correctly. Furthermore, +gsm_control_retransmit() handles this number incorrectly by performing +N2 - 1 retransmission attempts. Setting N2 to zero results in more than 255 +retransmission attempts. +Fix the range check in gsm_config() and the value handling in +gsm_control_send() and gsm_control_retransmit() to comply with 3GPP 27.010. + +Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Starke +Link: https://lore.kernel.org/r/20220414094225.4527-11-daniel.starke@siemens.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_gsm.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -1324,7 +1324,6 @@ static void gsm_control_retransmit(struc + spin_lock_irqsave(&gsm->control_lock, flags); + ctrl = gsm->pending_cmd; + if (ctrl) { +- gsm->cretries--; + if (gsm->cretries == 0) { + gsm->pending_cmd = NULL; + ctrl->error = -ETIMEDOUT; +@@ -1333,6 +1332,7 @@ static void gsm_control_retransmit(struc + wake_up(&gsm->event); + return; + } ++ gsm->cretries--; + gsm_control_transmit(gsm, ctrl); + mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100); + } +@@ -1373,7 +1373,7 @@ retry: + + /* If DLCI0 is in ADM mode skip retries, it won't respond */ + if (gsm->dlci[0]->mode == DLCI_MODE_ADM) +- gsm->cretries = 1; ++ gsm->cretries = 0; + else + gsm->cretries = gsm->n2; + +@@ -2270,7 +2270,7 @@ static int gsm_config(struct gsm_mux *gs + /* Check the MRU/MTU range looks sane */ + if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8) + return -EINVAL; +- if (c->n2 < 3) ++ if (c->n2 > 255) + return -EINVAL; + if (c->encapsulation > 1) /* Basic, advanced, no I */ + return -EINVAL; diff --git a/queue-5.10/tty-n_gsm-fix-wrong-dlci-release-order.patch b/queue-5.10/tty-n_gsm-fix-wrong-dlci-release-order.patch new file mode 100644 index 00000000000..3d703c52270 --- /dev/null +++ b/queue-5.10/tty-n_gsm-fix-wrong-dlci-release-order.patch @@ -0,0 +1,35 @@ +From deefc58bafb4841df7f0a0d85d89a1c819db9743 Mon Sep 17 00:00:00 2001 +From: Daniel Starke +Date: Thu, 14 Apr 2022 02:42:14 -0700 +Subject: tty: n_gsm: fix wrong DLCI release order + +From: Daniel Starke + +commit deefc58bafb4841df7f0a0d85d89a1c819db9743 upstream. + +The current DLCI release order starts with the control channel followed by +the user channels. Reverse this order to keep the control channel open +until all user channels have been released. + +Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Starke +Link: https://lore.kernel.org/r/20220414094225.4527-9-daniel.starke@siemens.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_gsm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -2073,8 +2073,8 @@ static void gsm_cleanup_mux(struct gsm_m + /* Finish outstanding timers, making sure they are done */ + del_timer_sync(&gsm->t2_timer); + +- /* Free up any link layer users */ +- for (i = 0; i < NUM_DLCI; i++) ++ /* Free up any link layer users and finally the control channel */ ++ for (i = NUM_DLCI - 1; i >= 0; i--) + if (gsm->dlci[i]) + gsm_dlci_release(gsm->dlci[i]); + mutex_unlock(&gsm->mutex);