From: Greg Kroah-Hartman Date: Mon, 9 May 2022 08:38:35 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.9.313~96 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6f2201c74bbe4a5e49b6a0d387b1818bbd5a0763;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: firewire-core-extend-card-lock-in-fw_core_handle_bus_reset.patch firewire-fix-potential-uaf-in-outbound_phy_packet_callback.patch firewire-remove-check-of-list-iterator-against-head-past-the-loop-body.patch revert-sunrpc-attempt-af_local-connect-on-setup.patch --- diff --git a/queue-4.14/firewire-core-extend-card-lock-in-fw_core_handle_bus_reset.patch b/queue-4.14/firewire-core-extend-card-lock-in-fw_core_handle_bus_reset.patch new file mode 100644 index 00000000000..7c87af5f27e --- /dev/null +++ b/queue-4.14/firewire-core-extend-card-lock-in-fw_core_handle_bus_reset.patch @@ -0,0 +1,91 @@ +From a7ecbe92b9243edbe94772f6f2c854e4142a3345 Mon Sep 17 00:00:00 2001 +From: Niels Dossche +Date: Sat, 9 Apr 2022 13:12:43 +0900 +Subject: firewire: core: extend card->lock in fw_core_handle_bus_reset + +From: Niels Dossche + +commit a7ecbe92b9243edbe94772f6f2c854e4142a3345 upstream. + +card->local_node and card->bm_retries are both always accessed under +card->lock. +fw_core_handle_bus_reset has a check whose condition depends on +card->local_node and whose body writes to card->bm_retries. +Both of these accesses are not under card->lock. Move the lock acquiring +of card->lock to before this check such that these accesses do happen +when card->lock is held. +fw_destroy_nodes is called inside the check. +Since fw_destroy_nodes already acquires card->lock inside its function +body, move this out to the callsites of fw_destroy_nodes. +Also add a comment to indicate which locking is necessary when calling +fw_destroy_nodes. + +Cc: +Signed-off-by: Niels Dossche +Signed-off-by: Takashi Sakamoto +Link: https://lore.kernel.org/r/20220409041243.603210-4-o-takashi@sakamocchi.jp +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firewire/core-card.c | 3 +++ + drivers/firewire/core-topology.c | 9 +++------ + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/firewire/core-card.c ++++ b/drivers/firewire/core-card.c +@@ -681,6 +681,7 @@ EXPORT_SYMBOL_GPL(fw_card_release); + void fw_core_remove_card(struct fw_card *card) + { + struct fw_card_driver dummy_driver = dummy_driver_template; ++ unsigned long flags; + + card->driver->update_phy_reg(card, 4, + PHY_LINK_ACTIVE | PHY_CONTENDER, 0); +@@ -695,7 +696,9 @@ void fw_core_remove_card(struct fw_card + dummy_driver.stop_iso = card->driver->stop_iso; + card->driver = &dummy_driver; + ++ spin_lock_irqsave(&card->lock, flags); + fw_destroy_nodes(card); ++ spin_unlock_irqrestore(&card->lock, flags); + + /* Wait for all users, especially device workqueue jobs, to finish. */ + fw_card_put(card); +--- a/drivers/firewire/core-topology.c ++++ b/drivers/firewire/core-topology.c +@@ -387,16 +387,13 @@ static void report_found_node(struct fw_ + card->bm_retries = 0; + } + ++/* Must be called with card->lock held */ + void fw_destroy_nodes(struct fw_card *card) + { +- unsigned long flags; +- +- spin_lock_irqsave(&card->lock, flags); + card->color++; + if (card->local_node != NULL) + for_each_fw_node(card, card->local_node, report_lost_node); + card->local_node = NULL; +- spin_unlock_irqrestore(&card->lock, flags); + } + + static void move_tree(struct fw_node *node0, struct fw_node *node1, int port) +@@ -522,6 +519,8 @@ void fw_core_handle_bus_reset(struct fw_ + struct fw_node *local_node; + unsigned long flags; + ++ spin_lock_irqsave(&card->lock, flags); ++ + /* + * If the selfID buffer is not the immediate successor of the + * previously processed one, we cannot reliably compare the +@@ -533,8 +532,6 @@ void fw_core_handle_bus_reset(struct fw_ + card->bm_retries = 0; + } + +- spin_lock_irqsave(&card->lock, flags); +- + card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated; + card->node_id = node_id; + /* diff --git a/queue-4.14/firewire-fix-potential-uaf-in-outbound_phy_packet_callback.patch b/queue-4.14/firewire-fix-potential-uaf-in-outbound_phy_packet_callback.patch new file mode 100644 index 00000000000..1c83f9b913e --- /dev/null +++ b/queue-4.14/firewire-fix-potential-uaf-in-outbound_phy_packet_callback.patch @@ -0,0 +1,47 @@ +From b7c81f80246fac44077166f3e07103affe6db8ff Mon Sep 17 00:00:00 2001 +From: Chengfeng Ye +Date: Sat, 9 Apr 2022 13:12:41 +0900 +Subject: firewire: fix potential uaf in outbound_phy_packet_callback() + +From: Chengfeng Ye + +commit b7c81f80246fac44077166f3e07103affe6db8ff upstream. + +&e->event and e point to the same address, and &e->event could +be freed in queue_event. So there is a potential uaf issue if +we dereference e after calling queue_event(). Fix this by adding +a temporary variable to maintain e->client in advance, this can +avoid the potential uaf issue. + +Cc: +Signed-off-by: Chengfeng Ye +Signed-off-by: Takashi Sakamoto +Link: https://lore.kernel.org/r/20220409041243.603210-2-o-takashi@sakamocchi.jp +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firewire/core-cdev.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/firewire/core-cdev.c ++++ b/drivers/firewire/core-cdev.c +@@ -1495,6 +1495,7 @@ static void outbound_phy_packet_callback + { + struct outbound_phy_packet_event *e = + container_of(packet, struct outbound_phy_packet_event, p); ++ struct client *e_client; + + switch (status) { + /* expected: */ +@@ -1511,9 +1512,10 @@ static void outbound_phy_packet_callback + } + e->phy_packet.data[0] = packet->timestamp; + ++ e_client = e->client; + queue_event(e->client, &e->event, &e->phy_packet, + sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0); +- client_put(e->client); ++ client_put(e_client); + } + + static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) diff --git a/queue-4.14/firewire-remove-check-of-list-iterator-against-head-past-the-loop-body.patch b/queue-4.14/firewire-remove-check-of-list-iterator-against-head-past-the-loop-body.patch new file mode 100644 index 00000000000..1f818bb5745 --- /dev/null +++ b/queue-4.14/firewire-remove-check-of-list-iterator-against-head-past-the-loop-body.patch @@ -0,0 +1,140 @@ +From 9423973869bd4632ffe669f950510c49296656e0 Mon Sep 17 00:00:00 2001 +From: Jakob Koschel +Date: Sat, 9 Apr 2022 13:12:42 +0900 +Subject: firewire: remove check of list iterator against head past the loop body + +From: Jakob Koschel + +commit 9423973869bd4632ffe669f950510c49296656e0 upstream. + +When list_for_each_entry() completes the iteration over the whole list +without breaking the loop, the iterator value will be a bogus pointer +computed based on the head element. + +While it is safe to use the pointer to determine if it was computed +based on the head element, either with list_entry_is_head() or +&pos->member == head, using the iterator variable after the loop should +be avoided. + +In preparation to limit the scope of a list iterator to the list +traversal loop, use a dedicated pointer to point to the found element [1]. + +Link: https://lore.kernel.org/all/CAHk-=wgRr_D8CB-D9Kg-c=EHreAsk5SqXPwr9Y7k9sA6cWXJ6w@mail.gmail.com/ [1] +Cc: +Signed-off-by: Jakob Koschel +Signed-off-by: Takashi Sakamoto +Link: https://lore.kernel.org/r/20220409041243.603210-3-o-takashi@sakamocchi.jp +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firewire/core-transaction.c | 30 ++++++++++++++++-------------- + drivers/firewire/sbp2.c | 13 +++++++------ + 2 files changed, 23 insertions(+), 20 deletions(-) + +--- a/drivers/firewire/core-transaction.c ++++ b/drivers/firewire/core-transaction.c +@@ -86,24 +86,25 @@ static int try_cancel_split_timeout(stru + static int close_transaction(struct fw_transaction *transaction, + struct fw_card *card, int rcode) + { +- struct fw_transaction *t; ++ struct fw_transaction *t = NULL, *iter; + unsigned long flags; + + spin_lock_irqsave(&card->lock, flags); +- list_for_each_entry(t, &card->transaction_list, link) { +- if (t == transaction) { +- if (!try_cancel_split_timeout(t)) { ++ list_for_each_entry(iter, &card->transaction_list, link) { ++ if (iter == transaction) { ++ if (!try_cancel_split_timeout(iter)) { + spin_unlock_irqrestore(&card->lock, flags); + goto timed_out; + } +- list_del_init(&t->link); +- card->tlabel_mask &= ~(1ULL << t->tlabel); ++ list_del_init(&iter->link); ++ card->tlabel_mask &= ~(1ULL << iter->tlabel); ++ t = iter; + break; + } + } + spin_unlock_irqrestore(&card->lock, flags); + +- if (&t->link != &card->transaction_list) { ++ if (t) { + t->callback(card, rcode, NULL, 0, t->callback_data); + return 0; + } +@@ -938,7 +939,7 @@ EXPORT_SYMBOL(fw_core_handle_request); + + void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) + { +- struct fw_transaction *t; ++ struct fw_transaction *t = NULL, *iter; + unsigned long flags; + u32 *data; + size_t data_length; +@@ -950,20 +951,21 @@ void fw_core_handle_response(struct fw_c + rcode = HEADER_GET_RCODE(p->header[1]); + + spin_lock_irqsave(&card->lock, flags); +- list_for_each_entry(t, &card->transaction_list, link) { +- if (t->node_id == source && t->tlabel == tlabel) { +- if (!try_cancel_split_timeout(t)) { ++ list_for_each_entry(iter, &card->transaction_list, link) { ++ if (iter->node_id == source && iter->tlabel == tlabel) { ++ if (!try_cancel_split_timeout(iter)) { + spin_unlock_irqrestore(&card->lock, flags); + goto timed_out; + } +- list_del_init(&t->link); +- card->tlabel_mask &= ~(1ULL << t->tlabel); ++ list_del_init(&iter->link); ++ card->tlabel_mask &= ~(1ULL << iter->tlabel); ++ t = iter; + break; + } + } + spin_unlock_irqrestore(&card->lock, flags); + +- if (&t->link == &card->transaction_list) { ++ if (!t) { + timed_out: + fw_notice(card, "unsolicited response (source %x, tlabel %x)\n", + source, tlabel); +--- a/drivers/firewire/sbp2.c ++++ b/drivers/firewire/sbp2.c +@@ -421,7 +421,7 @@ static void sbp2_status_write(struct fw_ + void *payload, size_t length, void *callback_data) + { + struct sbp2_logical_unit *lu = callback_data; +- struct sbp2_orb *orb; ++ struct sbp2_orb *orb = NULL, *iter; + struct sbp2_status status; + unsigned long flags; + +@@ -446,17 +446,18 @@ static void sbp2_status_write(struct fw_ + + /* Lookup the orb corresponding to this status write. */ + spin_lock_irqsave(&lu->tgt->lock, flags); +- list_for_each_entry(orb, &lu->orb_list, link) { ++ list_for_each_entry(iter, &lu->orb_list, link) { + if (STATUS_GET_ORB_HIGH(status) == 0 && +- STATUS_GET_ORB_LOW(status) == orb->request_bus) { +- orb->rcode = RCODE_COMPLETE; +- list_del(&orb->link); ++ STATUS_GET_ORB_LOW(status) == iter->request_bus) { ++ iter->rcode = RCODE_COMPLETE; ++ list_del(&iter->link); ++ orb = iter; + break; + } + } + spin_unlock_irqrestore(&lu->tgt->lock, flags); + +- if (&orb->link != &lu->orb_list) { ++ if (orb) { + orb->callback(orb, &status); + kref_put(&orb->kref, free_orb); /* orb callback reference */ + } else { diff --git a/queue-4.14/revert-sunrpc-attempt-af_local-connect-on-setup.patch b/queue-4.14/revert-sunrpc-attempt-af_local-connect-on-setup.patch new file mode 100644 index 00000000000..623a0c46466 --- /dev/null +++ b/queue-4.14/revert-sunrpc-attempt-af_local-connect-on-setup.patch @@ -0,0 +1,36 @@ +From a3d0562d4dc039bca39445e1cddde7951662e17d Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 29 Apr 2022 12:27:30 -0400 +Subject: Revert "SUNRPC: attempt AF_LOCAL connect on setup" + +From: Trond Myklebust + +commit a3d0562d4dc039bca39445e1cddde7951662e17d upstream. + +This reverts commit 7073ea8799a8cf73db60270986f14e4aae20fa80. + +We must not try to connect the socket while the transport is under +construction, because the mechanisms to safely tear it down are not in +place. As the code stands, we end up leaking the sockets on a connection +error. + +Reported-by: wanghai (M) +Cc: stable@vger.kernel.org +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman +--- + net/sunrpc/xprtsock.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -2941,9 +2941,6 @@ static struct rpc_xprt *xs_setup_local(s + } + xprt_set_bound(xprt); + xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL); +- ret = ERR_PTR(xs_local_setup_socket(transport)); +- if (ret) +- goto out_err; + break; + default: + ret = ERR_PTR(-EAFNOSUPPORT); diff --git a/queue-4.14/series b/queue-4.14/series index b65268aff09..ee79350fd22 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -54,3 +54,7 @@ drm-vgem-close-use-after-free-race-in-vgem_gem_create.patch mips-fix-cp0-counter-erratum-detection-for-r4k-cpus.patch parisc-merge-model-and-model-name-into-one-line-in-proc-cpuinfo.patch alsa-fireworks-fix-wrong-return-count-shorter-than-expected-by-4-bytes.patch +revert-sunrpc-attempt-af_local-connect-on-setup.patch +firewire-fix-potential-uaf-in-outbound_phy_packet_callback.patch +firewire-remove-check-of-list-iterator-against-head-past-the-loop-body.patch +firewire-core-extend-card-lock-in-fw_core_handle_bus_reset.patch