]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Jan 2019 13:54:29 +0000 (14:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Jan 2019 13:54:29 +0000 (14:54 +0100)
added patches:
can-gw-ensure-dlc-boundaries-after-can-frame-modification.patch
tty-ldsem-wake-up-readers-after-timed-out-down_write.patch

queue-3.18/can-gw-ensure-dlc-boundaries-after-can-frame-modification.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/tty-ldsem-wake-up-readers-after-timed-out-down_write.patch [new file with mode: 0644]

diff --git a/queue-3.18/can-gw-ensure-dlc-boundaries-after-can-frame-modification.patch b/queue-3.18/can-gw-ensure-dlc-boundaries-after-can-frame-modification.patch
new file mode 100644 (file)
index 0000000..b6bb927
--- /dev/null
@@ -0,0 +1,91 @@
+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)
index dafd6bf3aab184d10dce36ae234650073e1c24a0..6ed8f4d7deb22ec7f1d5e8b8b7bdaa1f1c4d4d09 100644 (file)
@@ -9,3 +9,5 @@ acpi-power-skip-duplicate-power-resource-references-in-_prx.patch
 i2c-dev-prevent-adapter-retries-and-timeout-being-set-as-minus-value.patch
 crypto-cts-fix-crash-on-short-inputs.patch
 sunrpc-use-after-free-in-svc_process_common.patch
+tty-ldsem-wake-up-readers-after-timed-out-down_write.patch
+can-gw-ensure-dlc-boundaries-after-can-frame-modification.patch
diff --git a/queue-3.18/tty-ldsem-wake-up-readers-after-timed-out-down_write.patch b/queue-3.18/tty-ldsem-wake-up-readers-after-timed-out-down_write.patch
new file mode 100644 (file)
index 0000000..5a8676e
--- /dev/null
@@ -0,0 +1,58 @@
+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);