From 89f829126fbe4aa8d75b2fed041171a89b1ca7e4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Dec 2020 09:45:25 +0100 Subject: [PATCH] 4.4-stable patches added patches: cifs-fix-potential-use-after-free-in-cifs_echo_request.patch powerpc-pseries-pass-msi-affinity-to-irq_create_mapping.patch tty-fix-session-locking.patch --- ...-use-after-free-in-cifs_echo_request.patch | 51 +++++ ...s-msi-affinity-to-irq_create_mapping.patch | 54 +++++ queue-4.4/series | 3 + queue-4.4/tty-fix-session-locking.patch | 197 ++++++++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 queue-4.4/cifs-fix-potential-use-after-free-in-cifs_echo_request.patch create mode 100644 queue-4.4/powerpc-pseries-pass-msi-affinity-to-irq_create_mapping.patch create mode 100644 queue-4.4/tty-fix-session-locking.patch diff --git a/queue-4.4/cifs-fix-potential-use-after-free-in-cifs_echo_request.patch b/queue-4.4/cifs-fix-potential-use-after-free-in-cifs_echo_request.patch new file mode 100644 index 00000000000..2a5b934c5c5 --- /dev/null +++ b/queue-4.4/cifs-fix-potential-use-after-free-in-cifs_echo_request.patch @@ -0,0 +1,51 @@ +From 212253367dc7b49ed3fc194ce71b0992eacaecf2 Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Sat, 28 Nov 2020 16:54:02 -0300 +Subject: cifs: fix potential use-after-free in cifs_echo_request() + +From: Paulo Alcantara + +commit 212253367dc7b49ed3fc194ce71b0992eacaecf2 upstream. + +This patch fixes a potential use-after-free bug in +cifs_echo_request(). + +For instance, + + thread 1 + -------- + cifs_demultiplex_thread() + clean_demultiplex_info() + kfree(server) + + thread 2 (workqueue) + -------- + apic_timer_interrupt() + smp_apic_timer_interrupt() + irq_exit() + __do_softirq() + run_timer_softirq() + call_timer_fn() + cifs_echo_request() <- use-after-free in server ptr + +Signed-off-by: Paulo Alcantara (SUSE) +CC: Stable +Reviewed-by: Ronnie Sahlberg +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/connect.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -783,6 +783,8 @@ static void clean_demultiplex_info(struc + list_del_init(&server->tcp_ses_list); + spin_unlock(&cifs_tcp_ses_lock); + ++ cancel_delayed_work_sync(&server->echo); ++ + spin_lock(&GlobalMid_Lock); + server->tcpStatus = CifsExiting; + spin_unlock(&GlobalMid_Lock); diff --git a/queue-4.4/powerpc-pseries-pass-msi-affinity-to-irq_create_mapping.patch b/queue-4.4/powerpc-pseries-pass-msi-affinity-to-irq_create_mapping.patch new file mode 100644 index 00000000000..8440ef01a07 --- /dev/null +++ b/queue-4.4/powerpc-pseries-pass-msi-affinity-to-irq_create_mapping.patch @@ -0,0 +1,54 @@ +From 9ea69a55b3b9a71cded9726af591949c1138f235 Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Thu, 26 Nov 2020 09:28:52 +0100 +Subject: powerpc/pseries: Pass MSI affinity to irq_create_mapping() + +From: Laurent Vivier + +commit 9ea69a55b3b9a71cded9726af591949c1138f235 upstream. + +With virtio multiqueue, normally each queue IRQ is mapped to a CPU. + +Commit 0d9f0a52c8b9f ("virtio_scsi: use virtio IRQ affinity") exposed +an existing shortcoming of the arch code by moving virtio_scsi to +the automatic IRQ affinity assignment. + +The affinity is correctly computed in msi_desc but this is not applied +to the system IRQs. + +It appears the affinity is correctly passed to rtas_setup_msi_irqs() but +lost at this point and never passed to irq_domain_alloc_descs() +(see commit 06ee6d571f0e ("genirq: Add affinity hint to irq allocation")) +because irq_create_mapping() doesn't take an affinity parameter. + +Use the new irq_create_mapping_affinity() function, which allows to forward +the affinity setting from rtas_setup_msi_irqs() to irq_domain_alloc_descs(). + +With this change, the virtqueues are correctly dispatched between the CPUs +on pseries. + +Fixes: e75eafb9b039 ("genirq/msi: Switch to new irq spreading infrastructure") +Signed-off-by: Laurent Vivier +Signed-off-by: Thomas Gleixner +Reviewed-by: Greg Kurz +Acked-by: Michael Ellerman +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20201126082852.1178497-3-lvivier@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/pseries/msi.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/platforms/pseries/msi.c ++++ b/arch/powerpc/platforms/pseries/msi.c +@@ -469,7 +469,8 @@ again: + return hwirq; + } + +- virq = irq_create_mapping(NULL, hwirq); ++ virq = irq_create_mapping_affinity(NULL, hwirq, ++ entry->affinity); + + if (virq == NO_IRQ) { + pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq); diff --git a/queue-4.4/series b/queue-4.4/series index 5e8eeb3cfd9..31244b0db4f 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -22,3 +22,6 @@ usb-serial-option-add-support-for-thales-cinterion-exs82.patch tty-fix-pgrp-locking-in-tiocspgrp.patch alsa-hda-realtek-add-new-codec-supported-for-alc897.patch alsa-hda-generic-add-option-to-enforce-preferred_dacs-pairs.patch +tty-fix-session-locking.patch +cifs-fix-potential-use-after-free-in-cifs_echo_request.patch +powerpc-pseries-pass-msi-affinity-to-irq_create_mapping.patch diff --git a/queue-4.4/tty-fix-session-locking.patch b/queue-4.4/tty-fix-session-locking.patch new file mode 100644 index 00000000000..fe834719c3f --- /dev/null +++ b/queue-4.4/tty-fix-session-locking.patch @@ -0,0 +1,197 @@ +From c8bcd9c5be24fb9e6132e97da5a35e55a83e36b9 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Thu, 3 Dec 2020 02:25:05 +0100 +Subject: tty: Fix ->session locking + +From: Jann Horn + +commit c8bcd9c5be24fb9e6132e97da5a35e55a83e36b9 upstream. + +Currently, locking of ->session is very inconsistent; most places +protect it using the legacy tty mutex, but disassociate_ctty(), +__do_SAK(), tiocspgrp() and tiocgsid() don't. +Two of the writers hold the ctrl_lock (because they already need it for +->pgrp), but __proc_set_tty() doesn't do that yet. + +On a PREEMPT=y system, an unprivileged user can theoretically abuse +this broken locking to read 4 bytes of freed memory via TIOCGSID if +tiocgsid() is preempted long enough at the right point. (Other things +might also go wrong, especially if root-only ioctls are involved; I'm +not sure about that.) + +Change the locking on ->session such that: + + - tty_lock() is held by all writers: By making disassociate_ctty() + hold it. This should be fine because the same lock can already be + taken through the call to tty_vhangup_session(). + The tricky part is that we need to shorten the area covered by + siglock to be able to take tty_lock() without ugly retry logic; as + far as I can tell, this should be fine, since nothing in the + signal_struct is touched in the `if (tty)` branch. + - ctrl_lock is held by all writers: By changing __proc_set_tty() to + hold the lock a little longer. + - All readers that aren't holding tty_lock() hold ctrl_lock: By + adding locking to tiocgsid() and __do_SAK(), and expanding the area + covered by ctrl_lock in tiocspgrp(). + +Cc: stable@kernel.org +Signed-off-by: Jann Horn +Reviewed-by: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/tty_io.c | 51 +++++++++++++++++++++++++++++++++++++-------------- + include/linux/tty.h | 4 ++++ + 2 files changed, 41 insertions(+), 14 deletions(-) + +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -537,8 +537,8 @@ static void __proc_set_tty(struct tty_st + put_pid(tty->session); + put_pid(tty->pgrp); + tty->pgrp = get_pid(task_pgrp(current)); +- spin_unlock_irqrestore(&tty->ctrl_lock, flags); + tty->session = get_pid(task_session(current)); ++ spin_unlock_irqrestore(&tty->ctrl_lock, flags); + if (current->signal->tty) { + tty_debug(tty, "current tty %s not NULL!!\n", + current->signal->tty->name); +@@ -929,21 +929,24 @@ void disassociate_ctty(int on_exit) + spin_lock_irq(¤t->sighand->siglock); + put_pid(current->signal->tty_old_pgrp); + current->signal->tty_old_pgrp = NULL; +- + tty = tty_kref_get(current->signal->tty); ++ spin_unlock_irq(¤t->sighand->siglock); ++ + if (tty) { + unsigned long flags; ++ ++ tty_lock(tty); + spin_lock_irqsave(&tty->ctrl_lock, flags); + put_pid(tty->session); + put_pid(tty->pgrp); + tty->session = NULL; + tty->pgrp = NULL; + spin_unlock_irqrestore(&tty->ctrl_lock, flags); ++ tty_unlock(tty); + tty_kref_put(tty); + } else + tty_debug_hangup(tty, "no current tty\n"); + +- spin_unlock_irq(¤t->sighand->siglock); + /* Now clear signal->tty under the lock */ + read_lock(&tasklist_lock); + session_clear_tty(task_session(current)); +@@ -2601,14 +2604,19 @@ static int tiocspgrp(struct tty_struct * + return -ENOTTY; + if (retval) + return retval; +- if (!current->signal->tty || +- (current->signal->tty != real_tty) || +- (real_tty->session != task_session(current))) +- return -ENOTTY; ++ + if (get_user(pgrp_nr, p)) + return -EFAULT; + if (pgrp_nr < 0) + return -EINVAL; ++ ++ spin_lock_irq(&real_tty->ctrl_lock); ++ if (!current->signal->tty || ++ (current->signal->tty != real_tty) || ++ (real_tty->session != task_session(current))) { ++ retval = -ENOTTY; ++ goto out_unlock_ctrl; ++ } + rcu_read_lock(); + pgrp = find_vpid(pgrp_nr); + retval = -ESRCH; +@@ -2618,12 +2626,12 @@ static int tiocspgrp(struct tty_struct * + if (session_of_pgrp(pgrp) != task_session(current)) + goto out_unlock; + retval = 0; +- spin_lock_irq(&real_tty->ctrl_lock); + put_pid(real_tty->pgrp); + real_tty->pgrp = get_pid(pgrp); +- spin_unlock_irq(&real_tty->ctrl_lock); + out_unlock: + rcu_read_unlock(); ++out_unlock_ctrl: ++ spin_unlock_irq(&real_tty->ctrl_lock); + return retval; + } + +@@ -2635,21 +2643,31 @@ out_unlock: + * + * Obtain the session id of the tty. If there is no session + * return an error. +- * +- * Locking: none. Reference to current->signal->tty is safe. + */ + + static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) + { ++ unsigned long flags; ++ pid_t sid; ++ + /* + * (tty == real_tty) is a cheap way of + * testing if the tty is NOT a master pty. + */ + if (tty == real_tty && current->signal->tty != real_tty) + return -ENOTTY; ++ ++ spin_lock_irqsave(&real_tty->ctrl_lock, flags); + if (!real_tty->session) +- return -ENOTTY; +- return put_user(pid_vnr(real_tty->session), p); ++ goto err; ++ sid = pid_vnr(real_tty->session); ++ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags); ++ ++ return put_user(sid, p); ++ ++err: ++ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags); ++ return -ENOTTY; + } + + /** +@@ -3061,10 +3079,14 @@ void __do_SAK(struct tty_struct *tty) + struct task_struct *g, *p; + struct pid *session; + int i; ++ unsigned long flags; + + if (!tty) + return; +- session = tty->session; ++ ++ spin_lock_irqsave(&tty->ctrl_lock, flags); ++ session = get_pid(tty->session); ++ spin_unlock_irqrestore(&tty->ctrl_lock, flags); + + tty_ldisc_flush(tty); + +@@ -3100,6 +3122,7 @@ void __do_SAK(struct tty_struct *tty) + task_unlock(p); + } while_each_thread(g, p); + read_unlock(&tasklist_lock); ++ put_pid(session); + #endif + } + +--- a/include/linux/tty.h ++++ b/include/linux/tty.h +@@ -280,6 +280,10 @@ struct tty_struct { + struct termiox *termiox; /* May be NULL for unsupported */ + char name[64]; + struct pid *pgrp; /* Protected by ctrl lock */ ++ /* ++ * Writes protected by both ctrl lock and legacy mutex, readers must use ++ * at least one of them. ++ */ + struct pid *session; + unsigned long flags; + int count; -- 2.47.3