]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Sep 2021 09:43:44 +0000 (11:43 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Sep 2021 09:43:44 +0000 (11:43 +0200)
added patches:
time-handle-negative-seconds-correctly-in-timespec64_to_ns.patch
tty-fix-data-race-between-tiocsti-and-flush_to_ldisc.patch

queue-4.9/series
queue-4.9/time-handle-negative-seconds-correctly-in-timespec64_to_ns.patch [new file with mode: 0644]
queue-4.9/tty-fix-data-race-between-tiocsti-and-flush_to_ldisc.patch [new file with mode: 0644]

index ea5dfd6bb14cf965d903247226e9e53de6ab514f..93a4da3087a40640aae96d4a0470c04cd7b0e325 100644 (file)
@@ -81,3 +81,5 @@ usb-ehci-orion-handle-errors-of-clk_prepare_enable-i.patch
 ath6kl-wmi-fix-an-error-code-in-ath6kl_wmi_sync_poin.patch
 bcma-fix-memory-leak-for-internally-handled-cores.patch
 ipv4-make-exception-cache-less-predictible.patch
+time-handle-negative-seconds-correctly-in-timespec64_to_ns.patch
+tty-fix-data-race-between-tiocsti-and-flush_to_ldisc.patch
diff --git a/queue-4.9/time-handle-negative-seconds-correctly-in-timespec64_to_ns.patch b/queue-4.9/time-handle-negative-seconds-correctly-in-timespec64_to_ns.patch
new file mode 100644 (file)
index 0000000..daf9351
--- /dev/null
@@ -0,0 +1,61 @@
+From 39ff83f2f6cc5cc1458dfcea9697f96338210beb Mon Sep 17 00:00:00 2001
+From: Lukas Hannen <lukas.hannen@opensource.tttech-industrial.com>
+Date: Wed, 25 Aug 2021 10:12:43 +0000
+Subject: time: Handle negative seconds correctly in timespec64_to_ns()
+
+From: Lukas Hannen <lukas.hannen@opensource.tttech-industrial.com>
+
+commit 39ff83f2f6cc5cc1458dfcea9697f96338210beb upstream.
+
+timespec64_ns() prevents multiplication overflows by comparing the seconds
+value of the timespec to KTIME_SEC_MAX. If the value is greater or equal it
+returns KTIME_MAX.
+
+But that check casts the signed seconds value to unsigned which makes the
+comparision true for all negative values and therefore return wrongly
+KTIME_MAX.
+
+Negative second values are perfectly valid and required in some places,
+e.g. ptp_clock_adjtime().
+
+Remove the cast and add a check for the negative boundary which is required
+to prevent undefined behaviour due to multiplication underflow.
+
+Fixes: cb47755725da ("time: Prevent undefined behaviour in timespec64_to_ns()")'
+Signed-off-by: Lukas Hannen <lukas.hannen@opensource.tttech-industrial.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/AM6PR01MB541637BD6F336B8FFB72AF80EEC69@AM6PR01MB5416.eurprd01.prod.exchangelabs.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/time64.h |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/include/linux/time64.h
++++ b/include/linux/time64.h
+@@ -39,7 +39,9 @@ struct itimerspec64 {
+ /* Located here for timespec[64]_valid_strict */
+ #define TIME64_MAX                    ((s64)~((u64)1 << 63))
+ #define KTIME_MAX                     ((s64)~((u64)1 << 63))
++#define KTIME_MIN                     (-KTIME_MAX - 1)
+ #define KTIME_SEC_MAX                 (KTIME_MAX / NSEC_PER_SEC)
++#define KTIME_SEC_MIN                 (KTIME_MIN / NSEC_PER_SEC)
+ #if __BITS_PER_LONG == 64
+@@ -188,10 +190,13 @@ static inline bool timespec64_valid_stri
+  */
+ static inline s64 timespec64_to_ns(const struct timespec64 *ts)
+ {
+-      /* Prevent multiplication overflow */
+-      if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
++      /* Prevent multiplication overflow / underflow */
++      if (ts->tv_sec >= KTIME_SEC_MAX)
+               return KTIME_MAX;
++      if (ts->tv_sec <= KTIME_SEC_MIN)
++              return KTIME_MIN;
++
+       return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
+ }
diff --git a/queue-4.9/tty-fix-data-race-between-tiocsti-and-flush_to_ldisc.patch b/queue-4.9/tty-fix-data-race-between-tiocsti-and-flush_to_ldisc.patch
new file mode 100644 (file)
index 0000000..8889d26
--- /dev/null
@@ -0,0 +1,59 @@
+From bb2853a6a421a052268eee00fd5d3f6b3504b2b1 Mon Sep 17 00:00:00 2001
+From: Nguyen Dinh Phi <phind.uet@gmail.com>
+Date: Mon, 23 Aug 2021 08:06:41 +0800
+Subject: tty: Fix data race between tiocsti() and flush_to_ldisc()
+
+From: Nguyen Dinh Phi <phind.uet@gmail.com>
+
+commit bb2853a6a421a052268eee00fd5d3f6b3504b2b1 upstream.
+
+The ops->receive_buf() may be accessed concurrently from these two
+functions.  If the driver flushes data to the line discipline
+receive_buf() method while tiocsti() is waiting for the
+ops->receive_buf() to finish its work, the data race will happen.
+
+For example:
+tty_ioctl                      |tty_ldisc_receive_buf
+ ->tioctsi                     | ->tty_port_default_receive_buf
+                               |  ->tty_ldisc_receive_buf
+   ->hci_uart_tty_receive      |   ->hci_uart_tty_receive
+    ->h4_recv                   |    ->h4_recv
+
+In this case, the h4 receive buffer will be overwritten by the
+latecomer, and we will lost the data.
+
+Hence, change tioctsi() function to use the exclusive lock interface
+from tty_buffer to avoid the data race.
+
+Reported-by: syzbot+97388eb9d31b997fe1d0@syzkaller.appspotmail.com
+Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
+Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
+Link: https://lore.kernel.org/r/20210823000641.2082292-1-phind.uet@gmail.com
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/tty_io.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2312,8 +2312,6 @@ static int tty_fasync(int fd, struct fil
+  *    Locking:
+  *            Called functions take tty_ldiscs_lock
+  *            current->signal->tty check is safe without locks
+- *
+- *    FIXME: may race normal receive processing
+  */
+ static int tiocsti(struct tty_struct *tty, char __user *p)
+@@ -2329,8 +2327,10 @@ static int tiocsti(struct tty_struct *tt
+       ld = tty_ldisc_ref_wait(tty);
+       if (!ld)
+               return -EIO;
++      tty_buffer_lock_exclusive(tty->port);
+       if (ld->ops->receive_buf)
+               ld->ops->receive_buf(tty, &ch, &mbz, 1);
++      tty_buffer_unlock_exclusive(tty->port);
+       tty_ldisc_deref(ld);
+       return 0;
+ }