From: Greg Kroah-Hartman Date: Thu, 27 Jan 2022 16:01:33 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.4.301~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0fb2f517c9b240a29e8753a39f8aaa1f953c5de;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: net-bridge-clear-bridge-s-private-skb-space-on-xmit.patch select-fix-indefinitely-sleeping-task-in-poll_schedule_timeout.patch --- diff --git a/queue-4.19/net-bridge-clear-bridge-s-private-skb-space-on-xmit.patch b/queue-4.19/net-bridge-clear-bridge-s-private-skb-space-on-xmit.patch new file mode 100644 index 00000000000..e796041925b --- /dev/null +++ b/queue-4.19/net-bridge-clear-bridge-s-private-skb-space-on-xmit.patch @@ -0,0 +1,37 @@ +From fd65e5a95d08389444e8591a20538b3edece0e15 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Fri, 31 Jul 2020 19:26:16 +0300 +Subject: net: bridge: clear bridge's private skb space on xmit + +From: Nikolay Aleksandrov + +commit fd65e5a95d08389444e8591a20538b3edece0e15 upstream. + +We need to clear all of the bridge private skb variables as they can be +stale due to the packet being recirculated through the stack and then +transmitted through the bridge device. Similar memset is already done on +bridge's input. We've seen cases where proxyarp_replied was 1 on routed +multicast packets transmitted through the bridge to ports with neigh +suppress which were getting dropped. Same thing can in theory happen with +the port isolation bit as well. + +Fixes: 821f1b21cabb ("bridge: add new BR_NEIGH_SUPPRESS port flag to suppress arp and nd flood") +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Huang Guobin +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_device.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/bridge/br_device.c ++++ b/net/bridge/br_device.c +@@ -42,6 +42,8 @@ netdev_tx_t br_dev_xmit(struct sk_buff * + struct ethhdr *eth; + u16 vid = 0; + ++ memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); ++ + rcu_read_lock(); + nf_ops = rcu_dereference(nf_br_ops); + if (nf_ops && nf_ops->br_dev_xmit_hook(skb)) { diff --git a/queue-4.19/select-fix-indefinitely-sleeping-task-in-poll_schedule_timeout.patch b/queue-4.19/select-fix-indefinitely-sleeping-task-in-poll_schedule_timeout.patch new file mode 100644 index 00000000000..3d1dacb9b77 --- /dev/null +++ b/queue-4.19/select-fix-indefinitely-sleeping-task-in-poll_schedule_timeout.patch @@ -0,0 +1,135 @@ +From 68514dacf2715d11b91ca50d88de047c086fea9c Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 10 Jan 2022 19:19:23 +0100 +Subject: select: Fix indefinitely sleeping task in poll_schedule_timeout() + +From: Jan Kara + +commit 68514dacf2715d11b91ca50d88de047c086fea9c upstream. + +A task can end up indefinitely sleeping in do_select() -> +poll_schedule_timeout() when the following race happens: + + TASK1 (thread1) TASK2 TASK1 (thread2) + do_select() + setup poll_wqueues table + with 'fd' + write data to 'fd' + pollwake() + table->triggered = 1 + closes 'fd' thread1 is + waiting for + poll_schedule_timeout() + - sees table->triggered + table->triggered = 0 + return -EINTR + loop back in do_select() + +But at this point when TASK1 loops back, the fdget() in the setup of +poll_wqueues fails. So now so we never find 'fd' is ready for reading +and sleep in poll_schedule_timeout() indefinitely. + +Treat an fd that got closed as a fd on which some event happened. This +makes sure cannot block indefinitely in do_select(). + +Another option would be to return -EBADF in this case but that has a +potential of subtly breaking applications that excercise this behavior +and it happens to work for them. So returning fd as active seems like a +safer choice. + +Suggested-by: Linus Torvalds +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + fs/select.c | 63 +++++++++++++++++++++++++++++++----------------------------- + 1 file changed, 33 insertions(+), 30 deletions(-) + +--- a/fs/select.c ++++ b/fs/select.c +@@ -431,9 +431,11 @@ get_max: + return max; + } + +-#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR) +-#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR) +-#define POLLEX_SET (EPOLLPRI) ++#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR |\ ++ EPOLLNVAL) ++#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR |\ ++ EPOLLNVAL) ++#define POLLEX_SET (EPOLLPRI | EPOLLNVAL) + + static inline void wait_key_set(poll_table *wait, unsigned long in, + unsigned long out, unsigned long bit, +@@ -500,6 +502,7 @@ static int do_select(int n, fd_set_bits + break; + if (!(bit & all_bits)) + continue; ++ mask = EPOLLNVAL; + f = fdget(i); + if (f.file) { + wait_key_set(wait, in, out, bit, +@@ -507,34 +510,34 @@ static int do_select(int n, fd_set_bits + mask = vfs_poll(f.file, wait); + + fdput(f); +- if ((mask & POLLIN_SET) && (in & bit)) { +- res_in |= bit; +- retval++; +- wait->_qproc = NULL; +- } +- if ((mask & POLLOUT_SET) && (out & bit)) { +- res_out |= bit; +- retval++; +- wait->_qproc = NULL; +- } +- if ((mask & POLLEX_SET) && (ex & bit)) { +- res_ex |= bit; +- retval++; +- wait->_qproc = NULL; +- } +- /* got something, stop busy polling */ +- if (retval) { +- can_busy_loop = false; +- busy_flag = 0; +- +- /* +- * only remember a returned +- * POLL_BUSY_LOOP if we asked for it +- */ +- } else if (busy_flag & mask) +- can_busy_loop = true; +- + } ++ if ((mask & POLLIN_SET) && (in & bit)) { ++ res_in |= bit; ++ retval++; ++ wait->_qproc = NULL; ++ } ++ if ((mask & POLLOUT_SET) && (out & bit)) { ++ res_out |= bit; ++ retval++; ++ wait->_qproc = NULL; ++ } ++ if ((mask & POLLEX_SET) && (ex & bit)) { ++ res_ex |= bit; ++ retval++; ++ wait->_qproc = NULL; ++ } ++ /* got something, stop busy polling */ ++ if (retval) { ++ can_busy_loop = false; ++ busy_flag = 0; ++ ++ /* ++ * only remember a returned ++ * POLL_BUSY_LOOP if we asked for it ++ */ ++ } else if (busy_flag & mask) ++ can_busy_loop = true; ++ + } + if (res_in) + *rinp = res_in; diff --git a/queue-4.19/series b/queue-4.19/series index 4f89d40aca8..8ee73c156b7 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -1 +1,3 @@ drm-i915-flush-tlbs-before-releasing-backing-store.patch +net-bridge-clear-bridge-s-private-skb-space-on-xmit.patch +select-fix-indefinitely-sleeping-task-in-poll_schedule_timeout.patch