From 5945228a5fceef1b672ccf6bc19f198e93ea6f4d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 27 Jul 2022 11:43:23 +0200 Subject: [PATCH] 5.15-stable patches added patches: tty-drivers-tty-stop-using-tty_schedule_flip.patch tty-drop-tty_schedule_flip.patch tty-extract-tty_flip_buffer_commit-from-tty_flip_buffer_push.patch tty-the-rest-stop-using-tty_schedule_flip.patch tty-use-new-tty_insert_flip_string_and_push_buffer-in-pty_write.patch watchqueue-make-sure-to-serialize-wqueue-defunct-properly.patch x86-alternative-report-missing-return-thunk-details.patch x86-amd-use-ibpb-for-firmware-calls.patch --- queue-5.15/series | 8 ++ ...ers-tty-stop-using-tty_schedule_flip.patch | 107 ++++++++++++++ queue-5.15/tty-drop-tty_schedule_flip.patch | 82 +++++++++++ ...fer_commit-from-tty_flip_buffer_push.patch | 55 +++++++ ...he-rest-stop-using-tty_schedule_flip.patch | 84 +++++++++++ ..._string_and_push_buffer-in-pty_write.patch | 118 +++++++++++++++ ...to-serialize-wqueue-defunct-properly.patch | 135 ++++++++++++++++++ ...-report-missing-return-thunk-details.patch | 34 +++++ .../x86-amd-use-ibpb-for-firmware-calls.patch | 70 +++++++++ 9 files changed, 693 insertions(+) create mode 100644 queue-5.15/tty-drivers-tty-stop-using-tty_schedule_flip.patch create mode 100644 queue-5.15/tty-drop-tty_schedule_flip.patch create mode 100644 queue-5.15/tty-extract-tty_flip_buffer_commit-from-tty_flip_buffer_push.patch create mode 100644 queue-5.15/tty-the-rest-stop-using-tty_schedule_flip.patch create mode 100644 queue-5.15/tty-use-new-tty_insert_flip_string_and_push_buffer-in-pty_write.patch create mode 100644 queue-5.15/watchqueue-make-sure-to-serialize-wqueue-defunct-properly.patch create mode 100644 queue-5.15/x86-alternative-report-missing-return-thunk-details.patch create mode 100644 queue-5.15/x86-amd-use-ibpb-for-firmware-calls.patch diff --git a/queue-5.15/series b/queue-5.15/series index 7bfbc5788d1..72a3929a090 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -184,3 +184,11 @@ exfat-use-updated-exfat_chain-directly-during-renaming.patch drm-amd-display-reset-dmcub-before-hw-init.patch drm-amd-display-optimize-bandwidth-on-following-fast-update.patch drm-amd-display-fix-surface-optimization-regression-on-carrizo.patch +x86-amd-use-ibpb-for-firmware-calls.patch +x86-alternative-report-missing-return-thunk-details.patch +watchqueue-make-sure-to-serialize-wqueue-defunct-properly.patch +tty-drivers-tty-stop-using-tty_schedule_flip.patch +tty-the-rest-stop-using-tty_schedule_flip.patch +tty-drop-tty_schedule_flip.patch +tty-extract-tty_flip_buffer_commit-from-tty_flip_buffer_push.patch +tty-use-new-tty_insert_flip_string_and_push_buffer-in-pty_write.patch diff --git a/queue-5.15/tty-drivers-tty-stop-using-tty_schedule_flip.patch b/queue-5.15/tty-drivers-tty-stop-using-tty_schedule_flip.patch new file mode 100644 index 00000000000..53b20e9fe63 --- /dev/null +++ b/queue-5.15/tty-drivers-tty-stop-using-tty_schedule_flip.patch @@ -0,0 +1,107 @@ +From 5f6a85158ccacc3f09744b3aafe8b11ab3b6c6f6 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Mon, 22 Nov 2021 12:16:46 +0100 +Subject: tty: drivers/tty/, stop using tty_schedule_flip() + +From: Jiri Slaby + +commit 5f6a85158ccacc3f09744b3aafe8b11ab3b6c6f6 upstream. + +Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014, +tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). We are +going to remove the latter (as it is used less), so call the former in +drivers/tty/. + +Cc: Vladimir Zapolskiy +Reviewed-by: Johan Hovold +Signed-off-by: Jiri Slaby +Link: https://lore.kernel.org/r/20211122111648.30379-2-jslaby@suse.cz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/goldfish.c | 2 +- + drivers/tty/moxa.c | 4 ++-- + drivers/tty/serial/lpc32xx_hs.c | 2 +- + drivers/tty/vt/keyboard.c | 6 +++--- + drivers/tty/vt/vt.c | 2 +- + 5 files changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/tty/goldfish.c ++++ b/drivers/tty/goldfish.c +@@ -151,7 +151,7 @@ static irqreturn_t goldfish_tty_interrup + address = (unsigned long)(void *)buf; + goldfish_tty_rw(qtty, address, count, 0); + +- tty_schedule_flip(&qtty->port); ++ tty_flip_buffer_push(&qtty->port); + return IRQ_HANDLED; + } + +--- a/drivers/tty/moxa.c ++++ b/drivers/tty/moxa.c +@@ -1383,7 +1383,7 @@ static int moxa_poll_port(struct moxa_po + if (inited && !tty_throttled(tty) && + MoxaPortRxQueue(p) > 0) { /* RX */ + MoxaPortReadData(p); +- tty_schedule_flip(&p->port); ++ tty_flip_buffer_push(&p->port); + } + } else { + clear_bit(EMPTYWAIT, &p->statusflags); +@@ -1408,7 +1408,7 @@ static int moxa_poll_port(struct moxa_po + + if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ + tty_insert_flip_char(&p->port, 0, TTY_BREAK); +- tty_schedule_flip(&p->port); ++ tty_flip_buffer_push(&p->port); + } + + if (intr & IntrLine) +--- a/drivers/tty/serial/lpc32xx_hs.c ++++ b/drivers/tty/serial/lpc32xx_hs.c +@@ -341,7 +341,7 @@ static irqreturn_t serial_lpc32xx_interr + LPC32XX_HSUART_IIR(port->membase)); + port->icount.overrun++; + tty_insert_flip_char(tport, 0, TTY_OVERRUN); +- tty_schedule_flip(tport); ++ tty_flip_buffer_push(tport); + } + + /* Data received? */ +--- a/drivers/tty/vt/keyboard.c ++++ b/drivers/tty/vt/keyboard.c +@@ -324,13 +324,13 @@ int kbd_rate(struct kbd_repeat *rpt) + static void put_queue(struct vc_data *vc, int ch) + { + tty_insert_flip_char(&vc->port, ch, 0); +- tty_schedule_flip(&vc->port); ++ tty_flip_buffer_push(&vc->port); + } + + static void puts_queue(struct vc_data *vc, const char *cp) + { + tty_insert_flip_string(&vc->port, cp, strlen(cp)); +- tty_schedule_flip(&vc->port); ++ tty_flip_buffer_push(&vc->port); + } + + static void applkey(struct vc_data *vc, int key, char mode) +@@ -584,7 +584,7 @@ static void fn_inc_console(struct vc_dat + static void fn_send_intr(struct vc_data *vc) + { + tty_insert_flip_char(&vc->port, 0, TTY_BREAK); +- tty_schedule_flip(&vc->port); ++ tty_flip_buffer_push(&vc->port); + } + + static void fn_scroll_forw(struct vc_data *vc) +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1833,7 +1833,7 @@ static void csi_m(struct vc_data *vc) + static void respond_string(const char *p, size_t len, struct tty_port *port) + { + tty_insert_flip_string(port, p, len); +- tty_schedule_flip(port); ++ tty_flip_buffer_push(port); + } + + static void cursor_report(struct vc_data *vc, struct tty_struct *tty) diff --git a/queue-5.15/tty-drop-tty_schedule_flip.patch b/queue-5.15/tty-drop-tty_schedule_flip.patch new file mode 100644 index 00000000000..815deac5539 --- /dev/null +++ b/queue-5.15/tty-drop-tty_schedule_flip.patch @@ -0,0 +1,82 @@ +From 5db96ef23bda6c2a61a51693c85b78b52d03f654 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Mon, 22 Nov 2021 12:16:48 +0100 +Subject: tty: drop tty_schedule_flip() + +From: Jiri Slaby + +commit 5db96ef23bda6c2a61a51693c85b78b52d03f654 upstream. + +Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014, +tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). All +users were converted in the previous patches, so remove +tty_schedule_flip() completely while inlining its body into +tty_flip_buffer_push(). + +One less exported function. + +Reviewed-by: Johan Hovold +Signed-off-by: Jiri Slaby +Link: https://lore.kernel.org/r/20211122111648.30379-4-jslaby@suse.cz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/tty_buffer.c | 30 ++++++++---------------------- + include/linux/tty_flip.h | 1 - + 2 files changed, 8 insertions(+), 23 deletions(-) + +--- a/drivers/tty/tty_buffer.c ++++ b/drivers/tty/tty_buffer.c +@@ -403,27 +403,6 @@ int __tty_insert_flip_char(struct tty_po + EXPORT_SYMBOL(__tty_insert_flip_char); + + /** +- * tty_schedule_flip - push characters to ldisc +- * @port: tty port to push from +- * +- * Takes any pending buffers and transfers their ownership to the +- * ldisc side of the queue. It then schedules those characters for +- * processing by the line discipline. +- */ +- +-void tty_schedule_flip(struct tty_port *port) +-{ +- struct tty_bufhead *buf = &port->buf; +- +- /* paired w/ acquire in flush_to_ldisc(); ensures +- * flush_to_ldisc() sees buffer data. +- */ +- smp_store_release(&buf->tail->commit, buf->tail->used); +- queue_work(system_unbound_wq, &buf->work); +-} +-EXPORT_SYMBOL(tty_schedule_flip); +- +-/** + * tty_prepare_flip_string - make room for characters + * @port: tty port + * @chars: return pointer for character write area +@@ -567,7 +546,14 @@ static void flush_to_ldisc(struct work_s + + void tty_flip_buffer_push(struct tty_port *port) + { +- tty_schedule_flip(port); ++ struct tty_bufhead *buf = &port->buf; ++ ++ /* ++ * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees ++ * buffer data. ++ */ ++ smp_store_release(&buf->tail->commit, buf->tail->used); ++ queue_work(system_unbound_wq, &buf->work); + } + EXPORT_SYMBOL(tty_flip_buffer_push); + +--- a/include/linux/tty_flip.h ++++ b/include/linux/tty_flip.h +@@ -17,7 +17,6 @@ extern int tty_insert_flip_string_fixed_ + extern int tty_prepare_flip_string(struct tty_port *port, + unsigned char **chars, size_t size); + extern void tty_flip_buffer_push(struct tty_port *port); +-void tty_schedule_flip(struct tty_port *port); + int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag); + + static inline int tty_insert_flip_char(struct tty_port *port, diff --git a/queue-5.15/tty-extract-tty_flip_buffer_commit-from-tty_flip_buffer_push.patch b/queue-5.15/tty-extract-tty_flip_buffer_commit-from-tty_flip_buffer_push.patch new file mode 100644 index 00000000000..a73aa9bdecb --- /dev/null +++ b/queue-5.15/tty-extract-tty_flip_buffer_commit-from-tty_flip_buffer_push.patch @@ -0,0 +1,55 @@ +From 716b10580283fda66f2b88140e3964f8a7f9da89 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Thu, 7 Jul 2022 10:25:57 +0200 +Subject: tty: extract tty_flip_buffer_commit() from tty_flip_buffer_push() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jiri Slaby + +commit 716b10580283fda66f2b88140e3964f8a7f9da89 upstream. + +We will need this new helper in the next patch. + +Cc: Hillf Danton +Cc: 一只狗 +Cc: Dan Carpenter +Signed-off-by: Jiri Slaby +Link: https://lore.kernel.org/r/20220707082558.9250-1-jslaby@suse.cz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/tty_buffer.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/tty/tty_buffer.c ++++ b/drivers/tty/tty_buffer.c +@@ -533,6 +533,15 @@ static void flush_to_ldisc(struct work_s + + } + ++static inline void tty_flip_buffer_commit(struct tty_buffer *tail) ++{ ++ /* ++ * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees ++ * buffer data. ++ */ ++ smp_store_release(&tail->commit, tail->used); ++} ++ + /** + * tty_flip_buffer_push - terminal + * @port: tty port to push +@@ -548,11 +557,7 @@ void tty_flip_buffer_push(struct tty_por + { + struct tty_bufhead *buf = &port->buf; + +- /* +- * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees +- * buffer data. +- */ +- smp_store_release(&buf->tail->commit, buf->tail->used); ++ tty_flip_buffer_commit(buf->tail); + queue_work(system_unbound_wq, &buf->work); + } + EXPORT_SYMBOL(tty_flip_buffer_push); diff --git a/queue-5.15/tty-the-rest-stop-using-tty_schedule_flip.patch b/queue-5.15/tty-the-rest-stop-using-tty_schedule_flip.patch new file mode 100644 index 00000000000..543ecc41d76 --- /dev/null +++ b/queue-5.15/tty-the-rest-stop-using-tty_schedule_flip.patch @@ -0,0 +1,84 @@ +From b68b914494df4f79b4e9b58953110574af1cb7a2 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Mon, 22 Nov 2021 12:16:47 +0100 +Subject: tty: the rest, stop using tty_schedule_flip() + +From: Jiri Slaby + +commit b68b914494df4f79b4e9b58953110574af1cb7a2 upstream. + +Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014, +tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). We are +going to remove the latter (as it is used less), so call the former in +the rest of the users. + +Cc: Richard Henderson +Cc: Ivan Kokshaysky +Cc: Matt Turner +Cc: William Hubbs +Cc: Chris Brannon +Cc: Kirk Reiser +Cc: Samuel Thibault +Cc: Heiko Carstens +Cc: Vasily Gorbik +Cc: Christian Borntraeger +Cc: Alexander Gordeev +Reviewed-by: Johan Hovold +Signed-off-by: Jiri Slaby +Link: https://lore.kernel.org/r/20211122111648.30379-3-jslaby@suse.cz +Signed-off-by: Greg Kroah-Hartman +--- + arch/alpha/kernel/srmcons.c | 2 +- + drivers/accessibility/speakup/spk_ttyio.c | 4 ++-- + drivers/s390/char/keyboard.h | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +--- a/arch/alpha/kernel/srmcons.c ++++ b/arch/alpha/kernel/srmcons.c +@@ -59,7 +59,7 @@ srmcons_do_receive_chars(struct tty_port + } while((result.bits.status & 1) && (++loops < 10)); + + if (count) +- tty_schedule_flip(port); ++ tty_flip_buffer_push(port); + + return count; + } +--- a/drivers/accessibility/speakup/spk_ttyio.c ++++ b/drivers/accessibility/speakup/spk_ttyio.c +@@ -88,7 +88,7 @@ static int spk_ttyio_receive_buf2(struct + } + + if (!ldisc_data->buf_free) +- /* ttyio_in will tty_schedule_flip */ ++ /* ttyio_in will tty_flip_buffer_push */ + return 0; + + /* Make sure the consumer has read buf before we have seen +@@ -312,7 +312,7 @@ static unsigned char ttyio_in(struct spk + mb(); + ldisc_data->buf_free = true; + /* Let TTY push more characters */ +- tty_schedule_flip(tty->port); ++ tty_flip_buffer_push(tty->port); + + return rv; + } +--- a/drivers/s390/char/keyboard.h ++++ b/drivers/s390/char/keyboard.h +@@ -56,7 +56,7 @@ static inline void + kbd_put_queue(struct tty_port *port, int ch) + { + tty_insert_flip_char(port, ch, 0); +- tty_schedule_flip(port); ++ tty_flip_buffer_push(port); + } + + static inline void +@@ -64,5 +64,5 @@ kbd_puts_queue(struct tty_port *port, ch + { + while (*cp) + tty_insert_flip_char(port, *cp++, 0); +- tty_schedule_flip(port); ++ tty_flip_buffer_push(port); + } diff --git a/queue-5.15/tty-use-new-tty_insert_flip_string_and_push_buffer-in-pty_write.patch b/queue-5.15/tty-use-new-tty_insert_flip_string_and_push_buffer-in-pty_write.patch new file mode 100644 index 00000000000..61b0656151b --- /dev/null +++ b/queue-5.15/tty-use-new-tty_insert_flip_string_and_push_buffer-in-pty_write.patch @@ -0,0 +1,118 @@ +From a501ab75e7624d133a5a3c7ec010687c8b961d23 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Thu, 7 Jul 2022 10:25:58 +0200 +Subject: tty: use new tty_insert_flip_string_and_push_buffer() in pty_write() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jiri Slaby + +commit a501ab75e7624d133a5a3c7ec010687c8b961d23 upstream. + +There is a race in pty_write(). pty_write() can be called in parallel +with e.g. ioctl(TIOCSTI) or ioctl(TCXONC) which also inserts chars to +the buffer. Provided, tty_flip_buffer_push() in pty_write() is called +outside the lock, it can commit inconsistent tail. This can lead to out +of bounds writes and other issues. See the Link below. + +To fix this, we have to introduce a new helper called +tty_insert_flip_string_and_push_buffer(). It does both +tty_insert_flip_string() and tty_flip_buffer_commit() under the port +lock. It also calls queue_work(), but outside the lock. See +71a174b39f10 (pty: do tty_flip_buffer_push without port->lock in +pty_write) for the reasons. + +Keep the helper internal-only (in drivers' tty.h). It is not intended to +be used widely. + +Link: https://seclists.org/oss-sec/2022/q2/155 +Fixes: 71a174b39f10 (pty: do tty_flip_buffer_push without port->lock in pty_write) +Cc: 一只狗 +Cc: Dan Carpenter +Suggested-by: Hillf Danton +Signed-off-by: Jiri Slaby +Link: https://lore.kernel.org/r/20220707082558.9250-2-jslaby@suse.cz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/pty.c | 14 ++------------ + drivers/tty/tty.h | 3 +++ + drivers/tty/tty_buffer.c | 31 +++++++++++++++++++++++++++++++ + 3 files changed, 36 insertions(+), 12 deletions(-) + +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -111,21 +111,11 @@ static void pty_unthrottle(struct tty_st + static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) + { + struct tty_struct *to = tty->link; +- unsigned long flags; + +- if (tty->flow.stopped) ++ if (tty->flow.stopped || !c) + return 0; + +- if (c > 0) { +- spin_lock_irqsave(&to->port->lock, flags); +- /* Stuff the data into the input queue of the other end */ +- c = tty_insert_flip_string(to->port, buf, c); +- spin_unlock_irqrestore(&to->port->lock, flags); +- /* And shovel */ +- if (c) +- tty_flip_buffer_push(to->port); +- } +- return c; ++ return tty_insert_flip_string_and_push_buffer(to->port, buf, c); + } + + /** +--- a/drivers/tty/tty.h ++++ b/drivers/tty/tty.h +@@ -111,4 +111,7 @@ static inline void tty_audit_tiocsti(str + + ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); + ++int tty_insert_flip_string_and_push_buffer(struct tty_port *port, ++ const unsigned char *chars, size_t cnt); ++ + #endif +--- a/drivers/tty/tty_buffer.c ++++ b/drivers/tty/tty_buffer.c +@@ -563,6 +563,37 @@ void tty_flip_buffer_push(struct tty_por + EXPORT_SYMBOL(tty_flip_buffer_push); + + /** ++ * tty_insert_flip_string_and_push_buffer - add characters to the tty buffer and ++ * push ++ * @port: tty port ++ * @chars: characters ++ * @size: size ++ * ++ * The function combines tty_insert_flip_string() and tty_flip_buffer_push() ++ * with the exception of properly holding the @port->lock. ++ * ++ * To be used only internally (by pty currently). ++ * ++ * Returns: the number added. ++ */ ++int tty_insert_flip_string_and_push_buffer(struct tty_port *port, ++ const unsigned char *chars, size_t size) ++{ ++ struct tty_bufhead *buf = &port->buf; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&port->lock, flags); ++ size = tty_insert_flip_string(port, chars, size); ++ if (size) ++ tty_flip_buffer_commit(buf->tail); ++ spin_unlock_irqrestore(&port->lock, flags); ++ ++ queue_work(system_unbound_wq, &buf->work); ++ ++ return size; ++} ++ ++/** + * tty_buffer_init - prepare a tty buffer structure + * @port: tty port to initialise + * diff --git a/queue-5.15/watchqueue-make-sure-to-serialize-wqueue-defunct-properly.patch b/queue-5.15/watchqueue-make-sure-to-serialize-wqueue-defunct-properly.patch new file mode 100644 index 00000000000..c78354a8bd4 --- /dev/null +++ b/queue-5.15/watchqueue-make-sure-to-serialize-wqueue-defunct-properly.patch @@ -0,0 +1,135 @@ +From 353f7988dd8413c47718f7ca79c030b6fb62cfe5 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Tue, 19 Jul 2022 11:09:01 -0700 +Subject: watchqueue: make sure to serialize 'wqueue->defunct' properly + +From: Linus Torvalds + +commit 353f7988dd8413c47718f7ca79c030b6fb62cfe5 upstream. + +When the pipe is closed, we mark the associated watchqueue defunct by +calling watch_queue_clear(). However, while that is protected by the +watchqueue lock, new watchqueue entries aren't actually added under that +lock at all: they use the pipe->rd_wait.lock instead, and looking up +that pipe happens without any locking. + +The watchqueue code uses the RCU read-side section to make sure that the +wqueue entry itself hasn't disappeared, but that does not protect the +pipe_info in any way. + +So make sure to actually hold the wqueue lock when posting watch events, +properly serializing against the pipe being torn down. + +Reported-by: Noam Rathaus +Cc: Greg KH +Cc: David Howells +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + kernel/watch_queue.c | 53 +++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 37 insertions(+), 16 deletions(-) + +--- a/kernel/watch_queue.c ++++ b/kernel/watch_queue.c +@@ -34,6 +34,27 @@ MODULE_LICENSE("GPL"); + #define WATCH_QUEUE_NOTE_SIZE 128 + #define WATCH_QUEUE_NOTES_PER_PAGE (PAGE_SIZE / WATCH_QUEUE_NOTE_SIZE) + ++/* ++ * This must be called under the RCU read-lock, which makes ++ * sure that the wqueue still exists. It can then take the lock, ++ * and check that the wqueue hasn't been destroyed, which in ++ * turn makes sure that the notification pipe still exists. ++ */ ++static inline bool lock_wqueue(struct watch_queue *wqueue) ++{ ++ spin_lock_bh(&wqueue->lock); ++ if (unlikely(wqueue->defunct)) { ++ spin_unlock_bh(&wqueue->lock); ++ return false; ++ } ++ return true; ++} ++ ++static inline void unlock_wqueue(struct watch_queue *wqueue) ++{ ++ spin_unlock_bh(&wqueue->lock); ++} ++ + static void watch_queue_pipe_buf_release(struct pipe_inode_info *pipe, + struct pipe_buffer *buf) + { +@@ -69,6 +90,10 @@ static const struct pipe_buf_operations + + /* + * Post a notification to a watch queue. ++ * ++ * Must be called with the RCU lock for reading, and the ++ * watch_queue lock held, which guarantees that the pipe ++ * hasn't been released. + */ + static bool post_one_notification(struct watch_queue *wqueue, + struct watch_notification *n) +@@ -85,9 +110,6 @@ static bool post_one_notification(struct + + spin_lock_irq(&pipe->rd_wait.lock); + +- if (wqueue->defunct) +- goto out; +- + mask = pipe->ring_size - 1; + head = pipe->head; + tail = pipe->tail; +@@ -203,7 +225,10 @@ void __post_watch_notification(struct wa + if (security_post_notification(watch->cred, cred, n) < 0) + continue; + +- post_one_notification(wqueue, n); ++ if (lock_wqueue(wqueue)) { ++ post_one_notification(wqueue, n); ++ unlock_wqueue(wqueue);; ++ } + } + + rcu_read_unlock(); +@@ -465,11 +490,12 @@ int add_watch_to_object(struct watch *wa + return -EAGAIN; + } + +- spin_lock_bh(&wqueue->lock); +- kref_get(&wqueue->usage); +- kref_get(&watch->usage); +- hlist_add_head(&watch->queue_node, &wqueue->watches); +- spin_unlock_bh(&wqueue->lock); ++ if (lock_wqueue(wqueue)) { ++ kref_get(&wqueue->usage); ++ kref_get(&watch->usage); ++ hlist_add_head(&watch->queue_node, &wqueue->watches); ++ unlock_wqueue(wqueue); ++ } + + hlist_add_head(&watch->list_node, &wlist->watchers); + return 0; +@@ -523,20 +549,15 @@ found: + + wqueue = rcu_dereference(watch->queue); + +- /* We don't need the watch list lock for the next bit as RCU is +- * protecting *wqueue from deallocation. +- */ +- if (wqueue) { ++ if (lock_wqueue(wqueue)) { + post_one_notification(wqueue, &n.watch); + +- spin_lock_bh(&wqueue->lock); +- + if (!hlist_unhashed(&watch->queue_node)) { + hlist_del_init_rcu(&watch->queue_node); + put_watch(watch); + } + +- spin_unlock_bh(&wqueue->lock); ++ unlock_wqueue(wqueue); + } + + if (wlist->release_watch) { diff --git a/queue-5.15/x86-alternative-report-missing-return-thunk-details.patch b/queue-5.15/x86-alternative-report-missing-return-thunk-details.patch new file mode 100644 index 00000000000..777c54ac8a8 --- /dev/null +++ b/queue-5.15/x86-alternative-report-missing-return-thunk-details.patch @@ -0,0 +1,34 @@ +From 65cdf0d623bedf0e069bb64ed52e8bb20105e2ba Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Wed, 13 Jul 2022 14:38:19 -0700 +Subject: x86/alternative: Report missing return thunk details + +From: Kees Cook + +commit 65cdf0d623bedf0e069bb64ed52e8bb20105e2ba upstream. + +Debugging missing return thunks is easier if we can see where they're +happening. + +Suggested-by: Peter Zijlstra +Signed-off-by: Kees Cook +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/lkml/Ys66hwtFcGbYmoiZ@hirez.programming.kicks-ass.net/ +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/alternative.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/alternative.c ++++ b/arch/x86/kernel/alternative.c +@@ -554,7 +554,9 @@ void __init_or_module noinline apply_ret + dest = addr + insn.length + insn.immediate.value; + + if (__static_call_fixup(addr, op, dest) || +- WARN_ON_ONCE(dest != &__x86_return_thunk)) ++ WARN_ONCE(dest != &__x86_return_thunk, ++ "missing return thunk: %pS-%pS: %*ph", ++ addr, dest, 5, addr)) + continue; + + DPRINTK("return thunk at: %pS (%px) len: %d to: %pS", diff --git a/queue-5.15/x86-amd-use-ibpb-for-firmware-calls.patch b/queue-5.15/x86-amd-use-ibpb-for-firmware-calls.patch new file mode 100644 index 00000000000..724e6830d25 --- /dev/null +++ b/queue-5.15/x86-amd-use-ibpb-for-firmware-calls.patch @@ -0,0 +1,70 @@ +From 28a99e95f55c61855983d36a88c05c178d966bb7 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Mon, 18 Jul 2022 13:41:37 +0200 +Subject: x86/amd: Use IBPB for firmware calls + +From: Peter Zijlstra + +commit 28a99e95f55c61855983d36a88c05c178d966bb7 upstream. + +On AMD IBRS does not prevent Retbleed; as such use IBPB before a +firmware call to flush the branch history state. + +And because in order to do an EFI call, the kernel maps a whole lot of +the kernel page table into the EFI page table, do an IBPB just in case +in order to prevent the scenario of poisoning the BTB and causing an EFI +call using the unprotected RET there. + + [ bp: Massage. ] + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220715194550.793957-1-cascardo@canonical.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/cpufeatures.h | 1 + + arch/x86/include/asm/nospec-branch.h | 2 ++ + arch/x86/kernel/cpu/bugs.c | 11 ++++++++++- + 3 files changed, 13 insertions(+), 1 deletion(-) + +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -300,6 +300,7 @@ + #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */ + #define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */ + #define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */ ++#define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */ + + /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ + #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ +--- a/arch/x86/include/asm/nospec-branch.h ++++ b/arch/x86/include/asm/nospec-branch.h +@@ -298,6 +298,8 @@ do { \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, \ + spec_ctrl_current() | SPEC_CTRL_IBRS, \ + X86_FEATURE_USE_IBRS_FW); \ ++ alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, \ ++ X86_FEATURE_USE_IBPB_FW); \ + } while (0) + + #define firmware_restrict_branch_speculation_end() \ +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -1512,7 +1512,16 @@ static void __init spectre_v2_select_mit + * the CPU supports Enhanced IBRS, kernel might un-intentionally not + * enable IBRS around firmware calls. + */ +- if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) { ++ if (boot_cpu_has_bug(X86_BUG_RETBLEED) && ++ (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || ++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)) { ++ ++ if (retbleed_cmd != RETBLEED_CMD_IBPB) { ++ setup_force_cpu_cap(X86_FEATURE_USE_IBPB_FW); ++ pr_info("Enabling Speculation Barrier for firmware calls\n"); ++ } ++ ++ } else if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) { + setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); + pr_info("Enabling Restricted Speculation for firmware calls\n"); + } -- 2.47.3