From: Greg Kroah-Hartman Date: Thu, 28 May 2026 12:13:43 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v5.10.258~28 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=c6d6d4fec59b16f87347ea876ac0adf8a1844d54;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: batman-adv-bla-fix-report_work-leak-on-backbone_gw-purge.patch batman-adv-clear-current-gateway-during-teardown.patch batman-adv-dat-handle-forward-allocation-error.patch batman-adv-fix-fragment-reassembly-length-accounting.patch batman-adv-fix-tp_meter-counter-underflow-during-shutdown.patch batman-adv-frag-disallow-unicast-fragment-in-fragment.patch batman-adv-mcast-fix-use-after-free-in-orig_node-rcu-release.patch batman-adv-tp_meter-avoid-use-of-uninit-sender-vars.patch batman-adv-tt-fix-negative-last_changeset_len.patch batman-adv-tt-fix-negative-tt_buff_len.patch cifs-fix-busy-dentry-used-after-unmounting.patch device-property-set-fwnode-secondary-to-null-in-fwnode_init.patch drm-amd-display-fix-integer-overflow-in-bios_get_image.patch drm-amd-display-validate-gpio-pin-lut-table-size-before-iterating.patch drm-amd-display-validate-payload-length-and-link_index-in-dc_process_dmub_aux_transfer_async.patch drm-bridge-chipone-icn6211-use-devm_drm_bridge_add-in-i2c-probe.patch drm-bridge-it66121-acquire-reset-gpio-in-probe.patch drm-bridge-megachips-remove-bridge-when-irq-request-fails.patch drm-virtio-use-uninterruptible-resv-lock-for-plane-updates.patch hwmon-pmbus-adm1266-bounce-blackbox-records-through-a-protocol-sized-buffer.patch hwmon-pmbus-adm1266-cap-pdio-scan-in-get_multiple-at-adm1266_pdio_nr.patch hwmon-pmbus-adm1266-don-t-clobber-gpio-bits-before-pdio-read-in-get_multiple.patch hwmon-pmbus-adm1266-include-pec-byte-in-pmbus_block_xfer-read-buffer.patch hwmon-pmbus-adm1266-register-the-gpio_chip-after-pmbus_do_probe.patch hwmon-pmbus-adm1266-register-the-nvmem-device-after-pmbus_do_probe.patch hwmon-pmbus-adm1266-reject-implausible-blackbox-record_count.patch hwmon-pmbus-adm1266-reject-short-block-read-responses-in-the-gpio-accessors.patch hwmon-pmbus-adm1266-seed-timestamp-from-the-real-time-clock.patch hwmon-pmbus-adm1266-serialize-gpio-pmbus-accesses-with-pmbus_lock.patch hwmon-pmbus-adm1266-serialize-nvmem-blackbox-read-with-pmbus_lock.patch hwmon-pmbus-adm1266-serialize-sequencer_state-debugfs-read-with-pmbus_lock.patch kvm-arm64-vgic-its-reject-restored-dte-with-out-of-range-num_eventid_bits.patch loongarch-remove-unused-code-to-avoid-build-warning.patch rdma-siw-reject-mpa-fpdu-length-underflow-before-signed-receive-math.patch scsi-isci-fix-use-after-free-in-device-removal-path.patch spi-sprd-fix-error-pointer-deref-after-dma-setup-failure.patch spi-ti-qspi-fix-use-after-free-after-dma-setup-failure.patch tracing-do-not-call-map-ops-elt_free-if-elt_alloc-fails.patch --- diff --git a/queue-6.1/batman-adv-bla-fix-report_work-leak-on-backbone_gw-purge.patch b/queue-6.1/batman-adv-bla-fix-report_work-leak-on-backbone_gw-purge.patch new file mode 100644 index 0000000000..858c972a91 --- /dev/null +++ b/queue-6.1/batman-adv-bla-fix-report_work-leak-on-backbone_gw-purge.patch @@ -0,0 +1,115 @@ +From 0459430add32ea41f3e2ef9351610e6d33627a6b Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Sun, 10 May 2026 11:43:20 +0200 +Subject: batman-adv: bla: fix report_work leak on backbone_gw purge + +From: Sven Eckelmann + +commit 0459430add32ea41f3e2ef9351610e6d33627a6b upstream. + +batadv_bla_purge_backbone_gw() removes stale backbone gateway entries, +but fails to properly handle their associated report_work: + +- If report_work is running, the purge must wait for it to finish before + freeing the backbone_gw, otherwise the worker may access freed memory + (e.g. bat_priv). +- If report_work is pending, the purge must cancel it and release the + reference held for that pending work item. + +The previous implementation called hlist_for_each_entry_safe() inside a +spin_lock_bh() section, but cancel_work_sync() may sleep and therefore +cannot be called from within a spinlock-protected region. + +Restructure the loop to handle one entry per spinlock critical section: +acquire the lock, find the next entry to purge, remove it from the hash +list, then release the lock before calling cancel_work_sync() and +dropping the hash_entry reference. Repeat until no more entries require +purging. + +Cc: stable@kernel.org +Fixes: 23721387c409 ("batman-adv: add basic bridge loop avoidance code") +Reviewed-by: Simon Wunderlich +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/bridge_loop_avoidance.c | 60 ++++++++++++++++++++------------- + 1 file changed, 38 insertions(+), 22 deletions(-) + +--- a/net/batman-adv/bridge_loop_avoidance.c ++++ b/net/batman-adv/bridge_loop_avoidance.c +@@ -1224,6 +1224,7 @@ static void batadv_bla_purge_backbone_gw + struct hlist_head *head; + struct batadv_hashtable *hash; + spinlock_t *list_lock; /* protects write access to the hash lists */ ++ bool purged; + int i; + + hash = bat_priv->bla.backbone_hash; +@@ -1234,30 +1235,45 @@ static void batadv_bla_purge_backbone_gw + head = &hash->table[i]; + list_lock = &hash->list_locks[i]; + +- spin_lock_bh(list_lock); +- hlist_for_each_entry_safe(backbone_gw, node_tmp, +- head, hash_entry) { +- if (now) +- goto purge_now; +- if (!batadv_has_timed_out(backbone_gw->lasttime, +- BATADV_BLA_BACKBONE_TIMEOUT)) +- continue; +- +- batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, +- "%s(): backbone gw %pM timed out\n", +- __func__, backbone_gw->orig); ++ do { ++ purged = false; ++ ++ spin_lock_bh(list_lock); ++ hlist_for_each_entry_safe(backbone_gw, node_tmp, ++ head, hash_entry) { ++ if (now) ++ goto purge_now; ++ if (!batadv_has_timed_out(backbone_gw->lasttime, ++ BATADV_BLA_BACKBONE_TIMEOUT)) ++ continue; ++ ++ batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, ++ "%s(): backbone gw %pM timed out\n", ++ __func__, backbone_gw->orig); + + purge_now: +- /* don't wait for the pending request anymore */ +- if (atomic_read(&backbone_gw->request_sent)) +- atomic_dec(&bat_priv->bla.num_requests); +- +- batadv_bla_del_backbone_claims(backbone_gw); +- +- hlist_del_rcu(&backbone_gw->hash_entry); +- batadv_backbone_gw_put(backbone_gw); +- } +- spin_unlock_bh(list_lock); ++ purged = true; ++ ++ /* don't wait for the pending request anymore */ ++ if (atomic_read(&backbone_gw->request_sent)) ++ atomic_dec(&bat_priv->bla.num_requests); ++ ++ batadv_bla_del_backbone_claims(backbone_gw); ++ ++ hlist_del_rcu(&backbone_gw->hash_entry); ++ break; ++ } ++ spin_unlock_bh(list_lock); ++ ++ if (purged) { ++ /* reference for pending report_work */ ++ if (cancel_work_sync(&backbone_gw->report_work)) ++ batadv_backbone_gw_put(backbone_gw); ++ ++ /* reference for hash_entry */ ++ batadv_backbone_gw_put(backbone_gw); ++ } ++ } while (purged); + } + } + diff --git a/queue-6.1/batman-adv-clear-current-gateway-during-teardown.patch b/queue-6.1/batman-adv-clear-current-gateway-during-teardown.patch new file mode 100644 index 0000000000..793893105c --- /dev/null +++ b/queue-6.1/batman-adv-clear-current-gateway-during-teardown.patch @@ -0,0 +1,48 @@ +From a340a51ed801eab7bb454150c226323b865263cc Mon Sep 17 00:00:00 2001 +From: Ruijie Li +Date: Thu, 14 May 2026 16:13:25 +0800 +Subject: batman-adv: clear current gateway during teardown + +From: Ruijie Li + +commit a340a51ed801eab7bb454150c226323b865263cc upstream. + +batadv_gw_node_free() removes the gateway list entries during mesh teardown, +but it does not clear the currently selected gateway. This leaves stale +gateway state behind across cleanup and can break a later mesh recreation. + +Clear bat_priv->gw.curr_gw before walking the gateway list so the selected +gateway reference is dropped as part of teardown. + +Fixes: 2265c1410864 ("batman-adv: gateway election code refactoring") +Cc: stable@kernel.org +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Signed-off-by: Ruijie Li +Signed-off-by: Zhanpeng Li +Signed-off-by: Ren Wei +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/gateway_client.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/batman-adv/gateway_client.c ++++ b/net/batman-adv/gateway_client.c +@@ -479,10 +479,14 @@ void batadv_gw_node_delete(struct batadv + */ + void batadv_gw_node_free(struct batadv_priv *bat_priv) + { ++ struct batadv_gw_node *curr_gw; + struct batadv_gw_node *gw_node; + struct hlist_node *node_tmp; + + spin_lock_bh(&bat_priv->gw.list_lock); ++ curr_gw = rcu_replace_pointer(bat_priv->gw.curr_gw, NULL, true); ++ batadv_gw_node_put(curr_gw); ++ + hlist_for_each_entry_safe(gw_node, node_tmp, + &bat_priv->gw.gateway_list, list) { + hlist_del_init_rcu(&gw_node->list); diff --git a/queue-6.1/batman-adv-dat-handle-forward-allocation-error.patch b/queue-6.1/batman-adv-dat-handle-forward-allocation-error.patch new file mode 100644 index 0000000000..bf800b224e --- /dev/null +++ b/queue-6.1/batman-adv-dat-handle-forward-allocation-error.patch @@ -0,0 +1,42 @@ +From 2d8826a2d3657cea66fb0370f9e521575a673871 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Wed, 13 May 2026 09:01:34 +0200 +Subject: batman-adv: dat: handle forward allocation error + +From: Sven Eckelmann + +commit 2d8826a2d3657cea66fb0370f9e521575a673871 upstream. + +batadv_dat_forward_data() calls pskb_copy_for_clone() to duplicate an skb +for each DHT candidate, but does not check the return value before passing +it to batadv_send_skb_prepare_unicast_4addr(). That function dereferences +the skb unconditionally, so a failed allocation triggers a NULL pointer +dereference. + +Skip forwarding to the current DHT candidate on allocation failure. + +Cc: stable@kernel.org +Fixes: 785ea1144182 ("batman-adv: Distributed ARP Table - create DHT helper functions") +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Reviewed-by: Yuan Tan +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/distributed-arp-table.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/batman-adv/distributed-arp-table.c ++++ b/net/batman-adv/distributed-arp-table.c +@@ -698,6 +698,9 @@ static bool batadv_dat_forward_data(stru + goto free_orig; + + tmp_skb = pskb_copy_for_clone(skb, GFP_ATOMIC); ++ if (!tmp_skb) ++ goto free_neigh; ++ + if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb, + cand[i].orig_node, + packet_subtype)) { diff --git a/queue-6.1/batman-adv-fix-fragment-reassembly-length-accounting.patch b/queue-6.1/batman-adv-fix-fragment-reassembly-length-accounting.patch new file mode 100644 index 0000000000..eec6da300d --- /dev/null +++ b/queue-6.1/batman-adv-fix-fragment-reassembly-length-accounting.patch @@ -0,0 +1,132 @@ +From 9cd3f16c320bfdadd4509358122368deb56a5741 Mon Sep 17 00:00:00 2001 +From: Ruide Cao +Date: Wed, 13 May 2026 11:58:15 +0800 +Subject: batman-adv: fix fragment reassembly length accounting + +From: Ruide Cao + +commit 9cd3f16c320bfdadd4509358122368deb56a5741 upstream. + +batman-adv keeps a running payload length for queued fragments and uses it +to validate a fragment chain before reassembly. + +That accounting currently allows the accumulated fragment length to be +truncated during updates. As a result, malformed fragment chains can +bypass the intended validation and drive reassembly with inconsistent +length state, leading to a local denial of service. + +Fix the accounting by storing the accumulated length in a length-typed +field and rejecting update overflows before the existing validation logic +runs. + +The fix was verified against the original reproducer and against valid +fragment reassembly paths. + +Fixes: 610bfc6bc99b ("batman-adv: Receive fragmented packets and merge") +Cc: stable@kernel.org +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Signed-off-by: Ruide Cao +Tested-by: Ren Wei +Signed-off-by: Ren Wei +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/fragmentation.c | 23 +++++++++++++++++------ + net/batman-adv/types.h | 2 +- + 2 files changed, 18 insertions(+), 7 deletions(-) + +--- a/net/batman-adv/fragmentation.c ++++ b/net/batman-adv/fragmentation.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -81,9 +82,9 @@ void batadv_frag_purge_orig(struct batad + * + * Return: the maximum size of payload that can be fragmented. + */ +-static int batadv_frag_size_limit(void) ++static size_t batadv_frag_size_limit(void) + { +- int limit = BATADV_FRAG_MAX_FRAG_SIZE; ++ size_t limit = BATADV_FRAG_MAX_FRAG_SIZE; + + limit -= sizeof(struct batadv_frag_packet); + limit *= BATADV_FRAG_MAX_FRAGMENTS; +@@ -144,7 +145,9 @@ static bool batadv_frag_insert_packet(st + struct batadv_frag_packet *frag_packet; + u8 bucket; + u16 seqno, hdr_size = sizeof(struct batadv_frag_packet); ++ bool overflow = false; + bool ret = false; ++ size_t data_len; + + /* Linearize packet to avoid linearizing 16 packets in a row when doing + * the later merge. Non-linear merge should be added to remove this +@@ -154,6 +157,7 @@ static bool batadv_frag_insert_packet(st + goto err; + + frag_packet = (struct batadv_frag_packet *)skb->data; ++ data_len = skb->len - hdr_size; + seqno = ntohs(frag_packet->seqno); + bucket = seqno % BATADV_FRAG_BUFFER_COUNT; + +@@ -172,7 +176,7 @@ static bool batadv_frag_insert_packet(st + spin_lock_bh(&chain->lock); + if (batadv_frag_init_chain(chain, seqno)) { + hlist_add_head(&frag_entry_new->list, &chain->fragment_list); +- chain->size = skb->len - hdr_size; ++ chain->size = data_len; + chain->timestamp = jiffies; + chain->total_size = ntohs(frag_packet->total_size); + ret = true; +@@ -189,7 +193,11 @@ static bool batadv_frag_insert_packet(st + if (frag_entry_curr->no < frag_entry_new->no) { + hlist_add_before(&frag_entry_new->list, + &frag_entry_curr->list); +- chain->size += skb->len - hdr_size; ++ ++ if (check_add_overflow(chain->size, data_len, ++ &chain->size)) ++ overflow = true; ++ + chain->timestamp = jiffies; + ret = true; + goto out; +@@ -202,13 +210,16 @@ static bool batadv_frag_insert_packet(st + /* Reached the end of the list, so insert after 'frag_entry_last'. */ + if (likely(frag_entry_last)) { + hlist_add_behind(&frag_entry_new->list, &frag_entry_last->list); +- chain->size += skb->len - hdr_size; ++ ++ if (check_add_overflow(chain->size, data_len, &chain->size)) ++ overflow = true; ++ + chain->timestamp = jiffies; + ret = true; + } + + out: +- if (chain->size > batadv_frag_size_limit() || ++ if (overflow || chain->size > batadv_frag_size_limit() || + chain->total_size != ntohs(frag_packet->total_size) || + chain->total_size > batadv_frag_size_limit()) { + /* Clear chain if total size of either the list or the packet +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -294,7 +294,7 @@ struct batadv_frag_table_entry { + u16 seqno; + + /** @size: accumulated size of packets in list */ +- u16 size; ++ size_t size; + + /** @total_size: expected size of the assembled packet */ + u16 total_size; diff --git a/queue-6.1/batman-adv-fix-tp_meter-counter-underflow-during-shutdown.patch b/queue-6.1/batman-adv-fix-tp_meter-counter-underflow-during-shutdown.patch new file mode 100644 index 0000000000..68139c9396 --- /dev/null +++ b/queue-6.1/batman-adv-fix-tp_meter-counter-underflow-during-shutdown.patch @@ -0,0 +1,56 @@ +From 94f3b133168d1c49895e7cc6afbcf1cc0b354602 Mon Sep 17 00:00:00 2001 +From: Luxiao Xu +Date: Mon, 11 May 2026 18:52:09 +0200 +Subject: batman-adv: fix tp_meter counter underflow during shutdown + +From: Luxiao Xu + +commit 94f3b133168d1c49895e7cc6afbcf1cc0b354602 upstream. + +batadv_tp_sender_shutdown() unconditionally decrements the "sending" +atomic counter. If multiple paths (e.g. timeout, user cancel, and +normal finish) call this function, the counter can underflow to -1. + +Since the sender logic treats any non-zero value as "still sending", +a negative value causes the sender kthread to loop indefinitely. +This leads to a use-after-free when the interface is removed while +the zombie thread is still active. + +Fix this by using atomic_xchg() to ensure the counter only transitions +from 1 to 0 once. + +Fixes: 33a3bb4a3345 ("batman-adv: throughput meter implementation") +Cc: stable@kernel.org +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Signed-off-by: Luxiao Xu +Signed-off-by: Ren Wei +[sven: added missing change in batadv_tp_send] +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/tp_meter.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/batman-adv/tp_meter.c ++++ b/net/batman-adv/tp_meter.c +@@ -435,7 +435,7 @@ static void batadv_tp_sender_end(struct + static void batadv_tp_sender_shutdown(struct batadv_tp_vars *tp_vars, + enum batadv_tp_meter_reason reason) + { +- if (!atomic_dec_and_test(&tp_vars->sending)) ++ if (atomic_xchg(&tp_vars->sending, 0) != 1) + return; + + tp_vars->reason = reason; +@@ -869,7 +869,7 @@ static int batadv_tp_send(void *arg) + "Meter: %s() cannot send packets (%d)\n", + __func__, err); + /* ensure nobody else tries to stop the thread now */ +- if (atomic_dec_and_test(&tp_vars->sending)) ++ if (atomic_xchg(&tp_vars->sending, 0) == 1) + tp_vars->reason = err; + break; + } diff --git a/queue-6.1/batman-adv-frag-disallow-unicast-fragment-in-fragment.patch b/queue-6.1/batman-adv-frag-disallow-unicast-fragment-in-fragment.patch new file mode 100644 index 0000000000..ad4c97c961 --- /dev/null +++ b/queue-6.1/batman-adv-frag-disallow-unicast-fragment-in-fragment.patch @@ -0,0 +1,87 @@ +From bc62216dc8e221e3781afa14430f45208bfa9af9 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Wed, 13 May 2026 09:01:36 +0200 +Subject: batman-adv: frag: disallow unicast fragment in fragment + +From: Sven Eckelmann + +commit bc62216dc8e221e3781afa14430f45208bfa9af9 upstream. + +batadv_frag_skb_buffer() is called by batadv_batman_skb_recv() when a +BATADV_UNICAST_FRAG packet is received. Once all fragments are collected +and the packet is reassembled, batadv_recv_frag_packet() calls +batadv_batman_skb_recv() again to process the defragmented payload. + +A malicious sender can craft a BATADV_UNICAST_FRAG packet whose reassembled +payload is itself a BATADV_UNICAST_FRAG packet (matryoshka-style nesting). +Each nesting level recurses through batadv_batman_skb_recv() without bound, +growing the kernel stack until it is exhausted. + +Since refragmentation or fragments in fragments are not actually allowed, +discard all packets which are still BATADV_UNICAST_FRAG packets after the +defragmentation process. + +Cc: stable@kernel.org +Fixes: 610bfc6bc99b ("batman-adv: Receive fragmented packets and merge") +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Reviewed-by: Yuan Tan +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/fragmentation.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +--- a/net/batman-adv/fragmentation.c ++++ b/net/batman-adv/fragmentation.c +@@ -306,6 +306,31 @@ free: + } + + /** ++ * batadv_skb_is_frag() - check if newly merged skb is gain a unicast packet ++ * @skb: newly merged skb ++ * ++ * Return: if newly skb is of type BATADV_UNICAST_FRAG ++ */ ++static bool batadv_skb_is_frag(struct sk_buff *skb) ++{ ++ struct batadv_ogm_packet *batadv_ogm_packet; ++ ++ /* packet should hold at least type and version */ ++ if (unlikely(!pskb_may_pull(skb, 2))) ++ return false; ++ ++ batadv_ogm_packet = (struct batadv_ogm_packet *)skb->data; ++ ++ if (batadv_ogm_packet->version != BATADV_COMPAT_VERSION) ++ return false; ++ ++ if (batadv_ogm_packet->packet_type != BATADV_UNICAST_FRAG) ++ return false; ++ ++ return true; ++} ++ ++/** + * batadv_frag_skb_buffer() - buffer fragment for later merge + * @skb: skb to buffer + * @orig_node_src: originator that the skb is received from +@@ -338,6 +363,16 @@ bool batadv_frag_skb_buffer(struct sk_bu + if (!skb_out) + goto out_err; + ++ /* fragment in fragment is not allowed. otherwise it is possible ++ * to exhaust the stack when receiving a matryoshka-style ++ * "fragments in a fragment packet" ++ */ ++ if (batadv_skb_is_frag(skb_out)) { ++ kfree_skb(skb_out); ++ skb_out = NULL; ++ goto out_err; ++ } ++ + out: + ret = true; + out_err: diff --git a/queue-6.1/batman-adv-mcast-fix-use-after-free-in-orig_node-rcu-release.patch b/queue-6.1/batman-adv-mcast-fix-use-after-free-in-orig_node-rcu-release.patch new file mode 100644 index 0000000000..199d8e9b51 --- /dev/null +++ b/queue-6.1/batman-adv-mcast-fix-use-after-free-in-orig_node-rcu-release.patch @@ -0,0 +1,51 @@ +From 20c2d6a20ca936f5aaa6dd40f73f262ac45c87cc Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Thu, 14 May 2026 19:22:02 +0200 +Subject: batman-adv: mcast: fix use-after-free in orig_node RCU release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Sven Eckelmann + +commit 20c2d6a20ca936f5aaa6dd40f73f262ac45c87cc upstream. + +batadv_mcast_purge_orig() removes entries from RCU-protected hlists but +does not wait for an RCU grace period before returning. Concurrent RCU +readers may still accesses references to those entries at the point of +removal. RCU-protected readers trying to operate on entries like +orig->mcast_want_all_ipv6_node will then access already freed memory. + +Fix this by moving batadv_mcast_purge_orig() to batadv_orig_node_release(), +just before the call_rcu() invocation. This ensures RCU readers that were +active at purge time have drained before the orig_node memory is reclaimed. + +Cc: stable@kernel.org +Fixes: ab49886e3da7 ("batman-adv: Add IPv4 link-local/IPv6-ll-all-nodes multicast support") +Acked-by: Linus Lüssing +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/originator.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/batman-adv/originator.c ++++ b/net/batman-adv/originator.c +@@ -823,8 +823,6 @@ static void batadv_orig_node_free_rcu(st + + orig_node = container_of(rcu, struct batadv_orig_node, rcu); + +- batadv_mcast_purge_orig(orig_node); +- + batadv_frag_purge_orig(orig_node, NULL); + + kfree(orig_node->tt_buff); +@@ -878,6 +876,8 @@ void batadv_orig_node_release(struct kre + /* Free nc_nodes */ + batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL); + ++ batadv_mcast_purge_orig(orig_node); ++ + call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu); + } + diff --git a/queue-6.1/batman-adv-tp_meter-avoid-use-of-uninit-sender-vars.patch b/queue-6.1/batman-adv-tp_meter-avoid-use-of-uninit-sender-vars.patch new file mode 100644 index 0000000000..5faba171cc --- /dev/null +++ b/queue-6.1/batman-adv-tp_meter-avoid-use-of-uninit-sender-vars.patch @@ -0,0 +1,65 @@ +From 6c65cf23d4c6170fcf5714c32aa64689718cb142 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Wed, 13 May 2026 09:01:35 +0200 +Subject: batman-adv: tp_meter: avoid use of uninit sender vars + +From: Sven Eckelmann + +commit 6c65cf23d4c6170fcf5714c32aa64689718cb142 upstream. + +batadv_tp_recv_ack() and batadv_tp_stop() are only valid for tp_vars in the +BATADV_TP_SENDER role. When called with a BATADV_TP_RECEIVER role, it +proceeds to read sender-only members that were never initialized, leading +to undefined behavior. + +This can be triggered when a node that is currently acting as a receiver in +an ongoing tp_meter session receives a malicious ACK packet. + +Guard against this by checking tp_vars->role immediately after the +lookup and bailing out if it is not BATADV_TP_SENDER, before any of +those members are accessed. + +Cc: stable@kernel.org +Fixes: 33a3bb4a3345 ("batman-adv: throughput meter implementation") +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Reviewed-by: Yuan Tan +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/tp_meter.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/net/batman-adv/tp_meter.c ++++ b/net/batman-adv/tp_meter.c +@@ -647,6 +647,9 @@ static void batadv_tp_recv_ack(struct ba + if (unlikely(!tp_vars)) + return; + ++ if (unlikely(tp_vars->role != BATADV_TP_SENDER)) ++ goto out; ++ + if (unlikely(atomic_read(&tp_vars->sending) == 0)) + goto out; + +@@ -1080,12 +1083,16 @@ void batadv_tp_stop(struct batadv_priv * + if (!tp_vars) { + batadv_dbg(BATADV_DBG_TP_METER, bat_priv, + "Meter: trying to interrupt an already over connection\n"); +- goto out; ++ goto out_put_orig_node; + } + ++ if (unlikely(tp_vars->role != BATADV_TP_SENDER)) ++ goto out_put_tp_vars; ++ + batadv_tp_sender_shutdown(tp_vars, return_value); ++out_put_tp_vars: + batadv_tp_vars_put(tp_vars); +-out: ++out_put_orig_node: + batadv_orig_node_put(orig_node); + } + diff --git a/queue-6.1/batman-adv-tt-fix-negative-last_changeset_len.patch b/queue-6.1/batman-adv-tt-fix-negative-last_changeset_len.patch new file mode 100644 index 0000000000..84c214021a --- /dev/null +++ b/queue-6.1/batman-adv-tt-fix-negative-last_changeset_len.patch @@ -0,0 +1,41 @@ +From fc92cdfcb295cefa4344d71a527d61b638b7bfc4 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Sat, 2 May 2026 19:53:21 +0200 +Subject: batman-adv: tt: fix negative last_changeset_len + +From: Sven Eckelmann + +commit fc92cdfcb295cefa4344d71a527d61b638b7bfc4 upstream. + +batadv_piv_tt::last_changeset_len len was declared as s16, but the field is +never intended to hold a negative value. When a value greater than 32767 is +assigned, it wraps to a negative signed integer. + +In batadv_send_my_tt_response(), last_changeset_len is temporarily widened +to s32. The incorrectly negative s16 value propagates into the s32, causing +batadv_tt_prepare_tvlv_local_data() to allocate a full sized buffer but +populates only a small portion of it with the collected changeset. All +remaining bits are kept uninitialized. + +Using an u16 avoids this type confusion and ensures that no (negative) sign +extension is performed in batadv_send_my_tt_response(). + +Cc: stable@kernel.org +Fixes: a73105b8d4c7 ("batman-adv: improved client announcement mechanism") +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/types.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -993,7 +993,7 @@ struct batadv_priv_tt { + * @last_changeset_len: length of last tt changeset this host has + * generated + */ +- s16 last_changeset_len; ++ u16 last_changeset_len; + + /** + * @last_changeset_lock: lock protecting last_changeset & diff --git a/queue-6.1/batman-adv-tt-fix-negative-tt_buff_len.patch b/queue-6.1/batman-adv-tt-fix-negative-tt_buff_len.patch new file mode 100644 index 0000000000..0599d28846 --- /dev/null +++ b/queue-6.1/batman-adv-tt-fix-negative-tt_buff_len.patch @@ -0,0 +1,41 @@ +From b64963a2ceeb7529310b6cf253a1e540784422f4 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Sat, 2 May 2026 19:53:21 +0200 +Subject: batman-adv: tt: fix negative tt_buff_len + +From: Sven Eckelmann + +commit b64963a2ceeb7529310b6cf253a1e540784422f4 upstream. + +batadv_orig_node::tt_buff_len was declared as s16, but the field is never +intended to hold a negative value. When a value greater than 32767 is +assigned, it wraps to a negative signed integer. + +In batadv_send_other_tt_response(), tt_buff_len is temporarily widened to +s32. The incorrectly negative s16 value propagates into the s32, causing +batadv_tt_prepare_tvlv_global_data() to allocate a full sized buffer but +populates only a small portion of it with the collected changeset. All +remaining bits are kept uninitialized. + +Using an u16 avoids this type confusion and ensures that no (negative) sign +extension is performed in batadv_send_other_tt_response(). + +Cc: stable@kernel.org +Fixes: a73105b8d4c7 ("batman-adv: improved client announcement mechanism") +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/types.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -445,7 +445,7 @@ struct batadv_orig_node { + * @tt_buff_len: length of the last tt changeset this node received + * from the orig node + */ +- s16 tt_buff_len; ++ u16 tt_buff_len; + + /** @tt_buff_lock: lock that protects tt_buff and tt_buff_len */ + spinlock_t tt_buff_lock; diff --git a/queue-6.1/cifs-fix-busy-dentry-used-after-unmounting.patch b/queue-6.1/cifs-fix-busy-dentry-used-after-unmounting.patch new file mode 100644 index 0000000000..7383a460c0 --- /dev/null +++ b/queue-6.1/cifs-fix-busy-dentry-used-after-unmounting.patch @@ -0,0 +1,73 @@ +From c68337442f03953237a94577beb468ab2662a851 Mon Sep 17 00:00:00 2001 +From: Zhihao Cheng +Date: Tue, 19 May 2026 17:18:05 +0800 +Subject: cifs: Fix busy dentry used after unmounting + +From: Zhihao Cheng + +commit c68337442f03953237a94577beb468ab2662a851 upstream. + +Since commit 340cea84f691c ("cifs: open files should not hold ref on +superblock"), cifs file only holds the dentry ref_cnt, the cifs file +close work(cfile->deferred) could be executed after unmounting, which +will trigger a warning in generic_shutdown_super: + BUG: Dentry 00000000a14a6845{i=c,n=file} still in use (1) [unmount of + cifs cifs] + +The detailed processs is: + process A process B kworker + fd = open(PATH) + vfs_open + file->__f_path = *path // dentry->d_lockref.count = 1 + cifs_open + cifs_new_fileinfo + cfile->dentry = dget(dentry) // dentry->d_lockref.count = 2 + close(fd) + __fput + cifs_close + queue_delayed_work(deferredclose_wq, cfile->deferred) + dput(dentry) // dentry->d_lockref.count = 1 + smb2_deferred_work_close + _cifsFileInfo_put + list_del(&cifs_file->flist) + umount + cleanup_mnt + deactivate_super + cifs_kill_sb + cifs_close_all_deferred_files_sb + cifs_close_all_deferred_files + // cannot find cfile, skip _cifsFileInfo_put + kill_anon_super + generic_shutdown_super + shrink_dcache_for_umount + umount_check + WARN ! // dentry->d_lockref.count = 1 + cifsFileInfo_put_final + dput(cifs_file->dentry) + // dentry->d_lockref.count = 0 + +Fix it by flushing 'deferredclose_wq' before calling kill_anon_super. + +Fetch a reproducer in https://bugzilla.kernel.org/show_bug.cgi?id=221548. + +Fixes: 340cea84f691c ("cifs: open files should not hold ref on superblock") +Cc: stable@vger.kernel.org +Reviewed-by: Shyam Prasad N +Signed-off-by: Zhihao Cheng +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/cifsfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -296,6 +296,8 @@ static void cifs_kill_sb(struct super_bl + + /* Wait for all pending oplock breaks to complete */ + flush_workqueue(cifsoplockd_wq); ++ /* Wait for all opened files to release */ ++ flush_workqueue(deferredclose_wq); + + /* finally release root dentry */ + dput(cifs_sb->root); diff --git a/queue-6.1/device-property-set-fwnode-secondary-to-null-in-fwnode_init.patch b/queue-6.1/device-property-set-fwnode-secondary-to-null-in-fwnode_init.patch new file mode 100644 index 0000000000..cc039b92af --- /dev/null +++ b/queue-6.1/device-property-set-fwnode-secondary-to-null-in-fwnode_init.patch @@ -0,0 +1,40 @@ +From 215c90ee656114f5e8c32408228d97082f8e0eef Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski +Date: Wed, 6 May 2026 13:57:00 +0200 +Subject: device property: set fwnode->secondary to NULL in fwnode_init() + +From: Bartosz Golaszewski + +commit 215c90ee656114f5e8c32408228d97082f8e0eef upstream. + +If a firmware node is allocated on the stack (for instance: temporary +software node whose life-time we control) or on the heap - but using a +non-zeroing allocation function - and initialized using fwnode_init(), +its secondary pointer will contain uninitalized memory which likely will +be neither NULL nor IS_ERR() and so may end up being dereferenced (for +example: in dev_to_swnode()). Set fwnode->secondary to NULL on +initialization. + +Cc: stable +Fixes: 01bb86b380a3 ("driver core: Add fwnode_init()") +Signed-off-by: Bartosz Golaszewski +Reviewed-by: Rafael J. Wysocki (Intel) +Reviewed-by: Andy Shevchenko +Reviewed-by: Sakari Ailus +Link: https://patch.msgid.link/20260506115701.23035-1-bartosz.golaszewski@oss.qualcomm.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/fwnode.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/include/linux/fwnode.h ++++ b/include/linux/fwnode.h +@@ -193,6 +193,7 @@ struct fwnode_operations { + static inline void fwnode_init(struct fwnode_handle *fwnode, + const struct fwnode_operations *ops) + { ++ fwnode->secondary = NULL; + fwnode->ops = ops; + INIT_LIST_HEAD(&fwnode->consumers); + INIT_LIST_HEAD(&fwnode->suppliers); diff --git a/queue-6.1/drm-amd-display-fix-integer-overflow-in-bios_get_image.patch b/queue-6.1/drm-amd-display-fix-integer-overflow-in-bios_get_image.patch new file mode 100644 index 0000000000..a664689894 --- /dev/null +++ b/queue-6.1/drm-amd-display-fix-integer-overflow-in-bios_get_image.patch @@ -0,0 +1,56 @@ +From cd86529ec61474a38c3837fb7823790a7c3f8cce Mon Sep 17 00:00:00 2001 +From: Harry Wentland +Date: Mon, 4 May 2026 11:14:45 -0400 +Subject: drm/amd/display: Fix integer overflow in bios_get_image() + +From: Harry Wentland + +commit cd86529ec61474a38c3837fb7823790a7c3f8cce upstream. + +[Why&How] +The bounds check in bios_get_image() computes 'offset + size' using +unsigned 32-bit arithmetic before comparing against bios_size. If a +VBIOS image contains a near-UINT32_MAX offset the addition wraps to a +small value, the comparison passes, and the function returns a wild +pointer past the VBIOS mapping. + +Additionally, the comparison uses '<' (strict), which incorrectly +rejects the valid exact-fit case where offset + size == bios_size. + +Fix both issues by restructuring the check to avoid the addition +entirely: first reject if offset alone exceeds bios_size, then check +size against the remaining space (bios_size - offset). This eliminates +the overflow and correctly permits exact-fit accesses. + +Assisted-by: GitHub Copilot:claude-opus-4.6 +Reviewed-by: Alex Hung +Signed-off-by: Harry Wentland +Signed-off-by: Ivan Lipski +Tested-by: Dan Wheeler +Signed-off-by: Alex Deucher +(cherry picked from commit d40fb392af659c4a02b560319f226842f6ec1a95) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c +@@ -37,10 +37,13 @@ uint8_t *bios_get_image(struct dc_bios * + uint32_t offset, + uint32_t size) + { +- if (bp->bios && offset + size < bp->bios_size) +- return bp->bios + offset; +- else ++ if (!bp->bios) + return NULL; ++ ++ if (offset > bp->bios_size || size > bp->bios_size - offset) ++ return NULL; ++ ++ return bp->bios + offset; + } + + #include "reg_helper.h" diff --git a/queue-6.1/drm-amd-display-validate-gpio-pin-lut-table-size-before-iterating.patch b/queue-6.1/drm-amd-display-validate-gpio-pin-lut-table-size-before-iterating.patch new file mode 100644 index 0000000000..ae6f812a71 --- /dev/null +++ b/queue-6.1/drm-amd-display-validate-gpio-pin-lut-table-size-before-iterating.patch @@ -0,0 +1,60 @@ +From 86d2b20644b11d21fe52c596e6e922b4590a3e3f Mon Sep 17 00:00:00 2001 +From: Harry Wentland +Date: Mon, 4 May 2026 16:14:11 -0400 +Subject: drm/amd/display: Validate GPIO pin LUT table size before iterating + +From: Harry Wentland + +commit 86d2b20644b11d21fe52c596e6e922b4590a3e3f upstream. + +[Why&How] +The GPIO pin table parsers in get_gpio_i2c_info() and +bios_parser_get_gpio_pin_info() derive an element count from the VBIOS +table_header.structuresize field, then iterate over gpio_pin[] entries. +However, GET_IMAGE() only validates that the table header itself fits +within the BIOS image. If the VBIOS reports a structuresize larger than +the actual mapped data, the loop reads past the end of the BIOS image, +causing an out-of-bounds read. + +Fix this by calling bios_get_image() to validate that the full claimed +structuresize is accessible within the BIOS image before entering the +loop in both functions. + +Assisted-by: GitHub Copilot:claude-opus-4-6 +Reviewed-by: Alex Hung +Signed-off-by: Harry Wentland +Signed-off-by: Ivan Lipski +Tested-by: Dan Wheeler +Signed-off-by: Alex Deucher +(cherry picked from commit ba5e95b43b773ae1bf1f66ee6b31eb774e65afe3) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -490,6 +490,10 @@ static enum bp_result get_gpio_i2c_info( + - sizeof(struct atom_common_table_header)) + / sizeof(struct atom_gpio_pin_assignment); + ++ if (!bios_get_image(&bp->base, DATA_TABLES(gpio_pin_lut), ++ le16_to_cpu(header->table_header.structuresize))) ++ return BP_RESULT_BADBIOSTABLE; ++ + pin = (struct atom_gpio_pin_assignment *) header->gpio_pin; + + for (table_index = 0; table_index < count; table_index++) { +@@ -680,6 +684,11 @@ static enum bp_result bios_parser_get_gp + count = (le16_to_cpu(header->table_header.structuresize) + - sizeof(struct atom_common_table_header)) + / sizeof(struct atom_gpio_pin_assignment); ++ ++ if (!bios_get_image(&bp->base, DATA_TABLES(gpio_pin_lut), ++ le16_to_cpu(header->table_header.structuresize))) ++ return BP_RESULT_BADBIOSTABLE; ++ + for (i = 0; i < count; ++i) { + if (header->gpio_pin[i].gpio_id != gpio_id) + continue; diff --git a/queue-6.1/drm-amd-display-validate-payload-length-and-link_index-in-dc_process_dmub_aux_transfer_async.patch b/queue-6.1/drm-amd-display-validate-payload-length-and-link_index-in-dc_process_dmub_aux_transfer_async.patch new file mode 100644 index 0000000000..0b863e07e8 --- /dev/null +++ b/queue-6.1/drm-amd-display-validate-payload-length-and-link_index-in-dc_process_dmub_aux_transfer_async.patch @@ -0,0 +1,50 @@ +From 6c92f6d9600efa3ef0d9e560a2b52776d9803c29 Mon Sep 17 00:00:00 2001 +From: Harry Wentland +Date: Thu, 7 May 2026 16:26:31 -0400 +Subject: drm/amd/display: Validate payload length and link_index in dc_process_dmub_aux_transfer_async + +From: Harry Wentland + +commit 6c92f6d9600efa3ef0d9e560a2b52776d9803c29 upstream. + +[Why&How] +dc_process_dmub_aux_transfer_async() copies payload->length bytes into a +16-byte stack buffer (dpaux.data[16]) guarded only by an ASSERT(), which +is a no-op in release builds. If a caller ever passes length > 16 this +results in a stack buffer overflow via memcpy. + +Additionally, link_index is used to dereference dc->links[] without +bounds checking against dc->link_count, risking an out-of-bounds access. + +Replace the ASSERT with a hard runtime check that returns false when +payload->length exceeds the destination buffer size, and add a bounds +check for link_index before it is used. + +Assisted-by: GitHub Copilot:Claude claude-4-opus +Reviewed-by: Alex Hung +Signed-off-by: Harry Wentland +Signed-off-by: Ivan Lipski +Tested-by: Dan Wheeler +Signed-off-by: Alex Deucher +(cherry picked from commit ba4caa9fecdf7a38f98c878ad05a8a64148b6881) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -4737,7 +4737,11 @@ bool dc_process_dmub_aux_transfer_async( + union dmub_rb_cmd cmd = {0}; + struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; + +- ASSERT(payload->length <= 16); ++ if (link_index >= dc->link_count || !dc->links[link_index]) ++ return false; ++ ++ if (payload->length > sizeof(cmd.dp_aux_access.aux_control.dpaux.data)) ++ return false; + + cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS; + cmd.dp_aux_access.header.payload_bytes = 0; diff --git a/queue-6.1/drm-bridge-chipone-icn6211-use-devm_drm_bridge_add-in-i2c-probe.patch b/queue-6.1/drm-bridge-chipone-icn6211-use-devm_drm_bridge_add-in-i2c-probe.patch new file mode 100644 index 0000000000..a77f370daa --- /dev/null +++ b/queue-6.1/drm-bridge-chipone-icn6211-use-devm_drm_bridge_add-in-i2c-probe.patch @@ -0,0 +1,36 @@ +From 73d01051e8040c0b1de7fd26b3b8d0c2ffa6895c Mon Sep 17 00:00:00 2001 +From: Osama Abdelkader +Date: Thu, 30 Apr 2026 21:49:42 +0200 +Subject: drm/bridge: chipone-icn6211: use devm_drm_bridge_add in i2c probe + +From: Osama Abdelkader + +commit 73d01051e8040c0b1de7fd26b3b8d0c2ffa6895c upstream. + +Use devm_drm_bridge_add() so the bridge is released if probe +fails after registration, and drop drm_bridge_remove() in chipone_i2c_probe. + +Signed-off-by: Osama Abdelkader +Fixes: 8dde6f7452a1 ("drm: bridge: icn6211: Add I2C configuration support") +Cc: stable@vger.kernel.org +Reviewed-by: Luca Ceresoli +Link: https://patch.msgid.link/20260430194944.78119-1-osama.abdelkader@gmail.com +Signed-off-by: Luca Ceresoli +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/bridge/chipone-icn6211.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/bridge/chipone-icn6211.c ++++ b/drivers/gpu/drm/bridge/chipone-icn6211.c +@@ -758,7 +758,9 @@ static int chipone_i2c_probe(struct i2c_ + dev_set_drvdata(dev, icn); + i2c_set_clientdata(client, icn); + +- drm_bridge_add(&icn->bridge); ++ ret = devm_drm_bridge_add(dev, &icn->bridge); ++ if (ret) ++ return ret; + + return chipone_dsi_host_attach(icn); + } diff --git a/queue-6.1/drm-bridge-it66121-acquire-reset-gpio-in-probe.patch b/queue-6.1/drm-bridge-it66121-acquire-reset-gpio-in-probe.patch new file mode 100644 index 0000000000..b51c84a793 --- /dev/null +++ b/queue-6.1/drm-bridge-it66121-acquire-reset-gpio-in-probe.patch @@ -0,0 +1,50 @@ +From e02b5262fd288cc235f14e12233ea54e78c04611 Mon Sep 17 00:00:00 2001 +From: Julien Chauveau +Date: Tue, 24 Mar 2026 20:30:11 +0100 +Subject: drm/bridge: it66121: acquire reset GPIO in probe + +From: Julien Chauveau + +commit e02b5262fd288cc235f14e12233ea54e78c04611 upstream. + +The it66121_ctx structure has a gpio_reset field, and it66121_hw_reset() +calls gpiod_set_value() on it. However, the GPIO descriptor is never +acquired via devm_gpiod_get(), leaving gpio_reset as NULL throughout +the driver lifetime. + +gpiod_set_value() silently returns when passed a NULL descriptor, so +the hardware reset sequence in it66121_hw_reset() is a no-op. This +leaves the chip in an undefined state at probe time, which can prevent +it from responding on the I2C bus. + +The DT binding marks reset-gpios as a required property, so all +compliant device trees provide this GPIO. Add the missing +devm_gpiod_get() call after enabling power supplies and before the +hardware reset, so the chip is properly reset with power applied. + +Fixes: 988156dc2fc9 ("drm: bridge: add it66121 driver") +Cc: stable@vger.kernel.org +Signed-off-by: Julien Chauveau +Reviewed-by: Javier Martinez Canillas +Tested-by: Javier Martinez Canillas +Link: https://patch.msgid.link/20260324193011.16583-1-chauveau.julien@gmail.com +Signed-off-by: Javier Martinez Canillas +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/bridge/ite-it66121.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -1582,6 +1582,11 @@ static int it66121_probe(struct i2c_clie + if (ret) + return ret; + ++ ctx->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); ++ if (IS_ERR(ctx->gpio_reset)) ++ return dev_err_probe(dev, PTR_ERR(ctx->gpio_reset), ++ "Failed to get reset GPIO\n"); ++ + it66121_hw_reset(ctx); + + ctx->regmap = devm_regmap_init_i2c(client, &it66121_regmap_config); diff --git a/queue-6.1/drm-bridge-megachips-remove-bridge-when-irq-request-fails.patch b/queue-6.1/drm-bridge-megachips-remove-bridge-when-irq-request-fails.patch new file mode 100644 index 0000000000..6666659e73 --- /dev/null +++ b/queue-6.1/drm-bridge-megachips-remove-bridge-when-irq-request-fails.patch @@ -0,0 +1,68 @@ +From d45d5c819f2cd0b6b5d76a194a537a5f4aeefecb Mon Sep 17 00:00:00 2001 +From: Osama Abdelkader +Date: Thu, 30 Apr 2026 21:56:59 +0200 +Subject: drm/bridge: megachips: remove bridge when irq request fails + +From: Osama Abdelkader + +commit d45d5c819f2cd0b6b5d76a194a537a5f4aeefecb upstream. + +If devm_request_threaded_irq() fails after drm_bridge_add(), remove the +bridge before returning. + +Keep drm_bridge_add() rather than devm_drm_bridge_add(): registration is +tied to the STDP4028 device while ge_b850v3_register() may complete from +either I2C probe; devm would not unwind the bridge if the other client's +probe fails. + +Signed-off-by: Osama Abdelkader +Fixes: fcfa0ddc18ed ("drm/bridge: Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)") +Cc: stable@vger.kernel.org +Reviewed-by: Luca Ceresoli +Tested-by: Ian Ray +Link: https://patch.msgid.link/20260430195700.80317-1-osama.abdelkader@gmail.com +Signed-off-by: Luca Ceresoli +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 16 +++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c ++++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +@@ -302,7 +302,6 @@ static void ge_b850v3_lvds_remove(void) + goto out; + + drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge); +- + ge_b850v3_lvds_ptr = NULL; + out: + mutex_unlock(&ge_b850v3_lvds_dev_mutex); +@@ -312,6 +311,7 @@ static int ge_b850v3_register(void) + { + struct i2c_client *stdp4028_i2c = ge_b850v3_lvds_ptr->stdp4028_i2c; + struct device *dev = &stdp4028_i2c->dev; ++ int ret; + + /* drm bridge initialization */ + ge_b850v3_lvds_ptr->bridge.funcs = &ge_b850v3_lvds_funcs; +@@ -329,11 +329,15 @@ static int ge_b850v3_register(void) + if (!stdp4028_i2c->irq) + return 0; + +- return devm_request_threaded_irq(&stdp4028_i2c->dev, +- stdp4028_i2c->irq, NULL, +- ge_b850v3_lvds_irq_handler, +- IRQF_TRIGGER_HIGH | IRQF_ONESHOT, +- "ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr); ++ ret = devm_request_threaded_irq(&stdp4028_i2c->dev, ++ stdp4028_i2c->irq, NULL, ++ ge_b850v3_lvds_irq_handler, ++ IRQF_TRIGGER_HIGH | IRQF_ONESHOT, ++ "ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr); ++ if (ret) ++ drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge); ++ ++ return ret; + } + + static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, diff --git a/queue-6.1/drm-virtio-use-uninterruptible-resv-lock-for-plane-updates.patch b/queue-6.1/drm-virtio-use-uninterruptible-resv-lock-for-plane-updates.patch new file mode 100644 index 0000000000..dd4d92f076 --- /dev/null +++ b/queue-6.1/drm-virtio-use-uninterruptible-resv-lock-for-plane-updates.patch @@ -0,0 +1,145 @@ +From 9af1b6e175c82daf4b423da339a722d8e67a735a Mon Sep 17 00:00:00 2001 +From: Deepanshu Kartikey +Date: Tue, 19 May 2026 13:52:47 +0530 +Subject: drm/virtio: use uninterruptible resv lock for plane updates + +From: Deepanshu Kartikey + +commit 9af1b6e175c82daf4b423da339a722d8e67a735a upstream. + +virtio_gpu_cursor_plane_update() and virtio_gpu_resource_flush() lock +the framebuffer BO's dma_resv via virtio_gpu_array_lock_resv() and +ignore its return value. The function can fail with -EINTR from +dma_resv_lock_interruptible() (signal during lock wait) or with +-ENOMEM from dma_resv_reserve_fences() (fence slot allocation), +leaving the resv lock not held. The queue path then walks the object +array and calls dma_resv_add_fence(), which requires the lock held; +with lockdep enabled this trips dma_resv_assert_held(): + + WARNING: drivers/dma-buf/dma-resv.c:296 at dma_resv_add_fence+0x71e/0x840 + Call Trace: + virtio_gpu_array_add_fence + virtio_gpu_queue_ctrl_sgs + virtio_gpu_queue_fenced_ctrl_buffer + virtio_gpu_cursor_plane_update + drm_atomic_helper_commit_planes + drm_atomic_helper_commit_tail + commit_tail + drm_atomic_helper_commit + drm_atomic_commit + drm_atomic_helper_update_plane + __setplane_atomic + drm_mode_cursor_universal + drm_mode_cursor_common + drm_mode_cursor_ioctl + drm_ioctl + __x64_sys_ioctl + +Beyond the WARN, mutating the dma_resv fence list without the lock +races with concurrent readers/writers and can corrupt the list. + +Both call sites run inside the .atomic_update plane callback, which +DRM atomic helpers do not allow to fail (by the time it runs, the +commit has been signed off to userspace and there is no clean +rollback path). Moving the lock acquisition to .prepare_fb was +rejected because the broader lock scope deadlocks against other BO +locking paths in the same atomic commit. + +Introduce virtio_gpu_lock_one_resv_uninterruptible() that uses +dma_resv_lock() instead of dma_resv_lock_interruptible(). This +eliminates the -EINTR failure mode -- the realistic syzbot trigger +-- without extending the lock hold across the commit. The helper +locks a single BO and rejects nents > 1 with -EINVAL; both fix +sites lock exactly one BO. + +Use it from virtio_gpu_cursor_plane_update() and +virtio_gpu_resource_flush(); check the return value to handle the +remaining -ENOMEM case from dma_resv_reserve_fences() by freeing +the objs and skipping the plane update for that frame. The +framebuffer BOs touched here are not shared with other contexts +and lock contention is expected to be brief, so the loss of +signal-interruptibility is acceptable. + +Other callers of virtio_gpu_array_lock_resv() (the ioctl paths) +continue to use the interruptible variant. + +The bug was reported by syzbot, triggered via fault injection +(fail_nth) on the DRM_IOCTL_MODE_CURSOR path, which forces the +-ENOMEM branch in dma_resv_reserve_fences(). + +Reported-by: syzbot+72bd3dd3a5d5f39a0271@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=72bd3dd3a5d5f39a0271 +Fixes: 5cfd31c5b3a3 ("drm/virtio: fix virtio_gpu_cursor_plane_update().") +Cc: stable@vger.kernel.org +Signed-off-by: Deepanshu Kartikey +Signed-off-by: Dmitry Osipenko +Link: https://patch.msgid.link/20260519082247.34470-1-kartikey406@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + + drivers/gpu/drm/virtio/virtgpu_gem.c | 17 +++++++++++++++++ + drivers/gpu/drm/virtio/virtgpu_plane.c | 10 ++++++++-- + 3 files changed, 26 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -311,6 +311,7 @@ virtio_gpu_array_from_handles(struct drm + void virtio_gpu_array_add_obj(struct virtio_gpu_object_array *objs, + struct drm_gem_object *obj); + int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs); ++int virtio_gpu_lock_one_resv_uninterruptible(struct virtio_gpu_object_array *objs); + void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs); + void virtio_gpu_array_add_fence(struct virtio_gpu_object_array *objs, + struct dma_fence *fence); +--- a/drivers/gpu/drm/virtio/virtgpu_gem.c ++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c +@@ -236,6 +236,23 @@ int virtio_gpu_array_lock_resv(struct vi + return ret; + } + ++int virtio_gpu_lock_one_resv_uninterruptible(struct virtio_gpu_object_array *objs) ++{ ++ int ret; ++ ++ if (objs->nents != 1) ++ return -EINVAL; ++ ++ dma_resv_lock(objs->objs[0]->resv, NULL); ++ ++ ret = dma_resv_reserve_fences(objs->objs[0]->resv, 1); ++ if (ret) { ++ virtio_gpu_array_unlock_resv(objs); ++ return ret; ++ } ++ return 0; ++} ++ + void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs) + { + if (objs->nents == 1) { +--- a/drivers/gpu/drm/virtio/virtgpu_plane.c ++++ b/drivers/gpu/drm/virtio/virtgpu_plane.c +@@ -158,7 +158,10 @@ static void virtio_gpu_resource_flush(st + if (!objs) + return; + virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]); +- virtio_gpu_array_lock_resv(objs); ++ if (virtio_gpu_lock_one_resv_uninterruptible(objs)) { ++ virtio_gpu_array_put_free(objs); ++ return; ++ } + virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y, + width, height, objs, + vgplane_st->fence); +@@ -329,7 +332,10 @@ static void virtio_gpu_cursor_plane_upda + if (!objs) + return; + virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]); +- virtio_gpu_array_lock_resv(objs); ++ if (virtio_gpu_lock_one_resv_uninterruptible(objs)) { ++ virtio_gpu_array_put_free(objs); ++ return; ++ } + virtio_gpu_cmd_transfer_to_host_2d + (vgdev, 0, + plane->state->crtc_w, diff --git a/queue-6.1/hwmon-pmbus-adm1266-bounce-blackbox-records-through-a-protocol-sized-buffer.patch b/queue-6.1/hwmon-pmbus-adm1266-bounce-blackbox-records-through-a-protocol-sized-buffer.patch new file mode 100644 index 0000000000..0703675326 --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-bounce-blackbox-records-through-a-protocol-sized-buffer.patch @@ -0,0 +1,69 @@ +From 43cae21424ff8e33894a0f86c6b80b840c049fd7 Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Fri, 15 May 2026 15:11:51 -0700 +Subject: hwmon: (pmbus/adm1266) bounce blackbox records through a protocol-sized buffer + +From: Abdurrahman Hussain + +commit 43cae21424ff8e33894a0f86c6b80b840c049fd7 upstream. + +adm1266_pmbus_block_xfer() copies the device-supplied block payload +into the caller-provided buffer using the device-supplied length: + + memcpy(data_r, &msgs[1].buf[1], msgs[1].buf[0]); + +The helper does not know how large data_r is and trusts the device to +return at most one record's worth of bytes. adm1266_nvmem_read_blackbox() +violates that contract: it advances read_buff inside data->dev_mem in +ADM1266_BLACKBOX_SIZE (64-byte) strides while the helper is willing to +write up to ADM1266_PMBUS_BLOCK_MAX (255) bytes. A device that returns +more than 64 bytes on the trailing record (read_buff offset 1984 in +the 2048-byte dev_mem allocation) overflows dev_mem by up to 191 bytes +before the post-call + + if (ret != ADM1266_BLACKBOX_SIZE) + return -EIO; + +can reject the response. + +Contain the fix in the caller without changing the helper signature: +read each record into a 255-byte local bounce buffer that matches the +helper's maximum output, validate the returned length, and only then +copy exactly ADM1266_BLACKBOX_SIZE bytes into the dev_mem slot. + +Fixes: 407dc802a9c0 ("hwmon: (pmbus/adm1266) Add Block process call") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Link: https://lore.kernel.org/r/20260515-adm1266-fixes-v1-5-1c1ea1349cfe@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -350,6 +350,7 @@ static void adm1266_init_debugfs(struct + + static int adm1266_nvmem_read_blackbox(struct adm1266_data *data, u8 *read_buff) + { ++ u8 record[ADM1266_PMBUS_BLOCK_MAX]; + int record_count; + char index; + u8 buf[I2C_SMBUS_BLOCK_MAX]; +@@ -367,13 +368,14 @@ static int adm1266_nvmem_read_blackbox(s + return -EIO; + + for (index = 0; index < record_count; index++) { +- ret = adm1266_pmbus_block_xfer(data, ADM1266_READ_BLACKBOX, 1, &index, read_buff); ++ ret = adm1266_pmbus_block_xfer(data, ADM1266_READ_BLACKBOX, 1, &index, record); + if (ret < 0) + return ret; + + if (ret != ADM1266_BLACKBOX_SIZE) + return -EIO; + ++ memcpy(read_buff, record, ADM1266_BLACKBOX_SIZE); + read_buff += ADM1266_BLACKBOX_SIZE; + } + diff --git a/queue-6.1/hwmon-pmbus-adm1266-cap-pdio-scan-in-get_multiple-at-adm1266_pdio_nr.patch b/queue-6.1/hwmon-pmbus-adm1266-cap-pdio-scan-in-get_multiple-at-adm1266_pdio_nr.patch new file mode 100644 index 0000000000..37ec95b11d --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-cap-pdio-scan-in-get_multiple-at-adm1266_pdio_nr.patch @@ -0,0 +1,55 @@ +From d7834d92251baade796812876e95555e2066fa9f Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Mon, 18 May 2026 17:52:25 -0700 +Subject: hwmon: (pmbus/adm1266) cap PDIO scan in get_multiple at ADM1266_PDIO_NR + +From: Abdurrahman Hussain + +commit d7834d92251baade796812876e95555e2066fa9f upstream. + +adm1266_gpio_get_multiple() iterates the PDIO portion of the +caller-supplied mask using + + for_each_set_bit_from(gpio_nr, mask, + ADM1266_GPIO_NR + ADM1266_PDIO_STATUS) { + ... + } + +where ADM1266_PDIO_STATUS is the PMBus command code (0xE9, i.e. 233), +not the number of PDIO pins. The intended upper bound is +ADM1266_GPIO_NR + ADM1266_PDIO_NR = 25. + +gpiolib hands in a mask sized for gc.ngpio (= 25 bits on this chip), +so the iteration walks find_next_bit() up to 242, reading up to 217 +extra bits (a handful of unsigned-long words: four on 64-bit, seven +on 32-bit) of whatever lives past the end of the mask in the +caller's stack. Any incidental set bit in that range then drives a +set_bit(gpio_nr, bits) call that writes past the end of the +caller-supplied bits array too -- both out-of-bounds. + +Substitute ADM1266_PDIO_NR for the constant so the scan stops at the +last real PDIO bit. + +Fixes: d98dfad35c38 ("hwmon: (pmbus/adm1266) Add support for GPIOs") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Reviewed-by: Bartosz Golaszewski +Reviewed-by: Linus Walleij +Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-1-e425e4f88139@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -212,7 +212,7 @@ static int adm1266_gpio_get_multiple(str + status = read_buf[0] + (read_buf[1] << 8); + + *bits = 0; +- for_each_set_bit_from(gpio_nr, mask, ADM1266_GPIO_NR + ADM1266_PDIO_STATUS) { ++ for_each_set_bit_from(gpio_nr, mask, ADM1266_GPIO_NR + ADM1266_PDIO_NR) { + if (test_bit(gpio_nr - ADM1266_GPIO_NR, &status)) + set_bit(gpio_nr, bits); + } diff --git a/queue-6.1/hwmon-pmbus-adm1266-don-t-clobber-gpio-bits-before-pdio-read-in-get_multiple.patch b/queue-6.1/hwmon-pmbus-adm1266-don-t-clobber-gpio-bits-before-pdio-read-in-get_multiple.patch new file mode 100644 index 0000000000..1ff5371e34 --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-don-t-clobber-gpio-bits-before-pdio-read-in-get_multiple.patch @@ -0,0 +1,55 @@ +From 3327a12aee9e10ffa903e28b8445dfd1af5307c0 Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Mon, 18 May 2026 17:52:26 -0700 +Subject: hwmon: (pmbus/adm1266) don't clobber GPIO bits before PDIO read in get_multiple + +From: Abdurrahman Hussain + +commit 3327a12aee9e10ffa903e28b8445dfd1af5307c0 upstream. + +adm1266_gpio_get_multiple() zeroes *bits before the GPIO_STATUS loop +and then a second time before the PDIO_STATUS loop: + + *bits = 0; + for_each_set_bit(gpio_nr, mask, ADM1266_GPIO_NR) { + ... + set_bit(gpio_nr, bits); + } + + ret = i2c_smbus_read_block_data(data->client, ADM1266_PDIO_STATUS, ...); + ... + *bits = 0; + for_each_set_bit_from(gpio_nr, mask, ADM1266_GPIO_NR + ADM1266_PDIO_NR) { + ... + set_bit(gpio_nr, bits); + } + +The second *bits = 0 throws away every GPIO bit the first loop just +populated, so callers asking for any combination of GPIO and PDIO +pins always see the GPIO portion of the returned bits as zero. + +Drop the redundant second assignment so both halves of the result +survive. + +Fixes: d98dfad35c38 ("hwmon: (pmbus/adm1266) Add support for GPIOs") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Reviewed-by: Bartosz Golaszewski +Reviewed-by: Linus Walleij +Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-2-e425e4f88139@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -211,7 +211,6 @@ static int adm1266_gpio_get_multiple(str + + status = read_buf[0] + (read_buf[1] << 8); + +- *bits = 0; + for_each_set_bit_from(gpio_nr, mask, ADM1266_GPIO_NR + ADM1266_PDIO_NR) { + if (test_bit(gpio_nr - ADM1266_GPIO_NR, &status)) + set_bit(gpio_nr, bits); diff --git a/queue-6.1/hwmon-pmbus-adm1266-include-pec-byte-in-pmbus_block_xfer-read-buffer.patch b/queue-6.1/hwmon-pmbus-adm1266-include-pec-byte-in-pmbus_block_xfer-read-buffer.patch new file mode 100644 index 0000000000..74d4a341f9 --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-include-pec-byte-in-pmbus_block_xfer-read-buffer.patch @@ -0,0 +1,52 @@ +From 487566cb1ccdf3756fdd7bf8d875e612ff3169bb Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Fri, 15 May 2026 15:11:50 -0700 +Subject: hwmon: (pmbus/adm1266) include PEC byte in pmbus_block_xfer read buffer + +From: Abdurrahman Hussain + +commit 487566cb1ccdf3756fdd7bf8d875e612ff3169bb upstream. + +adm1266_pmbus_block_xfer() sets up the read transaction with + + .buf = data->read_buf, + .len = ADM1266_PMBUS_BLOCK_MAX + 2, + +but read_buf in struct adm1266_data is declared as + + u8 read_buf[ADM1266_PMBUS_BLOCK_MAX + 1]; + +For a max-length block response (length byte = 255 + up to 1 PEC +byte), the i2c controller is told to write 257 bytes into a 256-byte +buffer, putting one byte past the end of read_buf. The same response +also makes the subsequent PEC compare + + if (crc != msgs[1].buf[msgs[1].buf[0] + 1]) + +read a byte beyond the array. + +Bump the read_buf declaration to ADM1266_PMBUS_BLOCK_MAX + 2 so the +buffer can hold the length byte, up to 255 payload bytes, and the PEC +byte the i2c_msg length already accounts for. + +Fixes: 407dc802a9c0 ("hwmon: (pmbus/adm1266) Add Block process call") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Link: https://lore.kernel.org/r/20260515-adm1266-fixes-v1-4-1c1ea1349cfe@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -61,7 +61,7 @@ struct adm1266_data { + u8 *dev_mem; + struct mutex buf_mutex; + u8 write_buf[ADM1266_PMBUS_BLOCK_MAX + 1] ____cacheline_aligned; +- u8 read_buf[ADM1266_PMBUS_BLOCK_MAX + 1] ____cacheline_aligned; ++ u8 read_buf[ADM1266_PMBUS_BLOCK_MAX + 2] ____cacheline_aligned; + }; + + static const struct nvmem_cell_info adm1266_nvmem_cells[] = { diff --git a/queue-6.1/hwmon-pmbus-adm1266-register-the-gpio_chip-after-pmbus_do_probe.patch b/queue-6.1/hwmon-pmbus-adm1266-register-the-gpio_chip-after-pmbus_do_probe.patch new file mode 100644 index 0000000000..3e1d882fa7 --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-register-the-gpio_chip-after-pmbus_do_probe.patch @@ -0,0 +1,60 @@ +From 491403b9b76cf66abd81301c5901aa4a4549f1e8 Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Mon, 18 May 2026 17:52:28 -0700 +Subject: hwmon: (pmbus/adm1266) register the gpio_chip after pmbus_do_probe() + +From: Abdurrahman Hussain + +commit 491403b9b76cf66abd81301c5901aa4a4549f1e8 upstream. + +adm1266_probe() calls adm1266_config_gpio() -- which goes on to +devm_gpiochip_add_data() and exposes the gpio_chip callbacks to +gpiolib -- before pmbus_do_probe() has initialised the per-client +PMBus state (notably the pmbus_lock mutex the core hands out via +pmbus_get_data()). + +That ordering is already a latent hazard: any GPIO access that lands +between adm1266_config_gpio() and the end of pmbus_do_probe() (for +example a sysfs read from a user space agent that opens the gpiochip +the instant gpiolib advertises it) races pmbus_do_probe()'s own +device accesses with no serialisation. + +Move adm1266_config_gpio() down past pmbus_do_probe() so the chip +isn't reachable from userspace until the PMBus state it depends on +is fully initialised. + +Fixes: d98dfad35c38 ("hwmon: (pmbus/adm1266) Add support for GPIOs") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Reviewed-by: Bartosz Golaszewski +Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-4-e425e4f88139@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -470,10 +470,6 @@ static int adm1266_probe(struct i2c_clie + crc8_populate_msb(pmbus_crc_table, 0x7); + mutex_init(&data->buf_mutex); + +- ret = adm1266_config_gpio(data); +- if (ret < 0) +- return ret; +- + ret = adm1266_set_rtc(data); + if (ret < 0) + return ret; +@@ -486,6 +482,10 @@ static int adm1266_probe(struct i2c_clie + if (ret) + return ret; + ++ ret = adm1266_config_gpio(data); ++ if (ret < 0) ++ return ret; ++ + adm1266_init_debugfs(data); + + return 0; diff --git a/queue-6.1/hwmon-pmbus-adm1266-register-the-nvmem-device-after-pmbus_do_probe.patch b/queue-6.1/hwmon-pmbus-adm1266-register-the-nvmem-device-after-pmbus_do_probe.patch new file mode 100644 index 0000000000..b23eff4d2c --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-register-the-nvmem-device-after-pmbus_do_probe.patch @@ -0,0 +1,55 @@ +From 6af713af91d5c34ec049eb3cc2c5b3f5eba953b8 Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Mon, 18 May 2026 17:52:29 -0700 +Subject: hwmon: (pmbus/adm1266) register the nvmem device after pmbus_do_probe() + +From: Abdurrahman Hussain + +commit 6af713af91d5c34ec049eb3cc2c5b3f5eba953b8 upstream. + +adm1266_probe() calls adm1266_config_nvmem() -- which goes on to +devm_nvmem_register() and exposes adm1266_nvmem_read() to userspace -- +before pmbus_do_probe() has initialised the per-client PMBus state. + +Same latent hazard as the gpio_chip one fixed in the previous patch: +once the nvmem device is registered, gpiolib's nvmem char-dev / sysfs +interface is reachable, and any concurrent read triggers +adm1266_nvmem_read() -> adm1266_nvmem_read_blackbox(), which issues +PMBus traffic that races pmbus_do_probe()'s own device accesses with +no serialisation. + +Move adm1266_config_nvmem() down past pmbus_do_probe() so the nvmem +device isn't reachable from userspace until the PMBus state the +nvmem accessors depend on is fully initialised. + +Fixes: 15609d189302 ("hwmon: (pmbus/adm1266) read blackbox") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-5-e425e4f88139@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -474,14 +474,14 @@ static int adm1266_probe(struct i2c_clie + if (ret < 0) + return ret; + +- ret = adm1266_config_nvmem(data); +- if (ret < 0) +- return ret; +- + ret = pmbus_do_probe(client, &data->info); + if (ret) + return ret; + ++ ret = adm1266_config_nvmem(data); ++ if (ret < 0) ++ return ret; ++ + ret = adm1266_config_gpio(data); + if (ret < 0) + return ret; diff --git a/queue-6.1/hwmon-pmbus-adm1266-reject-implausible-blackbox-record_count.patch b/queue-6.1/hwmon-pmbus-adm1266-reject-implausible-blackbox-record_count.patch new file mode 100644 index 0000000000..9ab8c3a92d --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-reject-implausible-blackbox-record_count.patch @@ -0,0 +1,51 @@ +From 4afca954622d672ea65ed961bed01cf91caa034e Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Fri, 15 May 2026 15:11:49 -0700 +Subject: hwmon: (pmbus/adm1266) reject implausible blackbox record_count + +From: Abdurrahman Hussain + +commit 4afca954622d672ea65ed961bed01cf91caa034e upstream. + +adm1266_nvmem_read_blackbox() loops over a record_count that comes +straight from byte 3 of the BLACKBOX_INFO response. The destination +buffer is data->dev_mem, sized for the nvmem cell's declared 2048 +bytes (ADM1266_BLACKBOX_MAX_RECORDS * ADM1266_BLACKBOX_SIZE = 32 * 64). +A device that reports a record_count greater than 32 -- whether due +to firmware bugs, bus corruption, or a non-responsive slave returning +0xff -- would walk read_buff past the end of the dev_mem allocation +on the trailing iterations. + +Cap record_count at ADM1266_BLACKBOX_MAX_RECORDS (introduced here) +before entering the loop and return -EIO on any larger value, so a +malformed BLACKBOX_INFO response cannot drive the loop out of bounds. + +Fixes: 15609d189302 ("hwmon: (pmbus/adm1266) read blackbox") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Link: https://lore.kernel.org/r/20260515-adm1266-fixes-v1-3-1c1ea1349cfe@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -46,6 +46,7 @@ + + #define ADM1266_BLACKBOX_OFFSET 0 + #define ADM1266_BLACKBOX_SIZE 64 ++#define ADM1266_BLACKBOX_MAX_RECORDS 32 + + #define ADM1266_PMBUS_BLOCK_MAX 255 + +@@ -362,6 +363,8 @@ static int adm1266_nvmem_read_blackbox(s + return -EIO; + + record_count = buf[3]; ++ if (record_count > ADM1266_BLACKBOX_MAX_RECORDS) ++ return -EIO; + + for (index = 0; index < record_count; index++) { + ret = adm1266_pmbus_block_xfer(data, ADM1266_READ_BLACKBOX, 1, &index, read_buff); diff --git a/queue-6.1/hwmon-pmbus-adm1266-reject-short-block-read-responses-in-the-gpio-accessors.patch b/queue-6.1/hwmon-pmbus-adm1266-reject-short-block-read-responses-in-the-gpio-accessors.patch new file mode 100644 index 0000000000..b3ff5cbdba --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-reject-short-block-read-responses-in-the-gpio-accessors.patch @@ -0,0 +1,71 @@ +From a7232f68c43ca62f545049b7f5fbfc75137b843b Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Mon, 18 May 2026 17:52:27 -0700 +Subject: hwmon: (pmbus/adm1266) reject short block-read responses in the GPIO accessors + +From: Abdurrahman Hussain + +commit a7232f68c43ca62f545049b7f5fbfc75137b843b upstream. + +adm1266_gpio_get() and adm1266_gpio_get_multiple() both compose the +pin-status word as + + pins_status = read_buf[0] + (read_buf[1] << 8); + +right after i2c_smbus_read_block_data(), guarding only against an +error return. A well-behaved device returns 2 bytes for +GPIO_STATUS/PDIO_STATUS, but the helper happily reports a 0- or +1-byte response too. If the device returns 0 bytes, both read_buf +slots are uninitialized stack memory; if it returns 1 byte, read_buf[1] +is. + +The composed value then flows through set_bit() into the caller's +*bits in adm1266_gpio_get_multiple(), or into the return value of +adm1266_gpio_get(), and ends up in userspace via gpiolib (sysfs and +the char-dev ioctls). That leaks a few bits of kernel stack per +request on any device whose firmware glitch, bus error, or hostile +slave produces a short block-read response. + +Add the missing length check to both call sites and surface a short +response as -EIO. + +Fixes: d98dfad35c38 ("hwmon: (pmbus/adm1266) Add support for GPIOs") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Reviewed-by: Bartosz Golaszewski +Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-3-e425e4f88139@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -176,6 +176,8 @@ static int adm1266_gpio_get(struct gpio_ + ret = i2c_smbus_read_block_data(data->client, pmbus_cmd, read_buf); + if (ret < 0) + return ret; ++ if (ret < 2) ++ return -EIO; + + pins_status = read_buf[0] + (read_buf[1] << 8); + if (offset < ADM1266_GPIO_NR) +@@ -196,6 +198,8 @@ static int adm1266_gpio_get_multiple(str + ret = i2c_smbus_read_block_data(data->client, ADM1266_GPIO_STATUS, read_buf); + if (ret < 0) + return ret; ++ if (ret < 2) ++ return -EIO; + + status = read_buf[0] + (read_buf[1] << 8); + +@@ -208,6 +212,8 @@ static int adm1266_gpio_get_multiple(str + ret = i2c_smbus_read_block_data(data->client, ADM1266_PDIO_STATUS, read_buf); + if (ret < 0) + return ret; ++ if (ret < 2) ++ return -EIO; + + status = read_buf[0] + (read_buf[1] << 8); + diff --git a/queue-6.1/hwmon-pmbus-adm1266-seed-timestamp-from-the-real-time-clock.patch b/queue-6.1/hwmon-pmbus-adm1266-seed-timestamp-from-the-real-time-clock.patch new file mode 100644 index 0000000000..f5ee1abc72 --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-seed-timestamp-from-the-real-time-clock.patch @@ -0,0 +1,45 @@ +From b86095e3d7dcf2bf80c747349a35912a87a85098 Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Fri, 15 May 2026 15:11:47 -0700 +Subject: hwmon: (pmbus/adm1266) seed timestamp from the real-time clock + +From: Abdurrahman Hussain + +commit b86095e3d7dcf2bf80c747349a35912a87a85098 upstream. + +adm1266_set_rtc() seeds the chip's SET_RTC register from +ktime_get_seconds(), which returns CLOCK_MONOTONIC -- i.e. seconds +since the host last booted, not seconds since the Unix epoch. + +The chip stamps that value into every blackbox record it captures. +Userspace reading those timestamps back expects wall-clock seconds: +that's what the SET_RTC frame layout documents (datasheet Rev. D, +Table 84) and what every other consumer of "seconds since epoch" +assumes. Seeding from CLOCK_MONOTONIC gives blackbox records a +timestamp that is only meaningful within a single boot of the host +and silently resets to small values on every reboot. + +Switch to ktime_get_real_seconds() so the seed matches what the +register is documented to hold. + +Fixes: 15609d189302 ("hwmon: (pmbus/adm1266) read blackbox") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Link: https://lore.kernel.org/r/20260515-adm1266-fixes-v1-1-1c1ea1349cfe@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -436,7 +436,7 @@ static int adm1266_set_rtc(struct adm126 + char write_buf[6]; + int i; + +- kt = ktime_get_seconds(); ++ kt = ktime_get_real_seconds(); + + memset(write_buf, 0, sizeof(write_buf)); + diff --git a/queue-6.1/hwmon-pmbus-adm1266-serialize-gpio-pmbus-accesses-with-pmbus_lock.patch b/queue-6.1/hwmon-pmbus-adm1266-serialize-gpio-pmbus-accesses-with-pmbus_lock.patch new file mode 100644 index 0000000000..2c3e3d7110 --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-serialize-gpio-pmbus-accesses-with-pmbus_lock.patch @@ -0,0 +1,62 @@ +From bab8c6fb5af8df7e753d196c1262cb78e92ca872 Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Mon, 18 May 2026 17:52:30 -0700 +Subject: hwmon: (pmbus/adm1266) serialize GPIO PMBus accesses with pmbus_lock + +From: Abdurrahman Hussain + +commit bab8c6fb5af8df7e753d196c1262cb78e92ca872 upstream. + +adm1266_gpio_get(), adm1266_gpio_get_multiple(), and +adm1266_gpio_dbg_show() all issue PMBus reads against the device but +none of them take pmbus_lock. The pmbus_core framework holds +pmbus_lock around its own multi-transaction sequences (notably the +"set PAGE, then read paged register" pattern used by hwmon +attributes), so an unlocked GPIO accessor can land between a PAGE +write and the subsequent paged read in another thread and corrupt +either side's view of the device state machine. + +Take pmbus_lock at the top of each of the three accessors via the +scope-based guard(). The lock is uncontended in the common case and +adds only a single mutex round-trip per call. + +Fixes: d98dfad35c38 ("hwmon: (pmbus/adm1266) Add support for GPIOs") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Reviewed-by: Bartosz Golaszewski +Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-6-e425e4f88139@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -173,6 +173,8 @@ static int adm1266_gpio_get(struct gpio_ + else + pmbus_cmd = ADM1266_PDIO_STATUS; + ++ guard(pmbus_lock)(data->client); ++ + ret = i2c_smbus_read_block_data(data->client, pmbus_cmd, read_buf); + if (ret < 0) + return ret; +@@ -195,6 +197,8 @@ static int adm1266_gpio_get_multiple(str + unsigned int gpio_nr; + int ret; + ++ guard(pmbus_lock)(data->client); ++ + ret = i2c_smbus_read_block_data(data->client, ADM1266_GPIO_STATUS, read_buf); + if (ret < 0) + return ret; +@@ -236,6 +240,8 @@ static void adm1266_gpio_dbg_show(struct + int ret; + int i; + ++ guard(pmbus_lock)(data->client); ++ + for (i = 0; i < ADM1266_GPIO_NR; i++) { + write_cmd = adm1266_gpio_mapping[i][1]; + ret = adm1266_pmbus_block_xfer(data, ADM1266_GPIO_CONFIG, 1, &write_cmd, read_buf); diff --git a/queue-6.1/hwmon-pmbus-adm1266-serialize-nvmem-blackbox-read-with-pmbus_lock.patch b/queue-6.1/hwmon-pmbus-adm1266-serialize-nvmem-blackbox-read-with-pmbus_lock.patch new file mode 100644 index 0000000000..8b77e07594 --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-serialize-nvmem-blackbox-read-with-pmbus_lock.patch @@ -0,0 +1,58 @@ +From 9f1dd8f9491eb840cbea7ffdf4cad031e25f8ae0 Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Mon, 18 May 2026 17:52:31 -0700 +Subject: hwmon: (pmbus/adm1266) serialize NVMEM blackbox read with pmbus_lock + +From: Abdurrahman Hussain + +commit 9f1dd8f9491eb840cbea7ffdf4cad031e25f8ae0 upstream. + +adm1266_nvmem_read() is the reg_read callback the NVMEM core invokes +when userspace reads /sys/bus/nvmem/devices/.../nvmem on this chip. +On the first byte of every read it does a memset of data->dev_mem, +walks the device blackbox through adm1266_nvmem_read_blackbox() +(which issues a chain of PMBus block transactions), and then memcpys +the refreshed buffer out to userspace. None of that runs under +pmbus_lock today. + +Two consequences: + + - The PMBus traffic the refresh issues is not serialised against + pmbus_core's own multi-step PAGE+register sequences. A paged + hwmon attribute read from another thread can land between a + PAGE write and the paged read in either direction and corrupt + one side's view of the device state machine. + + - The NVMEM core does not serialise concurrent reg_read calls, so + two userspace readers racing at offset 0 can interleave the + memset of data->dev_mem with another reader's + adm1266_nvmem_read_blackbox() refill or memcpy out, returning + torn data to userspace. + +Take pmbus_lock at the top of adm1266_nvmem_read() via the +scope-based guard(). Patch 5 of this series moves +adm1266_config_nvmem() past pmbus_do_probe() so the lock is +guaranteed to be live before the callback is reachable from +userspace. + +Fixes: 15609d189302 ("hwmon: (pmbus/adm1266) read blackbox") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-7-e425e4f88139@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -385,6 +385,8 @@ static int adm1266_nvmem_read(void *priv + if (offset + bytes > data->nvmem_config.size) + return -EINVAL; + ++ guard(pmbus_lock)(data->client); ++ + if (offset == 0) { + memset(data->dev_mem, 0, data->nvmem_config.size); + diff --git a/queue-6.1/hwmon-pmbus-adm1266-serialize-sequencer_state-debugfs-read-with-pmbus_lock.patch b/queue-6.1/hwmon-pmbus-adm1266-serialize-sequencer_state-debugfs-read-with-pmbus_lock.patch new file mode 100644 index 0000000000..1c10ea0dcc --- /dev/null +++ b/queue-6.1/hwmon-pmbus-adm1266-serialize-sequencer_state-debugfs-read-with-pmbus_lock.patch @@ -0,0 +1,44 @@ +From 4e4af55aaca7f6d7673d5f9889ad0529db86a048 Mon Sep 17 00:00:00 2001 +From: Abdurrahman Hussain +Date: Mon, 18 May 2026 17:52:32 -0700 +Subject: hwmon: (pmbus/adm1266) serialize sequencer_state debugfs read with pmbus_lock + +From: Abdurrahman Hussain + +commit 4e4af55aaca7f6d7673d5f9889ad0529db86a048 upstream. + +adm1266_state_read() backs the sequencer_state debugfs entry and +issues an i2c_smbus_read_word_data(client, ADM1266_READ_STATE) +against the device without taking pmbus_lock. pmbus_core holds +pmbus_lock around its own multi-transaction sequences (notably the +"set PAGE, then read paged register" pattern used by hwmon +attributes), so an unlocked debugfs reader can land between a PAGE +write and the subsequent paged read in another thread. READ_STATE +itself is not paged, so it cannot corrupt PAGE in flight, but the +same defensive serialisation that applies to the GPIO accessors +applies here: any direct device access from outside pmbus_core +should be ordered with respect to pmbus_core's own. + +Take pmbus_lock at the top of adm1266_state_read() via the +scope-based guard(). + +Fixes: ed1ff457e187 ("hwmon: (pmbus/adm1266) add debugfs for states") +Cc: stable@vger.kernel.org +Signed-off-by: Abdurrahman Hussain +Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-8-e425e4f88139@nexthop.ai +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/pmbus/adm1266.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/hwmon/pmbus/adm1266.c ++++ b/drivers/hwmon/pmbus/adm1266.c +@@ -334,6 +334,7 @@ static int adm1266_state_read(struct seq + struct i2c_client *client = to_i2c_client(dev); + int ret; + ++ guard(pmbus_lock)(client); + ret = i2c_smbus_read_word_data(client, ADM1266_READ_STATE); + if (ret < 0) + return ret; diff --git a/queue-6.1/kvm-arm64-vgic-its-reject-restored-dte-with-out-of-range-num_eventid_bits.patch b/queue-6.1/kvm-arm64-vgic-its-reject-restored-dte-with-out-of-range-num_eventid_bits.patch new file mode 100644 index 0000000000..4d5fc154f9 --- /dev/null +++ b/queue-6.1/kvm-arm64-vgic-its-reject-restored-dte-with-out-of-range-num_eventid_bits.patch @@ -0,0 +1,43 @@ +From 9ce754ed8e7ab4e3999767ce1505f85c449ccb07 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Tue, 19 May 2026 09:25:19 -0400 +Subject: KVM: arm64: vgic-its: Reject restored DTE with out-of-range num_eventid_bits + +From: Michael Bommarito + +commit 9ce754ed8e7ab4e3999767ce1505f85c449ccb07 upstream. + +Userspace can restore an ITS Device Table Entry whose Size field encodes +more EventID bits than the virtual ITS supports. The live MAPD path +rejects that state, but vgic_its_restore_dte() accepts it and stores the +out-of-range value in dev->num_eventid_bits. + +Reject restored DTEs with num_eventid_bits > VITS_TYPER_IDBITS before +allocating the device. This mirrors the MAPD check and prevents the +restored state from reaching vgic_its_restore_itt(), where the unchecked +value can be converted into an oversized scan_its_table() range. + +Fixes: 57a9a117154c ("KVM: arm64: vgic-its: Device table save/restore") +Assisted-by: Claude:claude-opus-4-7 +Signed-off-by: Michael Bommarito +Link: https://lore.kernel.org/r/20260519132519.2142458-1-michael.bommarito@gmail.com +Signed-off-by: Marc Zyngier +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kvm/vgic/vgic-its.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/arm64/kvm/vgic/vgic-its.c ++++ b/arch/arm64/kvm/vgic/vgic-its.c +@@ -2413,6 +2413,10 @@ static int vgic_its_restore_dte(struct v + /* dte entry is valid */ + offset = (entry & KVM_ITS_DTE_NEXT_MASK) >> KVM_ITS_DTE_NEXT_SHIFT; + ++ /* Mimic the MAPD behaviour and reject invalid EID bits. */ ++ if (num_eventid_bits > VITS_TYPER_IDBITS) ++ return -EINVAL; ++ + if (!vgic_its_check_id(its, baser, id, NULL)) + return -EINVAL; + diff --git a/queue-6.1/loongarch-remove-unused-code-to-avoid-build-warning.patch b/queue-6.1/loongarch-remove-unused-code-to-avoid-build-warning.patch new file mode 100644 index 0000000000..ca52245e88 --- /dev/null +++ b/queue-6.1/loongarch-remove-unused-code-to-avoid-build-warning.patch @@ -0,0 +1,40 @@ +From 0ccc9d47cf020994097ff51827cebd04aa2b0bf4 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Thu, 21 May 2026 20:58:40 +0800 +Subject: LoongArch: Remove unused code to avoid build warning + +From: Huacai Chen + +commit 0ccc9d47cf020994097ff51827cebd04aa2b0bf4 upstream. + +After commit feee6b2989165631b1 ("mm/memory_hotplug: shrink zones when +offlining memory"), __remove_pages() doesn't need the "zone" parameter +so the "page" variable is also unused. Remove the unused code to avoid +such build warning: + +arch/loongarch/mm/init.c: In function 'arch_remove_memory': +arch/loongarch/mm/init.c:134:22: warning: variable 'page' set but not used [-Wunused-but-set-variable=] + 134 | struct page *page = pfn_to_page(start_pfn); + +Cc: +Reviewed-by: Guo Ren +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + arch/loongarch/mm/init.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/arch/loongarch/mm/init.c ++++ b/arch/loongarch/mm/init.c +@@ -132,11 +132,7 @@ void arch_remove_memory(u64 start, u64 s + { + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long nr_pages = size >> PAGE_SHIFT; +- struct page *page = pfn_to_page(start_pfn); + +- /* With altmap the first mapped page is offset from @start */ +- if (altmap) +- page += vmem_altmap_offset(altmap); + __remove_pages(start_pfn, nr_pages, altmap); + } + diff --git a/queue-6.1/rdma-siw-reject-mpa-fpdu-length-underflow-before-signed-receive-math.patch b/queue-6.1/rdma-siw-reject-mpa-fpdu-length-underflow-before-signed-receive-math.patch new file mode 100644 index 0000000000..bf317f39c5 --- /dev/null +++ b/queue-6.1/rdma-siw-reject-mpa-fpdu-length-underflow-before-signed-receive-math.patch @@ -0,0 +1,101 @@ +From 0ce1bc9e46ecabe84772bb561e373c0d9876d6f2 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Wed, 13 May 2026 13:53:24 -0400 +Subject: RDMA/siw: Reject MPA FPDU length underflow before signed receive math + +From: Michael Bommarito + +commit 0ce1bc9e46ecabe84772bb561e373c0d9876d6f2 upstream. + +A malicious connected siw peer can send an iWARP FPDU whose MPA length +field (c_hdr->mpa_len, 16 bit big-endian, peer-controlled) is smaller +than the fixed DDP/RDMAP header for the announced opcode. Soft-iWARP +parses the full header in siw_get_hdr() based on iwarp_pktinfo[opcode] +.hdr_len, but never compares mpa_len against that header length. + +siw_tcp_rx_data() then derives + + srx->fpdu_part_rem = be16_to_cpu(mpa_len) - fpdu_part_rcvd + + MPA_HDR_SIZE; + +where fpdu_part_rcvd equals iwarp_pktinfo[opcode].hdr_len at this +point. For a tagged WRITE (hdr_len 16, MPA_HDR_SIZE 2) the smallest +on-wire mpa_len of 0 yields fpdu_part_rem = -14, and any mpa_len below +hdr_len - MPA_HDR_SIZE underflows to a negative int. + +The signed value then flows into siw_proc_write()/siw_proc_rresp() as + + bytes = min(srx->fpdu_part_rem, srx->skb_new); + +is handed to siw_check_mem() as an int len (whose interval check +addr + len > mem->va + mem->len is satisfied for a valid base when +len is negative), and reaches siw_rx_data() -> siw_rx_kva() / +siw_rx_umem() -> skb_copy_bits() as a signed copy length. The header +copy branch in skb_copy_bits() promotes that to size_t, producing a +multi-gigabyte read. + +KASAN under a KUnit harness that drives the real kernel TCP receive +path -- a loopback AF_INET socketpair, the malformed FPDU written via +kernel_sendmsg, sk_data_ready firing in softirq, tcp_read_sock +dispatching to siw_tcp_rx_data -- reports: + + BUG: KASAN: use-after-free in skb_copy_bits+0x284/0x480 + Read of size 4294967295 at addr ffff888... + Call Trace: + skb_copy_bits + siw_rx_kva + siw_rx_data + siw_check_mem + siw_proc_write + siw_tcp_rx_data + __tcp_read_sock + siw_qp_llp_data_ready + tcp_data_ready + tcp_data_queue + +Add the missing invariant at the earliest point where the peer header +is fully assembled. iwarp_pktinfo[*].hdr_len - MPA_HDR_SIZE is exactly +the value the siw transmitter uses as the minimum mpa_len for each +opcode (drivers/infiniband/sw/siw/siw_qp.c:33), so this matches the +protocol contract. Out-of-range FPDUs terminate the connection with +TERM_ERROR_LAYER_LLP / LLP_ETYPE_MPA / LLP_ECODE_FPDU_START -- which +is RFC 5044 Section 8 error code 3 ("Marker and ULPDU Length fields +do not agree on the start of an FPDU"), the correct framing-error +class for this inconsistency. + +Fixes: 8b6a361b8c48 ("rdma/siw: receive path") +Link: https://patch.msgid.link/r/20260513175325.2042630-2-michael.bommarito@gmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Michael Bommarito +Assisted-by: Claude:claude-opus-4-7 +Acked-by: Bernard Metzler +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/sw/siw/siw_qp_rx.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/infiniband/sw/siw/siw_qp_rx.c ++++ b/drivers/infiniband/sw/siw/siw_qp_rx.c +@@ -1102,6 +1102,21 @@ static int siw_get_hdr(struct siw_rx_str + } + + /* ++ * Peer-controlled mpa_len must not underflow srx->fpdu_part_rem ++ * in siw_tcp_rx_data(); a negative value flows as a signed copy ++ * length into siw_check_mem() and skb_copy_bits(). ++ */ ++ if (unlikely(be16_to_cpu(c_hdr->mpa_len) + MPA_HDR_SIZE < ++ iwarp_pktinfo[opcode].hdr_len)) { ++ pr_warn_ratelimited("siw: short mpa_len %u for opcode %u (hdr_len %u)\n", ++ be16_to_cpu(c_hdr->mpa_len), opcode, ++ iwarp_pktinfo[opcode].hdr_len); ++ siw_init_terminate(rx_qp(srx), TERM_ERROR_LAYER_LLP, ++ LLP_ETYPE_MPA, LLP_ECODE_FPDU_START, 0); ++ return -EINVAL; ++ } ++ ++ /* + * DDP/RDMAP header receive completed. Check if the current + * DDP segment starts a new RDMAP message or continues a previously + * started RDMAP message. diff --git a/queue-6.1/scsi-isci-fix-use-after-free-in-device-removal-path.patch b/queue-6.1/scsi-isci-fix-use-after-free-in-device-removal-path.patch new file mode 100644 index 0000000000..669a9ecfdb --- /dev/null +++ b/queue-6.1/scsi-isci-fix-use-after-free-in-device-removal-path.patch @@ -0,0 +1,60 @@ +From b52a8d52c3125ec9a93106ed816582368de34426 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Sun, 19 Apr 2026 17:04:20 -0400 +Subject: scsi: isci: Fix use-after-free in device removal path + +From: Michael Bommarito + +commit b52a8d52c3125ec9a93106ed816582368de34426 upstream. + +The ISCI completion tasklet is initialized in isci_host_alloc() +(drivers/scsi/isci/init.c:496) and scheduled from both MSI-X and legacy +interrupt handlers (drivers/scsi/isci/host.c:223,613). + +isci_host_deinit() stops the controller and waits for stop completion, +but it never kills completion_tasklet before teardown continues. A +top-of-function tasklet_kill() is not sufficient here: interrupts are +only disabled when isci_host_stop_complete() runs, so until +wait_for_stop() returns the IRQ handlers can still requeue the +tasklet. The tasklet callback also re-enables interrupts after draining +completions, so killing the tasklet before the source is quiesced leaves +the same race open. + +Once wait_for_stop() returns, no further IRQ-driven scheduling can +occur. Kill completion_tasklet there so teardown cannot race a queued +tasklet running on a dead ihost. On remove or unload, the stale callback +can otherwise dereference ihost and touch ihost->smu_registers after the +host lifetime ends. + +A UML + KASAN analogue reproduced the failure class both with no +tasklet_kill() and with tasklet_kill() placed before source quiesce, and +stayed clean once the kill happened after quiescing the scheduling +source. + +This mirrors commit f6ab594672d4 ("scsi: aic94xx: fix use-after-free in +device removal path"), but ISCI needs the kill after wait_for_stop(). + +Fixes: 6f231dda6808 ("isci: Intel(R) C600 Series Chipset Storage Control Unit Driver") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-7 +Assisted-by: Codex:gpt-5-4 +Signed-off-by: Michael Bommarito +Link: https://patch.msgid.link/20260419210420.2134639-1-michael.bommarito@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/isci/host.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/scsi/isci/host.c ++++ b/drivers/scsi/isci/host.c +@@ -1252,6 +1252,9 @@ void isci_host_deinit(struct isci_host * + + wait_for_stop(ihost); + ++ /* No further IRQ-driven scheduling can happen past wait_for_stop(). */ ++ tasklet_kill(&ihost->completion_tasklet); ++ + /* phy stop is after controller stop to allow port and device to + * go idle before shutting down the phys, but the expectation is + * that i/o has been shut off well before we reach this diff --git a/queue-6.1/series b/queue-6.1/series index d25c23b7e6..9bfc8a4c49 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -862,3 +862,41 @@ ipv4-raw-reject-ip_hdrincl-packets-with-ihl-5.patch ixgbevf-fix-use-after-free-in-vepa-multicast-source-pruning.patch ice-fix-setting-promisc-mode-while-adding-vid-filter.patch wifi-cfg80211-advance-loop-vars-in-cfg80211_merge_profile.patch +cifs-fix-busy-dentry-used-after-unmounting.patch +tracing-do-not-call-map-ops-elt_free-if-elt_alloc-fails.patch +kvm-arm64-vgic-its-reject-restored-dte-with-out-of-range-num_eventid_bits.patch +hwmon-pmbus-adm1266-serialize-nvmem-blackbox-read-with-pmbus_lock.patch +drm-bridge-chipone-icn6211-use-devm_drm_bridge_add-in-i2c-probe.patch +scsi-isci-fix-use-after-free-in-device-removal-path.patch +spi-sprd-fix-error-pointer-deref-after-dma-setup-failure.patch +spi-ti-qspi-fix-use-after-free-after-dma-setup-failure.patch +rdma-siw-reject-mpa-fpdu-length-underflow-before-signed-receive-math.patch +loongarch-remove-unused-code-to-avoid-build-warning.patch +device-property-set-fwnode-secondary-to-null-in-fwnode_init.patch +drm-virtio-use-uninterruptible-resv-lock-for-plane-updates.patch +drm-bridge-it66121-acquire-reset-gpio-in-probe.patch +drm-bridge-megachips-remove-bridge-when-irq-request-fails.patch +drm-amd-display-fix-integer-overflow-in-bios_get_image.patch +drm-amd-display-validate-gpio-pin-lut-table-size-before-iterating.patch +drm-amd-display-validate-payload-length-and-link_index-in-dc_process_dmub_aux_transfer_async.patch +batman-adv-mcast-fix-use-after-free-in-orig_node-rcu-release.patch +batman-adv-clear-current-gateway-during-teardown.patch +batman-adv-dat-handle-forward-allocation-error.patch +batman-adv-fix-fragment-reassembly-length-accounting.patch +batman-adv-fix-tp_meter-counter-underflow-during-shutdown.patch +batman-adv-frag-disallow-unicast-fragment-in-fragment.patch +batman-adv-bla-fix-report_work-leak-on-backbone_gw-purge.patch +batman-adv-tp_meter-avoid-use-of-uninit-sender-vars.patch +batman-adv-tt-fix-negative-last_changeset_len.patch +batman-adv-tt-fix-negative-tt_buff_len.patch +hwmon-pmbus-adm1266-seed-timestamp-from-the-real-time-clock.patch +hwmon-pmbus-adm1266-reject-implausible-blackbox-record_count.patch +hwmon-pmbus-adm1266-include-pec-byte-in-pmbus_block_xfer-read-buffer.patch +hwmon-pmbus-adm1266-bounce-blackbox-records-through-a-protocol-sized-buffer.patch +hwmon-pmbus-adm1266-cap-pdio-scan-in-get_multiple-at-adm1266_pdio_nr.patch +hwmon-pmbus-adm1266-don-t-clobber-gpio-bits-before-pdio-read-in-get_multiple.patch +hwmon-pmbus-adm1266-register-the-gpio_chip-after-pmbus_do_probe.patch +hwmon-pmbus-adm1266-register-the-nvmem-device-after-pmbus_do_probe.patch +hwmon-pmbus-adm1266-reject-short-block-read-responses-in-the-gpio-accessors.patch +hwmon-pmbus-adm1266-serialize-gpio-pmbus-accesses-with-pmbus_lock.patch +hwmon-pmbus-adm1266-serialize-sequencer_state-debugfs-read-with-pmbus_lock.patch diff --git a/queue-6.1/spi-sprd-fix-error-pointer-deref-after-dma-setup-failure.patch b/queue-6.1/spi-sprd-fix-error-pointer-deref-after-dma-setup-failure.patch new file mode 100644 index 0000000000..6cd9c7a32d --- /dev/null +++ b/queue-6.1/spi-sprd-fix-error-pointer-deref-after-dma-setup-failure.patch @@ -0,0 +1,42 @@ +From 3d67fffb74267772d461c02c67f1eff893ad547d Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 12 May 2026 09:47:33 +0200 +Subject: spi: sprd: fix error pointer deref after DMA setup failure + +From: Johan Hovold + +commit 3d67fffb74267772d461c02c67f1eff893ad547d upstream. + +The driver falls back to PIO mode if DMA setup fails during probe. + +Make sure to check the dma.enabled flag before trying to release the DMA +channels also on late probe errors to avoid dereferencing an error +pointer (or attempting to release a channel a second time). + +This issue was flagged by Sashiko when reviewing a devres allocation +conversion patch. + +Fixes: 386119bc7be9 ("spi: sprd: spi: sprd: Add DMA mode support") +Link: https://sashiko.dev/#/patchset/20260505072909.618363-1-johan%40kernel.org?part=10 +Cc: stable@vger.kernel.org # 5.1 +Cc: Lanqing Liu +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260512074733.915029-1-johan@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi-sprd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/spi/spi-sprd.c ++++ b/drivers/spi/spi-sprd.c +@@ -995,7 +995,8 @@ err_rpm_put: + disable_clk: + clk_disable_unprepare(ss->clk); + release_dma: +- sprd_spi_dma_release(ss); ++ if (ss->dma.enable) ++ sprd_spi_dma_release(ss); + free_controller: + spi_controller_put(sctlr); + diff --git a/queue-6.1/spi-ti-qspi-fix-use-after-free-after-dma-setup-failure.patch b/queue-6.1/spi-ti-qspi-fix-use-after-free-after-dma-setup-failure.patch new file mode 100644 index 0000000000..1641c6fccb --- /dev/null +++ b/queue-6.1/spi-ti-qspi-fix-use-after-free-after-dma-setup-failure.patch @@ -0,0 +1,41 @@ +From ea6ec3343e05f7937a53eb6d7617b3abdb4abc19 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 12 May 2026 09:48:09 +0200 +Subject: spi: ti-qspi: fix use-after-free after DMA setup failure + +From: Johan Hovold + +commit ea6ec3343e05f7937a53eb6d7617b3abdb4abc19 upstream. + +The driver falls back to PIO mode if DMA setup fails during probe. + +Make sure to clear the DMA channel pointer also if buffer allocation +fails to avoid passing a pointer to the released channel to the DMA +engine (or trying to free the channel a second time on late probe errors +or driver unbind). + +This issue was flagged by Sashiko when reviewing a devres allocation +conversion patch. + +Fixes: c687c46e9e45 ("spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble") +Link: https://sashiko.dev/#/patchset/20260505072909.618363-1-johan%40kernel.org?part=17 +Cc: stable@vger.kernel.org # 4.12 +Cc: Vignesh R +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260512074809.915084-1-johan@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi-ti-qspi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/spi/spi-ti-qspi.c ++++ b/drivers/spi/spi-ti-qspi.c +@@ -875,6 +875,7 @@ static int ti_qspi_probe(struct platform + dev_err(qspi->dev, + "dma_alloc_coherent failed, using PIO mode\n"); + dma_release_channel(qspi->rx_chan); ++ qspi->rx_chan = NULL; + goto no_dma; + } + master->dma_rx = qspi->rx_chan; diff --git a/queue-6.1/tracing-do-not-call-map-ops-elt_free-if-elt_alloc-fails.patch b/queue-6.1/tracing-do-not-call-map-ops-elt_free-if-elt_alloc-fails.patch new file mode 100644 index 0000000000..a967cb85c7 --- /dev/null +++ b/queue-6.1/tracing-do-not-call-map-ops-elt_free-if-elt_alloc-fails.patch @@ -0,0 +1,73 @@ +From 8f0f5c4fb9df0e19a341e0c6ed8dc4fda9124f03 Mon Sep 17 00:00:00 2001 +From: "Masami Hiramatsu (Google)" +Date: Thu, 21 May 2026 13:49:14 +0900 +Subject: tracing: Do not call map->ops->elt_free() if elt_alloc() fails + +From: Masami Hiramatsu (Google) + +commit 8f0f5c4fb9df0e19a341e0c6ed8dc4fda9124f03 upstream. + +In paths where tracing_map_elt_alloc() failed to allocate objects, +the map->ops->elt_alloc() call was never successful. In this case, +map->ops->elt_free() should not be called. + +Link: https://sashiko.dev/#/patchset/20260520223101.34710-1-rosenp%40gmail.com + +Cc: stable@vger.kernel.org +Cc: Tom Zanussi +Cc: Mathieu Desnoyers +Cc: Rosen Penev +Reported-by: Sashiko +Fixes: 2734b629525a ("tracing: Add per-element variable support to tracing_map") +Link: https://patch.msgid.link/177933895460.108746.5396070821443932634.stgit@devnote2 +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/tracing_map.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +--- a/kernel/trace/tracing_map.c ++++ b/kernel/trace/tracing_map.c +@@ -386,13 +386,11 @@ static void tracing_map_elt_init_fields( + } + } + +-static void tracing_map_elt_free(struct tracing_map_elt *elt) ++static void __tracing_map_elt_free(struct tracing_map_elt *elt) + { + if (!elt) + return; + +- if (elt->map->ops && elt->map->ops->elt_free) +- elt->map->ops->elt_free(elt); + kfree(elt->fields); + kfree(elt->vars); + kfree(elt->var_set); +@@ -400,6 +398,17 @@ static void tracing_map_elt_free(struct + kfree(elt); + } + ++static void tracing_map_elt_free(struct tracing_map_elt *elt) ++{ ++ if (!elt) ++ return; ++ ++ /* Only objects initialized with alloc_elt() should be passed to free_elt().*/ ++ if (elt->map->ops && elt->map->ops->elt_free) ++ elt->map->ops->elt_free(elt); ++ __tracing_map_elt_free(elt); ++} ++ + static struct tracing_map_elt *tracing_map_elt_alloc(struct tracing_map *map) + { + struct tracing_map_elt *elt; +@@ -444,7 +453,7 @@ static struct tracing_map_elt *tracing_m + } + return elt; + free: +- tracing_map_elt_free(elt); ++ __tracing_map_elt_free(elt); + + return ERR_PTR(err); + }