--- /dev/null
+From 0aaa81377c5a01f686bcdb8c7a6929a7bf330c68 Mon Sep 17 00:00:00 2001
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+Date: Fri, 4 Jan 2019 15:55:26 +0100
+Subject: can: gw: ensure DLC boundaries after CAN frame modification
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+commit 0aaa81377c5a01f686bcdb8c7a6929a7bf330c68 upstream.
+
+Muyu Yu provided a POC where user root with CAP_NET_ADMIN can create a CAN
+frame modification rule that makes the data length code a higher value than
+the available CAN frame data size. In combination with a configured checksum
+calculation where the result is stored relatively to the end of the data
+(e.g. cgw_csum_xor_rel) the tail of the skb (e.g. frag_list pointer in
+skb_shared_info) can be rewritten which finally can cause a system crash.
+
+Michael Kubecek suggested to drop frames that have a DLC exceeding the
+available space after the modification process and provided a patch that can
+handle CAN FD frames too. Within this patch we also limit the length for the
+checksum calculations to the maximum of Classic CAN data length (8).
+
+CAN frames that are dropped by these additional checks are counted with the
+CGW_DELETED counter which indicates misconfigurations in can-gw rules.
+
+This fixes CVE-2019-3701.
+
+Reported-by: Muyu Yu <ieatmuttonchuan@gmail.com>
+Reported-by: Marcus Meissner <meissner@suse.de>
+Suggested-by: Michal Kubecek <mkubecek@suse.cz>
+Tested-by: Muyu Yu <ieatmuttonchuan@gmail.com>
+Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Cc: linux-stable <stable@vger.kernel.org> # >= v3.2
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/can/gw.c | 30 +++++++++++++++++++++++++++---
+ 1 file changed, 27 insertions(+), 3 deletions(-)
+
+--- a/net/can/gw.c
++++ b/net/can/gw.c
+@@ -417,13 +417,29 @@ static void can_can_gw_rcv(struct sk_buf
+ while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx])
+ (*gwj->mod.modfunc[modidx++])(cf, &gwj->mod);
+
+- /* check for checksum updates when the CAN frame has been modified */
++ /* Has the CAN frame been modified? */
+ if (modidx) {
+- if (gwj->mod.csumfunc.crc8)
++ /* get available space for the processed CAN frame type */
++ int max_len = nskb->len - offsetof(struct can_frame, data);
++
++ /* dlc may have changed, make sure it fits to the CAN frame */
++ if (cf->can_dlc > max_len)
++ goto out_delete;
++
++ /* check for checksum updates in classic CAN length only */
++ if (gwj->mod.csumfunc.crc8) {
++ if (cf->can_dlc > 8)
++ goto out_delete;
++
+ (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8);
++ }
++
++ if (gwj->mod.csumfunc.xor) {
++ if (cf->can_dlc > 8)
++ goto out_delete;
+
+- if (gwj->mod.csumfunc.xor)
+ (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor);
++ }
+ }
+
+ /* clear the skb timestamp if not configured the other way */
+@@ -435,6 +451,14 @@ static void can_can_gw_rcv(struct sk_buf
+ gwj->dropped_frames++;
+ else
+ gwj->handled_frames++;
++
++ return;
++
++ out_delete:
++ /* delete frame due to misconfiguration */
++ gwj->deleted_frames++;
++ kfree_skb(nskb);
++ return;
+ }
+
+ static inline int cgw_register_filter(struct cgw_job *gwj)
--- /dev/null
+From 231f8fd0cca078bd4396dd7e380db813ac5736e2 Mon Sep 17 00:00:00 2001
+From: Dmitry Safonov <dima@arista.com>
+Date: Thu, 1 Nov 2018 00:24:46 +0000
+Subject: tty/ldsem: Wake up readers after timed out down_write()
+
+From: Dmitry Safonov <dima@arista.com>
+
+commit 231f8fd0cca078bd4396dd7e380db813ac5736e2 upstream.
+
+ldsem_down_read() will sleep if there is pending writer in the queue.
+If the writer times out, readers in the queue should be woken up,
+otherwise they may miss a chance to acquire the semaphore until the last
+active reader will do ldsem_up_read().
+
+There was a couple of reports where there was one active reader and
+other readers soft locked up:
+ Showing all locks held in the system:
+ 2 locks held by khungtaskd/17:
+ #0: (rcu_read_lock){......}, at: watchdog+0x124/0x6d1
+ #1: (tasklist_lock){.+.+..}, at: debug_show_all_locks+0x72/0x2d3
+ 2 locks held by askfirst/123:
+ #0: (&tty->ldisc_sem){.+.+.+}, at: ldsem_down_read+0x46/0x58
+ #1: (&ldata->atomic_read_lock){+.+...}, at: n_tty_read+0x115/0xbe4
+
+Prevent readers wait for active readers to release ldisc semaphore.
+
+Link: lkml.kernel.org/r/20171121132855.ajdv4k6swzhvktl6@wfg-t540p.sh.intel.com
+Link: lkml.kernel.org/r/20180907045041.GF1110@shao2-debian
+Cc: Jiri Slaby <jslaby@suse.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Reported-by: kernel test robot <rong.a.chen@intel.com>
+Signed-off-by: Dmitry Safonov <dima@arista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/tty_ldsem.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/tty/tty_ldsem.c
++++ b/drivers/tty/tty_ldsem.c
+@@ -306,6 +306,16 @@ down_write_failed(struct ld_semaphore *s
+ if (!locked)
+ ldsem_atomic_update(-LDSEM_WAIT_BIAS, sem);
+ list_del(&waiter.list);
++
++ /*
++ * In case of timeout, wake up every reader who gave the right of way
++ * to writer. Prevent separation readers into two groups:
++ * one that helds semaphore and another that sleeps.
++ * (in case of no contention with a writer)
++ */
++ if (!locked && list_empty(&sem->write_wait))
++ __ldsem_wake_readers(sem);
++
+ raw_spin_unlock_irq(&sem->wait_lock);
+
+ __set_task_state(tsk, TASK_RUNNING);