]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 28 Feb 2022 07:59:38 +0000 (08:59 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 28 Feb 2022 07:59:38 +0000 (08:59 +0100)
added patches:
tty-n_gsm-fix-deadlock-in-gsmtty_open.patch
tty-n_gsm-fix-encoding-of-command-response-bit.patch
tty-n_gsm-fix-null-pointer-access-due-to-dlci-release.patch
tty-n_gsm-fix-proper-link-termination-after-failed-open.patch
tty-n_gsm-fix-wrong-modem-processing-in-convergence-layer-type-2.patch
tty-n_gsm-fix-wrong-tty-control-line-for-flow-control.patch

queue-5.16/series
queue-5.16/tty-n_gsm-fix-deadlock-in-gsmtty_open.patch [new file with mode: 0644]
queue-5.16/tty-n_gsm-fix-encoding-of-command-response-bit.patch [new file with mode: 0644]
queue-5.16/tty-n_gsm-fix-null-pointer-access-due-to-dlci-release.patch [new file with mode: 0644]
queue-5.16/tty-n_gsm-fix-proper-link-termination-after-failed-open.patch [new file with mode: 0644]
queue-5.16/tty-n_gsm-fix-wrong-modem-processing-in-convergence-layer-type-2.patch [new file with mode: 0644]
queue-5.16/tty-n_gsm-fix-wrong-tty-control-line-for-flow-control.patch [new file with mode: 0644]

index 43772b5b0c476dd32c6411eb6ca85133e0df9106..a9a339f644c7dff392aa745492a573c3f510cc08 100644 (file)
@@ -152,3 +152,9 @@ riscv-fix-oops-caused-by-irqsoff-latency-tracer.patch
 mm-hugetlb-fix-kernel-crash-with-hugetlb-mremap.patch
 hugetlbfs-fix-a-truncation-issue-in-hugepages-parameter.patch
 tty-n_gsm-fix-encoding-of-control-signal-octet-bit-dv.patch
+tty-n_gsm-fix-encoding-of-command-response-bit.patch
+tty-n_gsm-fix-proper-link-termination-after-failed-open.patch
+tty-n_gsm-fix-null-pointer-access-due-to-dlci-release.patch
+tty-n_gsm-fix-wrong-tty-control-line-for-flow-control.patch
+tty-n_gsm-fix-wrong-modem-processing-in-convergence-layer-type-2.patch
+tty-n_gsm-fix-deadlock-in-gsmtty_open.patch
diff --git a/queue-5.16/tty-n_gsm-fix-deadlock-in-gsmtty_open.patch b/queue-5.16/tty-n_gsm-fix-deadlock-in-gsmtty_open.patch
new file mode 100644 (file)
index 0000000..fbe3973
--- /dev/null
@@ -0,0 +1,42 @@
+From a2ab75b8e76e455af7867e3835fd9cdf386b508f Mon Sep 17 00:00:00 2001
+From: "daniel.starke@siemens.com" <daniel.starke@siemens.com>
+Date: Thu, 17 Feb 2022 23:31:23 -0800
+Subject: tty: n_gsm: fix deadlock in gsmtty_open()
+
+From: daniel.starke@siemens.com <daniel.starke@siemens.com>
+
+commit a2ab75b8e76e455af7867e3835fd9cdf386b508f upstream.
+
+In the current implementation the user may open a virtual tty which then
+could fail to establish the underlying DLCI. The function gsmtty_open()
+gets stuck in tty_port_block_til_ready() while waiting for a carrier rise.
+This happens if the remote side fails to acknowledge the link establishment
+request in time or completely. At some point gsm_dlci_close() is called
+to abort the link establishment attempt. The function tries to inform the
+associated virtual tty by performing a hangup. But the blocking loop within
+tty_port_block_til_ready() is not informed about this event.
+The patch proposed here fixes this by resetting the initialization state of
+the virtual tty to ensure the loop exits and triggering it to make
+tty_port_block_til_ready() return.
+
+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/20220218073123.2121-7-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/n_gsm.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1457,6 +1457,9 @@ static void gsm_dlci_close(struct gsm_dl
+       if (dlci->addr != 0) {
+               tty_port_tty_hangup(&dlci->port, false);
+               kfifo_reset(&dlci->fifo);
++              /* Ensure that gsmtty_open() can return. */
++              tty_port_set_initialized(&dlci->port, 0);
++              wake_up_interruptible(&dlci->port.open_wait);
+       } else
+               dlci->gsm->dead = true;
+       /* Unregister gsmtty driver,report gsmtty dev remove uevent for user */
diff --git a/queue-5.16/tty-n_gsm-fix-encoding-of-command-response-bit.patch b/queue-5.16/tty-n_gsm-fix-encoding-of-command-response-bit.patch
new file mode 100644 (file)
index 0000000..3d615e1
--- /dev/null
@@ -0,0 +1,103 @@
+From 57435c42400ec147a527b2313188b649e81e449e Mon Sep 17 00:00:00 2001
+From: "daniel.starke@siemens.com" <daniel.starke@siemens.com>
+Date: Thu, 17 Feb 2022 23:31:18 -0800
+Subject: tty: n_gsm: fix encoding of command/response bit
+
+From: daniel.starke@siemens.com <daniel.starke@siemens.com>
+
+commit 57435c42400ec147a527b2313188b649e81e449e 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.2.1.2 describes the encoding of the
+C/R (command/response) bit. Table 1 shows that the actual encoding of the
+C/R bit is inverted if the associated frame is sent by the responder.
+
+The referenced commit fixed here further broke the internal meaning of this
+bit in the outgoing path by always setting the C/R bit regardless of the
+frame type.
+
+This patch fixes both by setting the C/R bit always consistently for
+command (1) and response (0) frames and inverting it later for the
+responder where necessary. The meaning of this bit in the debug output
+is being preserved and shows the bit as if it was encoded by the initiator.
+This reflects only the frame type rather than the encoded combination of
+communication side and frame type.
+
+Fixes: cc0f42122a7e ("tty: n_gsm: Modify CR,PF bit when config requester")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220218073123.2121-2-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/n_gsm.c |   16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -448,7 +448,7 @@ static u8 gsm_encode_modem(const struct
+  *    gsm_print_packet        -       display a frame for debug
+  *    @hdr: header to print before decode
+  *    @addr: address EA from the frame
+- *    @cr: C/R bit from the frame
++ *    @cr: C/R bit seen as initiator
+  *    @control: control including PF bit
+  *    @data: following data bytes
+  *    @dlen: length of data
+@@ -548,7 +548,7 @@ static int gsm_stuff_frame(const u8 *inp
+  *    gsm_send        -       send a control frame
+  *    @gsm: our GSM mux
+  *    @addr: address for control frame
+- *    @cr: command/response bit
++ *    @cr: command/response bit seen as initiator
+  *    @control:  control byte including PF bit
+  *
+  *    Format up and transmit a control frame. These do not go via the
+@@ -563,11 +563,15 @@ static void gsm_send(struct gsm_mux *gsm
+       int len;
+       u8 cbuf[10];
+       u8 ibuf[3];
++      int ocr;
++
++      /* toggle C/R coding if not initiator */
++      ocr = cr ^ (gsm->initiator ? 0 : 1);
+       switch (gsm->encoding) {
+       case 0:
+               cbuf[0] = GSM0_SOF;
+-              cbuf[1] = (addr << 2) | (cr << 1) | EA;
++              cbuf[1] = (addr << 2) | (ocr << 1) | EA;
+               cbuf[2] = control;
+               cbuf[3] = EA;   /* Length of data = 0 */
+               cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3);
+@@ -577,7 +581,7 @@ static void gsm_send(struct gsm_mux *gsm
+       case 1:
+       case 2:
+               /* Control frame + packing (but not frame stuffing) in mode 1 */
+-              ibuf[0] = (addr << 2) | (cr << 1) | EA;
++              ibuf[0] = (addr << 2) | (ocr << 1) | EA;
+               ibuf[1] = control;
+               ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2);
+               /* Stuffing may double the size worst case */
+@@ -611,7 +615,7 @@ static void gsm_send(struct gsm_mux *gsm
+ static inline void gsm_response(struct gsm_mux *gsm, int addr, int control)
+ {
+-      gsm_send(gsm, addr, 1, control);
++      gsm_send(gsm, addr, 0, control);
+ }
+ /**
+@@ -1800,10 +1804,10 @@ static void gsm_queue(struct gsm_mux *gs
+               goto invalid;
+       cr = gsm->address & 1;          /* C/R bit */
++      cr ^= gsm->initiator ? 0 : 1;   /* Flip so 1 always means command */
+       gsm_print_packet("<--", address, cr, gsm->control, gsm->buf, gsm->len);
+-      cr ^= 1 - gsm->initiator;       /* Flip so 1 always means command */
+       dlci = gsm->dlci[address];
+       switch (gsm->control) {
diff --git a/queue-5.16/tty-n_gsm-fix-null-pointer-access-due-to-dlci-release.patch b/queue-5.16/tty-n_gsm-fix-null-pointer-access-due-to-dlci-release.patch
new file mode 100644 (file)
index 0000000..020bb5e
--- /dev/null
@@ -0,0 +1,50 @@
+From 96b169f05cdcc844b400695184d77e42071d14f2 Mon Sep 17 00:00:00 2001
+From: "daniel.starke@siemens.com" <daniel.starke@siemens.com>
+Date: Thu, 17 Feb 2022 23:31:20 -0800
+Subject: tty: n_gsm: fix NULL pointer access due to DLCI release
+
+From: daniel.starke@siemens.com <daniel.starke@siemens.com>
+
+commit 96b169f05cdcc844b400695184d77e42071d14f2 upstream.
+
+The here fixed commit made the tty hangup asynchronous to avoid a circular
+locking warning. I could not reproduce this warning. Furthermore, due to
+the asynchronous hangup the function call now gets queued up while the
+underlying tty is being freed. Depending on the timing this results in a
+NULL pointer access in the global work queue scheduler. To be precise in
+process_one_work(). Therefore, the previous commit made the issue worse
+which it tried to fix.
+
+This patch fixes this by falling back to the old behavior which uses a
+blocking tty hangup call before freeing up the associated tty.
+
+Fixes: 7030082a7415 ("tty: n_gsm: avoid recursive locking with async port hangup")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220218073123.2121-4-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/n_gsm.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 53fa1cec49bd..79397a40a8f8 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1752,7 +1752,12 @@ static void gsm_dlci_release(struct gsm_dlci *dlci)
+               gsm_destroy_network(dlci);
+               mutex_unlock(&dlci->mutex);
+-              tty_hangup(tty);
++              /* We cannot use tty_hangup() because in tty_kref_put() the tty
++               * driver assumes that the hangup queue is free and reuses it to
++               * queue release_one_tty() -> NULL pointer panic in
++               * process_one_work().
++               */
++              tty_vhangup(tty);
+               tty_port_tty_set(&dlci->port, NULL);
+               tty_kref_put(tty);
+-- 
+2.35.1
+
diff --git a/queue-5.16/tty-n_gsm-fix-proper-link-termination-after-failed-open.patch b/queue-5.16/tty-n_gsm-fix-proper-link-termination-after-failed-open.patch
new file mode 100644 (file)
index 0000000..7cda743
--- /dev/null
@@ -0,0 +1,38 @@
+From e3b7468f082d106459e86e8dc6fb9bdd65553433 Mon Sep 17 00:00:00 2001
+From: "daniel.starke@siemens.com" <daniel.starke@siemens.com>
+Date: Thu, 17 Feb 2022 23:31:19 -0800
+Subject: tty: n_gsm: fix proper link termination after failed open
+
+From: daniel.starke@siemens.com <daniel.starke@siemens.com>
+
+commit e3b7468f082d106459e86e8dc6fb9bdd65553433 upstream.
+
+Trying to open a DLCI by sending a SABM frame may fail with a timeout.
+The link is closed on the initiator side without informing the responder
+about this event. The responder assumes the link is open after sending a
+UA frame to answer the SABM frame. The link gets stuck in a half open
+state.
+
+This patch fixes this by initiating the proper link termination procedure
+after link setup timeout instead of silently closing it down.
+
+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/20220218073123.2121-3-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/n_gsm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1518,7 +1518,7 @@ static void gsm_dlci_t1(struct timer_lis
+                       dlci->mode = DLCI_MODE_ADM;
+                       gsm_dlci_open(dlci);
+               } else {
+-                      gsm_dlci_close(dlci);
++                      gsm_dlci_begin_close(dlci); /* prevent half open link */
+               }
+               break;
diff --git a/queue-5.16/tty-n_gsm-fix-wrong-modem-processing-in-convergence-layer-type-2.patch b/queue-5.16/tty-n_gsm-fix-wrong-modem-processing-in-convergence-layer-type-2.patch
new file mode 100644 (file)
index 0000000..a0c4f8f
--- /dev/null
@@ -0,0 +1,115 @@
+From 687f9ad43c52501f46164758e908a5dd181a87fc Mon Sep 17 00:00:00 2001
+From: "daniel.starke@siemens.com" <daniel.starke@siemens.com>
+Date: Thu, 17 Feb 2022 23:31:22 -0800
+Subject: tty: n_gsm: fix wrong modem processing in convergence layer type 2
+
+From: daniel.starke@siemens.com <daniel.starke@siemens.com>
+
+commit 687f9ad43c52501f46164758e908a5dd181a87fc upstream.
+
+The function gsm_process_modem() exists to handle modem status bits of
+incoming frames. This includes incoming MSC (modem status command) frames
+and convergence layer type 2 data frames. The function, however, was only
+designed to handle MSC frames as it expects the command length. Within
+gsm_dlci_data() it is wrongly assumed that this is the same as the data
+frame length. This is only true if the data frame contains only 1 byte of
+payload.
+
+This patch names the length parameter of gsm_process_modem() in a generic
+manner to reflect its association. It also corrects all calls to the
+function to handle the variable number of modem status octets correctly in
+both cases.
+
+Fixes: 7263287af93d ("tty: n_gsm: Fixed logic to decode break signal from modem status")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220218073123.2121-6-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/n_gsm.c |   23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1021,25 +1021,25 @@ static void gsm_control_reply(struct gsm
+  *    @tty: virtual tty bound to the DLCI
+  *    @dlci: DLCI to affect
+  *    @modem: modem bits (full EA)
+- *    @clen: command length
++ *    @slen: number of signal octets
+  *
+  *    Used when a modem control message or line state inline in adaption
+  *    layer 2 is processed. Sort out the local modem state and throttles
+  */
+ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
+-                                                      u32 modem, int clen)
++                                                      u32 modem, int slen)
+ {
+       int  mlines = 0;
+       u8 brk = 0;
+       int fc;
+-      /* The modem status command can either contain one octet (v.24 signals)
+-         or two octets (v.24 signals + break signals). The length field will
+-         either be 2 or 3 respectively. This is specified in section
+-         5.4.6.3.7 of the  27.010 mux spec. */
++      /* The modem status command can either contain one octet (V.24 signals)
++       * or two octets (V.24 signals + break signals). This is specified in
++       * section 5.4.6.3.7 of the 07.10 mux spec.
++       */
+-      if (clen == 2)
++      if (slen == 1)
+               modem = modem & 0x7f;
+       else {
+               brk = modem & 0x7f;
+@@ -1096,6 +1096,7 @@ static void gsm_control_modem(struct gsm
+       unsigned int brk = 0;
+       struct gsm_dlci *dlci;
+       int len = clen;
++      int slen;
+       const u8 *dp = data;
+       struct tty_struct *tty;
+@@ -1115,6 +1116,7 @@ static void gsm_control_modem(struct gsm
+               return;
+       dlci = gsm->dlci[addr];
++      slen = len;
+       while (gsm_read_ea(&modem, *dp++) == 0) {
+               len--;
+               if (len == 0)
+@@ -1131,7 +1133,7 @@ static void gsm_control_modem(struct gsm
+               modem |= (brk & 0x7f);
+       }
+       tty = tty_port_tty_get(&dlci->port);
+-      gsm_process_modem(tty, dlci, modem, clen);
++      gsm_process_modem(tty, dlci, modem, slen);
+       if (tty) {
+               tty_wakeup(tty);
+               tty_kref_put(tty);
+@@ -1597,6 +1599,7 @@ static void gsm_dlci_data(struct gsm_dlc
+       struct tty_struct *tty;
+       unsigned int modem = 0;
+       int len = clen;
++      int slen = 0;
+       if (debug & 16)
+               pr_debug("%d bytes for tty\n", len);
+@@ -1609,12 +1612,14 @@ static void gsm_dlci_data(struct gsm_dlc
+       case 2:         /* Asynchronous serial with line state in each frame */
+               while (gsm_read_ea(&modem, *data++) == 0) {
+                       len--;
++                      slen++;
+                       if (len == 0)
+                               return;
+               }
++              slen++;
+               tty = tty_port_tty_get(port);
+               if (tty) {
+-                      gsm_process_modem(tty, dlci, modem, clen);
++                      gsm_process_modem(tty, dlci, modem, slen);
+                       tty_kref_put(tty);
+               }
+               fallthrough;
diff --git a/queue-5.16/tty-n_gsm-fix-wrong-tty-control-line-for-flow-control.patch b/queue-5.16/tty-n_gsm-fix-wrong-tty-control-line-for-flow-control.patch
new file mode 100644 (file)
index 0000000..cce49e8
--- /dev/null
@@ -0,0 +1,51 @@
+From c19d93542a6081577e6da9bf5e887979c72e80c1 Mon Sep 17 00:00:00 2001
+From: "daniel.starke@siemens.com" <daniel.starke@siemens.com>
+Date: Thu, 17 Feb 2022 23:31:21 -0800
+Subject: tty: n_gsm: fix wrong tty control line for flow control
+
+From: daniel.starke@siemens.com <daniel.starke@siemens.com>
+
+commit c19d93542a6081577e6da9bf5e887979c72e80c1 upstream.
+
+tty flow control is handled via gsmtty_throttle() and gsmtty_unthrottle().
+Both functions propagate the outgoing hardware flow control state to the
+remote side via MSC (modem status command) frames. The local state is taken
+from the RTS (ready to send) flag of the tty. However, RTS gets mapped to
+DTR (data terminal ready), which is wrong.
+This patch corrects this by mapping RTS to RTS.
+
+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/20220218073123.2121-5-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/n_gsm.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -3246,9 +3246,9 @@ static void gsmtty_throttle(struct tty_s
+       if (dlci->state == DLCI_CLOSED)
+               return;
+       if (C_CRTSCTS(tty))
+-              dlci->modem_tx &= ~TIOCM_DTR;
++              dlci->modem_tx &= ~TIOCM_RTS;
+       dlci->throttled = true;
+-      /* Send an MSC with DTR cleared */
++      /* Send an MSC with RTS cleared */
+       gsmtty_modem_update(dlci, 0);
+ }
+@@ -3258,9 +3258,9 @@ static void gsmtty_unthrottle(struct tty
+       if (dlci->state == DLCI_CLOSED)
+               return;
+       if (C_CRTSCTS(tty))
+-              dlci->modem_tx |= TIOCM_DTR;
++              dlci->modem_tx |= TIOCM_RTS;
+       dlci->throttled = false;
+-      /* Send an MSC with DTR set */
++      /* Send an MSC with RTS set */
+       gsmtty_modem_update(dlci, 0);
+ }