From: Greg Kroah-Hartman Date: Thu, 17 Jan 2019 13:54:29 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v4.20.4~61 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eedebaedd2f16f1a7ad8d32e68d7edf46554f05f;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: can-gw-ensure-dlc-boundaries-after-can-frame-modification.patch tty-ldsem-wake-up-readers-after-timed-out-down_write.patch --- 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 index 00000000000..b6bb927ed39 --- /dev/null +++ b/queue-3.18/can-gw-ensure-dlc-boundaries-after-can-frame-modification.patch @@ -0,0 +1,91 @@ +From 0aaa81377c5a01f686bcdb8c7a6929a7bf330c68 Mon Sep 17 00:00:00 2001 +From: Oliver Hartkopp +Date: Fri, 4 Jan 2019 15:55:26 +0100 +Subject: can: gw: ensure DLC boundaries after CAN frame modification + +From: Oliver Hartkopp + +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 +Reported-by: Marcus Meissner +Suggested-by: Michal Kubecek +Tested-by: Muyu Yu +Tested-by: Oliver Hartkopp +Signed-off-by: Oliver Hartkopp +Cc: linux-stable # >= v3.2 +Signed-off-by: Marc Kleine-Budde +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-3.18/series b/queue-3.18/series index dafd6bf3aab..6ed8f4d7deb 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -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 index 00000000000..5a8676e5f89 --- /dev/null +++ b/queue-3.18/tty-ldsem-wake-up-readers-after-timed-out-down_write.patch @@ -0,0 +1,58 @@ +From 231f8fd0cca078bd4396dd7e380db813ac5736e2 Mon Sep 17 00:00:00 2001 +From: Dmitry Safonov +Date: Thu, 1 Nov 2018 00:24:46 +0000 +Subject: tty/ldsem: Wake up readers after timed out down_write() + +From: Dmitry Safonov + +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 +Cc: Peter Zijlstra +Cc: stable@vger.kernel.org +Reported-by: kernel test robot +Signed-off-by: Dmitry Safonov +Signed-off-by: Greg Kroah-Hartman + +--- + 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);