From: Greg Kroah-Hartman Date: Fri, 3 Jun 2022 13:37:22 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.9.317~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba8e2e6bcdfd3b212bb2e26c828eec5266367e9f;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: assoc_array-fix-bug_on-during-garbage-collect.patch cfg80211-set-custom-regdomain-after-wiphy-registration.patch io_uring-don-t-re-import-iovecs-from-callbacks.patch io_uring-fix-using-under-expanded-iters.patch netfilter-nf_tables-disallow-non-stateful-expression-in-sets-earlier.patch pipe-fix-missing-lock-in-pipe_resize_ring.patch pipe-make-poll_usage-boolean-and-annotate-its-access.patch --- diff --git a/queue-5.10/assoc_array-fix-bug_on-during-garbage-collect.patch b/queue-5.10/assoc_array-fix-bug_on-during-garbage-collect.patch new file mode 100644 index 00000000000..9de75c9f61b --- /dev/null +++ b/queue-5.10/assoc_array-fix-bug_on-during-garbage-collect.patch @@ -0,0 +1,163 @@ +From d1dc87763f406d4e67caf16dbe438a5647692395 Mon Sep 17 00:00:00 2001 +From: Stephen Brennan +Date: Thu, 19 May 2022 09:50:30 +0100 +Subject: assoc_array: Fix BUG_ON during garbage collect + +From: Stephen Brennan + +commit d1dc87763f406d4e67caf16dbe438a5647692395 upstream. + +A rare BUG_ON triggered in assoc_array_gc: + + [3430308.818153] kernel BUG at lib/assoc_array.c:1609! + +Which corresponded to the statement currently at line 1593 upstream: + + BUG_ON(assoc_array_ptr_is_meta(p)); + +Using the data from the core dump, I was able to generate a userspace +reproducer[1] and determine the cause of the bug. + +[1]: https://github.com/brenns10/kernel_stuff/tree/master/assoc_array_gc + +After running the iterator on the entire branch, an internal tree node +looked like the following: + + NODE (nr_leaves_on_branch: 3) + SLOT [0] NODE (2 leaves) + SLOT [1] NODE (1 leaf) + SLOT [2..f] NODE (empty) + +In the userspace reproducer, the pr_devel output when compressing this +node was: + + -- compress node 0x5607cc089380 -- + free=0, leaves=0 + [0] retain node 2/1 [nx 0] + [1] fold node 1/1 [nx 0] + [2] fold node 0/1 [nx 2] + [3] fold node 0/2 [nx 2] + [4] fold node 0/3 [nx 2] + [5] fold node 0/4 [nx 2] + [6] fold node 0/5 [nx 2] + [7] fold node 0/6 [nx 2] + [8] fold node 0/7 [nx 2] + [9] fold node 0/8 [nx 2] + [10] fold node 0/9 [nx 2] + [11] fold node 0/10 [nx 2] + [12] fold node 0/11 [nx 2] + [13] fold node 0/12 [nx 2] + [14] fold node 0/13 [nx 2] + [15] fold node 0/14 [nx 2] + after: 3 + +At slot 0, an internal node with 2 leaves could not be folded into the +node, because there was only one available slot (slot 0). Thus, the +internal node was retained. At slot 1, the node had one leaf, and was +able to be folded in successfully. The remaining nodes had no leaves, +and so were removed. By the end of the compression stage, there were 14 +free slots, and only 3 leaf nodes. The tree was ascended and then its +parent node was compressed. When this node was seen, it could not be +folded, due to the internal node it contained. + +The invariant for compression in this function is: whenever +nr_leaves_on_branch < ASSOC_ARRAY_FAN_OUT, the node should contain all +leaf nodes. The compression step currently cannot guarantee this, given +the corner case shown above. + +To fix this issue, retry compression whenever we have retained a node, +and yet nr_leaves_on_branch < ASSOC_ARRAY_FAN_OUT. This second +compression will then allow the node in slot 1 to be folded in, +satisfying the invariant. Below is the output of the reproducer once the +fix is applied: + + -- compress node 0x560e9c562380 -- + free=0, leaves=0 + [0] retain node 2/1 [nx 0] + [1] fold node 1/1 [nx 0] + [2] fold node 0/1 [nx 2] + [3] fold node 0/2 [nx 2] + [4] fold node 0/3 [nx 2] + [5] fold node 0/4 [nx 2] + [6] fold node 0/5 [nx 2] + [7] fold node 0/6 [nx 2] + [8] fold node 0/7 [nx 2] + [9] fold node 0/8 [nx 2] + [10] fold node 0/9 [nx 2] + [11] fold node 0/10 [nx 2] + [12] fold node 0/11 [nx 2] + [13] fold node 0/12 [nx 2] + [14] fold node 0/13 [nx 2] + [15] fold node 0/14 [nx 2] + internal nodes remain despite enough space, retrying + -- compress node 0x560e9c562380 -- + free=14, leaves=1 + [0] fold node 2/15 [nx 0] + after: 3 + +Changes +======= +DH: + - Use false instead of 0. + - Reorder the inserted lines in a couple of places to put retained before + next_slot. + +ver #2) + - Fix typo in pr_devel, correct comparison to "<=" + +Fixes: 3cb989501c26 ("Add a generic associative array implementation.") +Cc: +Signed-off-by: Stephen Brennan +Signed-off-by: David Howells +cc: Andrew Morton +cc: keyrings@vger.kernel.org +Link: https://lore.kernel.org/r/20220511225517.407935-1-stephen.s.brennan@oracle.com/ # v1 +Link: https://lore.kernel.org/r/20220512215045.489140-1-stephen.s.brennan@oracle.com/ # v2 +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + lib/assoc_array.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/lib/assoc_array.c ++++ b/lib/assoc_array.c +@@ -1462,6 +1462,7 @@ int assoc_array_gc(struct assoc_array *a + struct assoc_array_ptr *cursor, *ptr; + struct assoc_array_ptr *new_root, *new_parent, **new_ptr_pp; + unsigned long nr_leaves_on_tree; ++ bool retained; + int keylen, slot, nr_free, next_slot, i; + + pr_devel("-->%s()\n", __func__); +@@ -1538,6 +1539,7 @@ continue_node: + goto descend; + } + ++retry_compress: + pr_devel("-- compress node %p --\n", new_n); + + /* Count up the number of empty slots in this node and work out the +@@ -1555,6 +1557,7 @@ continue_node: + pr_devel("free=%d, leaves=%lu\n", nr_free, new_n->nr_leaves_on_branch); + + /* See what we can fold in */ ++ retained = false; + next_slot = 0; + for (slot = 0; slot < ASSOC_ARRAY_FAN_OUT; slot++) { + struct assoc_array_shortcut *s; +@@ -1604,9 +1607,14 @@ continue_node: + pr_devel("[%d] retain node %lu/%d [nx %d]\n", + slot, child->nr_leaves_on_branch, nr_free + 1, + next_slot); ++ retained = true; + } + } + ++ if (retained && new_n->nr_leaves_on_branch <= ASSOC_ARRAY_FAN_OUT) { ++ pr_devel("internal nodes remain despite enough space, retrying\n"); ++ goto retry_compress; ++ } + pr_devel("after: %lu\n", new_n->nr_leaves_on_branch); + + nr_leaves_on_tree = new_n->nr_leaves_on_branch; diff --git a/queue-5.10/cfg80211-set-custom-regdomain-after-wiphy-registration.patch b/queue-5.10/cfg80211-set-custom-regdomain-after-wiphy-registration.patch new file mode 100644 index 00000000000..196a6188a6c --- /dev/null +++ b/queue-5.10/cfg80211-set-custom-regdomain-after-wiphy-registration.patch @@ -0,0 +1,68 @@ +From 1b7b3ac8ff3317cdcf07a1c413de9bdb68019c2b Mon Sep 17 00:00:00 2001 +From: Miri Korenblit +Date: Fri, 18 Jun 2021 13:41:46 +0300 +Subject: cfg80211: set custom regdomain after wiphy registration + +From: Miri Korenblit + +commit 1b7b3ac8ff3317cdcf07a1c413de9bdb68019c2b upstream. + +We used to set regulatory info before the registration of +the device and then the regulatory info didn't get set, because +the device isn't registered so there isn't a device to set the +regulatory info for. So set the regulatory info after the device +registration. +Call reg_process_self_managed_hints() once again after the device +registration because it does nothing before it. + +Signed-off-by: Miri Korenblit +Signed-off-by: Luca Coelho +Link: https://lore.kernel.org/r/iwlwifi.20210618133832.c96eadcffe80.I86799c2c866b5610b4cf91115c21d8ceb525c5aa@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/wireless/core.c | 8 ++++---- + net/wireless/reg.c | 1 + + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -5,7 +5,7 @@ + * Copyright 2006-2010 Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright 2015-2017 Intel Deutschland GmbH +- * Copyright (C) 2018-2020 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + */ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +@@ -918,9 +918,6 @@ int wiphy_register(struct wiphy *wiphy) + return res; + } + +- /* set up regulatory info */ +- wiphy_regulatory_register(wiphy); +- + list_add_rcu(&rdev->list, &cfg80211_rdev_list); + cfg80211_rdev_list_generation++; + +@@ -931,6 +928,9 @@ int wiphy_register(struct wiphy *wiphy) + cfg80211_debugfs_rdev_add(rdev); + nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); + ++ /* set up regulatory info */ ++ wiphy_regulatory_register(wiphy); ++ + if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) { + struct regulatory_request request; + +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -4001,6 +4001,7 @@ void wiphy_regulatory_register(struct wi + + wiphy_update_regulatory(wiphy, lr->initiator); + wiphy_all_share_dfs_chan_state(wiphy); ++ reg_process_self_managed_hints(); + } + + void wiphy_regulatory_deregister(struct wiphy *wiphy) diff --git a/queue-5.10/io_uring-don-t-re-import-iovecs-from-callbacks.patch b/queue-5.10/io_uring-don-t-re-import-iovecs-from-callbacks.patch new file mode 100644 index 00000000000..d4657de9657 --- /dev/null +++ b/queue-5.10/io_uring-don-t-re-import-iovecs-from-callbacks.patch @@ -0,0 +1,73 @@ +From foo@baz Fri Jun 3 03:29:03 PM CEST 2022 +From: Pavel Begunkov +Date: Fri, 3 Jun 2022 13:17:04 +0100 +Subject: io_uring: don't re-import iovecs from callbacks +To: stable@vger.kernel.org +Cc: Greg Kroah-Hartman , Jens Axboe , asml.silence@gmail.com +Message-ID: <34f9e14b1adef255bc205bcb0e6c6d6110646689.1654258554.git.asml.silence@gmail.com> + +From: Pavel Begunkov + +We can't re-import or modify iterators from iocb callbacks, it's not +safe as it might be reverted and/or reexpanded while unwinding stack. +It's also not safe to resubmit as io-wq thread will race with stack +undwinding for the iterator and other data. + +Disallow resubmission from callbacks, it can fail some cases that were +handled before, but the possibility of such a failure was a part of the +API from the beginning and so it should be fine. + +Signed-off-by: Pavel Begunkov +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 39 --------------------------------------- + 1 file changed, 39 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2579,45 +2579,6 @@ static void io_complete_rw_common(struct + #ifdef CONFIG_BLOCK + static bool io_resubmit_prep(struct io_kiocb *req, int error) + { +- struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; +- ssize_t ret = -ECANCELED; +- struct iov_iter iter; +- int rw; +- +- if (error) { +- ret = error; +- goto end_req; +- } +- +- switch (req->opcode) { +- case IORING_OP_READV: +- case IORING_OP_READ_FIXED: +- case IORING_OP_READ: +- rw = READ; +- break; +- case IORING_OP_WRITEV: +- case IORING_OP_WRITE_FIXED: +- case IORING_OP_WRITE: +- rw = WRITE; +- break; +- default: +- printk_once(KERN_WARNING "io_uring: bad opcode in resubmit %d\n", +- req->opcode); +- goto end_req; +- } +- +- if (!req->async_data) { +- ret = io_import_iovec(rw, req, &iovec, &iter, false); +- if (ret < 0) +- goto end_req; +- ret = io_setup_async_rw(req, iovec, inline_vecs, &iter, false); +- if (!ret) +- return true; +- kfree(iovec); +- } else { +- return true; +- } +-end_req: + req_set_fail_links(req); + return false; + } diff --git a/queue-5.10/io_uring-fix-using-under-expanded-iters.patch b/queue-5.10/io_uring-fix-using-under-expanded-iters.patch new file mode 100644 index 00000000000..296282b17dd --- /dev/null +++ b/queue-5.10/io_uring-fix-using-under-expanded-iters.patch @@ -0,0 +1,80 @@ +From foo@baz Fri Jun 3 03:29:03 PM CEST 2022 +From: Pavel Begunkov +Date: Fri, 3 Jun 2022 13:17:05 +0100 +Subject: io_uring: fix using under-expanded iters +To: stable@vger.kernel.org +Cc: Greg Kroah-Hartman , Jens Axboe , asml.silence@gmail.com +Message-ID: <5d1530f17820142cfe98a8fff6d425d47c4b18ca.1654258554.git.asml.silence@gmail.com> + +From: Pavel Begunkov + +[ upstream commit cd65869512ab5668a5d16f789bc4da1319c435c4 ] + +The issue was first described and addressed in +89c2b3b7491820 ("io_uring: reexpand under-reexpanded iters"), but +shortly after reimplemented as. +cd65869512ab56 ("io_uring: use iov_iter state save/restore helpers"). + +Here we follow the approach from the second patch but without in-callback +resubmissions, fixups for not yet supported in 5.10 short read retries +and replacing iov_iter_state with iter copies to not pull even more +dependencies, and because it's just much simpler. + +Signed-off-by: Pavel Begunkov +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -3389,6 +3389,7 @@ static int io_read(struct io_kiocb *req, + struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; + struct kiocb *kiocb = &req->rw.kiocb; + struct iov_iter __iter, *iter = &__iter; ++ struct iov_iter iter_cp; + struct io_async_rw *rw = req->async_data; + ssize_t io_size, ret, ret2; + bool no_async; +@@ -3399,6 +3400,7 @@ static int io_read(struct io_kiocb *req, + ret = io_import_iovec(READ, req, &iovec, iter, !force_nonblock); + if (ret < 0) + return ret; ++ iter_cp = *iter; + io_size = iov_iter_count(iter); + req->result = io_size; + ret = 0; +@@ -3434,7 +3436,7 @@ static int io_read(struct io_kiocb *req, + if (req->file->f_flags & O_NONBLOCK) + goto done; + /* some cases will consume bytes even on error returns */ +- iov_iter_revert(iter, io_size - iov_iter_count(iter)); ++ *iter = iter_cp; + ret = 0; + goto copy_iov; + } else if (ret < 0) { +@@ -3517,6 +3519,7 @@ static int io_write(struct io_kiocb *req + struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; + struct kiocb *kiocb = &req->rw.kiocb; + struct iov_iter __iter, *iter = &__iter; ++ struct iov_iter iter_cp; + struct io_async_rw *rw = req->async_data; + ssize_t ret, ret2, io_size; + +@@ -3526,6 +3529,7 @@ static int io_write(struct io_kiocb *req + ret = io_import_iovec(WRITE, req, &iovec, iter, !force_nonblock); + if (ret < 0) + return ret; ++ iter_cp = *iter; + io_size = iov_iter_count(iter); + req->result = io_size; + +@@ -3587,7 +3591,7 @@ done: + } else { + copy_iov: + /* some cases will consume bytes even on error returns */ +- iov_iter_revert(iter, io_size - iov_iter_count(iter)); ++ *iter = iter_cp; + ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false); + if (!ret) + return -EAGAIN; diff --git a/queue-5.10/netfilter-nf_tables-disallow-non-stateful-expression-in-sets-earlier.patch b/queue-5.10/netfilter-nf_tables-disallow-non-stateful-expression-in-sets-earlier.patch new file mode 100644 index 00000000000..aec92ba0295 --- /dev/null +++ b/queue-5.10/netfilter-nf_tables-disallow-non-stateful-expression-in-sets-earlier.patch @@ -0,0 +1,98 @@ +From 520778042ccca019f3ffa136dd0ca565c486cedd Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Wed, 25 May 2022 10:36:38 +0200 +Subject: netfilter: nf_tables: disallow non-stateful expression in sets earlier + +From: Pablo Neira Ayuso + +commit 520778042ccca019f3ffa136dd0ca565c486cedd upstream. + +Since 3e135cd499bf ("netfilter: nft_dynset: dynamic stateful expression +instantiation"), it is possible to attach stateful expressions to set +elements. + +cd5125d8f518 ("netfilter: nf_tables: split set destruction in deactivate +and destroy phase") introduces conditional destruction on the object to +accomodate transaction semantics. + +nft_expr_init() calls expr->ops->init() first, then check for +NFT_STATEFUL_EXPR, this stills allows to initialize a non-stateful +lookup expressions which points to a set, which might lead to UAF since +the set is not properly detached from the set->binding for this case. +Anyway, this combination is non-sense from nf_tables perspective. + +This patch fixes this problem by checking for NFT_STATEFUL_EXPR before +expr->ops->init() is called. + +The reporter provides a KASAN splat and a poc reproducer (similar to +those autogenerated by syzbot to report use-after-free errors). It is +unknown to me if they are using syzbot or if they use similar automated +tool to locate the bug that they are reporting. + +For the record, this is the KASAN splat. + +[ 85.431824] ================================================================== +[ 85.432901] BUG: KASAN: use-after-free in nf_tables_bind_set+0x81b/0xa20 +[ 85.433825] Write of size 8 at addr ffff8880286f0e98 by task poc/776 +[ 85.434756] +[ 85.434999] CPU: 1 PID: 776 Comm: poc Tainted: G W 5.18.0+ #2 +[ 85.436023] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 + +Fixes: 0b2d8a7b638b ("netfilter: nf_tables: add helper functions for expression handling") +Reported-and-tested-by: Aaron Adams +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman +--- + net/netfilter/nf_tables_api.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2679,27 +2679,31 @@ static struct nft_expr *nft_expr_init(co + + err = nf_tables_expr_parse(ctx, nla, &info); + if (err < 0) +- goto err1; ++ goto err_expr_parse; ++ ++ err = -EOPNOTSUPP; ++ if (!(expr_info.ops->type->flags & NFT_EXPR_STATEFUL)) ++ goto err_expr_stateful; + + err = -ENOMEM; + expr = kzalloc(info.ops->size, GFP_KERNEL); + if (expr == NULL) +- goto err2; ++ goto err_expr_stateful; + + err = nf_tables_newexpr(ctx, &info, expr); + if (err < 0) +- goto err3; ++ goto err_expr_new; + + return expr; +-err3: ++err_expr_new: + kfree(expr); +-err2: ++err_expr_stateful: + owner = info.ops->type->owner; + if (info.ops->type->release_ops) + info.ops->type->release_ops(info.ops); + + module_put(owner); +-err1: ++err_expr_parse: + return ERR_PTR(err); + } + +@@ -5055,9 +5059,6 @@ struct nft_expr *nft_set_elem_expr_alloc + return expr; + + err = -EOPNOTSUPP; +- if (!(expr->ops->type->flags & NFT_EXPR_STATEFUL)) +- goto err_set_elem_expr; +- + if (expr->ops->type->flags & NFT_EXPR_GC) { + if (set->flags & NFT_SET_TIMEOUT) + goto err_set_elem_expr; diff --git a/queue-5.10/pipe-fix-missing-lock-in-pipe_resize_ring.patch b/queue-5.10/pipe-fix-missing-lock-in-pipe_resize_ring.patch new file mode 100644 index 00000000000..6d739dfb395 --- /dev/null +++ b/queue-5.10/pipe-fix-missing-lock-in-pipe_resize_ring.patch @@ -0,0 +1,100 @@ +From 189b0ddc245139af81198d1a3637cac74f96e13a Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Thu, 26 May 2022 07:34:52 +0100 +Subject: pipe: Fix missing lock in pipe_resize_ring() + +From: David Howells + +commit 189b0ddc245139af81198d1a3637cac74f96e13a upstream. + +pipe_resize_ring() needs to take the pipe->rd_wait.lock spinlock to +prevent post_one_notification() from trying to insert into the ring +whilst the ring is being replaced. + +The occupancy check must be done after the lock is taken, and the lock +must be taken after the new ring is allocated. + +The bug can lead to an oops looking something like: + + BUG: KASAN: use-after-free in post_one_notification.isra.0+0x62e/0x840 + Read of size 4 at addr ffff88801cc72a70 by task poc/27196 + ... + Call Trace: + post_one_notification.isra.0+0x62e/0x840 + __post_watch_notification+0x3b7/0x650 + key_create_or_update+0xb8b/0xd20 + __do_sys_add_key+0x175/0x340 + __x64_sys_add_key+0xbe/0x140 + do_syscall_64+0x5c/0xc0 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +Reported by Selim Enes Karaduman @Enesdex working with Trend Micro Zero +Day Initiative. + +Fixes: c73be61cede5 ("pipe: Add general notification queue support") +Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-17291 +Signed-off-by: David Howells +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + fs/pipe.c | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +--- a/fs/pipe.c ++++ b/fs/pipe.c +@@ -1244,30 +1244,33 @@ unsigned int round_pipe_size(unsigned lo + + /* + * Resize the pipe ring to a number of slots. ++ * ++ * Note the pipe can be reduced in capacity, but only if the current ++ * occupancy doesn't exceed nr_slots; if it does, EBUSY will be ++ * returned instead. + */ + int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots) + { + struct pipe_buffer *bufs; + unsigned int head, tail, mask, n; + +- /* +- * We can shrink the pipe, if arg is greater than the ring occupancy. +- * Since we don't expect a lot of shrink+grow operations, just free and +- * allocate again like we would do for growing. If the pipe currently +- * contains more buffers than arg, then return busy. +- */ +- mask = pipe->ring_size - 1; +- head = pipe->head; +- tail = pipe->tail; +- n = pipe_occupancy(pipe->head, pipe->tail); +- if (nr_slots < n) +- return -EBUSY; +- + bufs = kcalloc(nr_slots, sizeof(*bufs), + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); + if (unlikely(!bufs)) + return -ENOMEM; + ++ spin_lock_irq(&pipe->rd_wait.lock); ++ mask = pipe->ring_size - 1; ++ head = pipe->head; ++ tail = pipe->tail; ++ ++ n = pipe_occupancy(head, tail); ++ if (nr_slots < n) { ++ spin_unlock_irq(&pipe->rd_wait.lock); ++ kfree(bufs); ++ return -EBUSY; ++ } ++ + /* + * The pipe array wraps around, so just start the new one at zero + * and adjust the indices. +@@ -1299,6 +1302,8 @@ int pipe_resize_ring(struct pipe_inode_i + pipe->tail = tail; + pipe->head = head; + ++ spin_unlock_irq(&pipe->rd_wait.lock); ++ + /* This might have made more room for writers */ + wake_up_interruptible(&pipe->wr_wait); + return 0; diff --git a/queue-5.10/pipe-make-poll_usage-boolean-and-annotate-its-access.patch b/queue-5.10/pipe-make-poll_usage-boolean-and-annotate-its-access.patch new file mode 100644 index 00000000000..baf56b8d6fb --- /dev/null +++ b/queue-5.10/pipe-make-poll_usage-boolean-and-annotate-its-access.patch @@ -0,0 +1,82 @@ +From f485922d8fe4e44f6d52a5bb95a603b7c65554bb Mon Sep 17 00:00:00 2001 +From: Kuniyuki Iwashima +Date: Fri, 29 Apr 2022 14:38:01 -0700 +Subject: pipe: make poll_usage boolean and annotate its access + +From: Kuniyuki Iwashima + +commit f485922d8fe4e44f6d52a5bb95a603b7c65554bb upstream. + +Patch series "Fix data-races around epoll reported by KCSAN." + +This series suppresses a false positive KCSAN's message and fixes a real +data-race. + + +This patch (of 2): + +pipe_poll() runs locklessly and assigns 1 to poll_usage. Once poll_usage +is set to 1, it never changes in other places. However, concurrent writes +of a value trigger KCSAN, so let's make KCSAN happy. + +BUG: KCSAN: data-race in pipe_poll / pipe_poll + +write to 0xffff8880042f6678 of 4 bytes by task 174 on cpu 3: + pipe_poll (fs/pipe.c:656) + ep_item_poll.isra.0 (./include/linux/poll.h:88 fs/eventpoll.c:853) + do_epoll_wait (fs/eventpoll.c:1692 fs/eventpoll.c:1806 fs/eventpoll.c:2234) + __x64_sys_epoll_wait (fs/eventpoll.c:2246 fs/eventpoll.c:2241 fs/eventpoll.c:2241) + do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:113) + +write to 0xffff8880042f6678 of 4 bytes by task 177 on cpu 1: + pipe_poll (fs/pipe.c:656) + ep_item_poll.isra.0 (./include/linux/poll.h:88 fs/eventpoll.c:853) + do_epoll_wait (fs/eventpoll.c:1692 fs/eventpoll.c:1806 fs/eventpoll.c:2234) + __x64_sys_epoll_wait (fs/eventpoll.c:2246 fs/eventpoll.c:2241 fs/eventpoll.c:2241) + do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:113) + +Reported by Kernel Concurrency Sanitizer on: +CPU: 1 PID: 177 Comm: epoll_race Not tainted 5.17.0-58927-gf443e374ae13 #6 +Hardware name: Red Hat KVM, BIOS 1.11.0-2.amzn2 04/01/2014 + +Link: https://lkml.kernel.org/r/20220322002653.33865-1-kuniyu@amazon.co.jp +Link: https://lkml.kernel.org/r/20220322002653.33865-2-kuniyu@amazon.co.jp +Fixes: 3b844826b6c6 ("pipe: avoid unnecessary EPOLLET wakeups under normal loads") +Signed-off-by: Kuniyuki Iwashima +Cc: Alexander Duyck +Cc: Al Viro +Cc: Davidlohr Bueso +Cc: Kuniyuki Iwashima +Cc: "Soheil Hassas Yeganeh" +Cc: "Sridhar Samudrala" +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/pipe.c | 2 +- + include/linux/pipe_fs_i.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/pipe.c ++++ b/fs/pipe.c +@@ -652,7 +652,7 @@ pipe_poll(struct file *filp, poll_table + unsigned int head, tail; + + /* Epoll has some historical nasty semantics, this enables them */ +- pipe->poll_usage = 1; ++ WRITE_ONCE(pipe->poll_usage, true); + + /* + * Reading pipe state only -- no need for acquiring the semaphore. +--- a/include/linux/pipe_fs_i.h ++++ b/include/linux/pipe_fs_i.h +@@ -71,7 +71,7 @@ struct pipe_inode_info { + unsigned int files; + unsigned int r_counter; + unsigned int w_counter; +- unsigned int poll_usage; ++ bool poll_usage; + struct page *tmp_page; + struct fasync_struct *fasync_readers; + struct fasync_struct *fasync_writers; diff --git a/queue-5.10/series b/queue-5.10/series index 91bfd39bcd1..be09ec7802f 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -5,3 +5,10 @@ nfc-pn533-fix-buggy-cleanup-order.patch net-ftgmac100-disable-hardware-checksum-on-ast2600.patch i2c-ismt-provide-a-dma-buffer-for-interrupt-cause-lo.patch drivers-i2c-thunderx-allow-driver-to-work-with-acpi-.patch +netfilter-nf_tables-disallow-non-stateful-expression-in-sets-earlier.patch +pipe-make-poll_usage-boolean-and-annotate-its-access.patch +pipe-fix-missing-lock-in-pipe_resize_ring.patch +cfg80211-set-custom-regdomain-after-wiphy-registration.patch +assoc_array-fix-bug_on-during-garbage-collect.patch +io_uring-don-t-re-import-iovecs-from-callbacks.patch +io_uring-fix-using-under-expanded-iters.patch