From: Greg Kroah-Hartman Date: Wed, 29 Jul 2026 14:49:22 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v6.1.179~8 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=69f047326dc2e5aa87f22e37685ebc5c97dc7b19;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: ice-use-read_once-to-access-cached-phc-time.patch ila-reload-ipv6-header-after-pskb_may_pull-in-checksum-adjust.patch mac802154-hold-an-interface-reference-across-the-scan-worker.patch mac802154-llsec-reject-frames-shorter-than-the-authentication-tag.patch mctp-serial-handle-zero-length-frames-to-prevent-rx-buffer-overflow.patch pppoe-reload-header-pointer-after-dev_hard_header.patch tipc-clear-sock-sk-on-the-failed-insert-path-in-tipc_sk_create.patch vxlan-mdb-fix-source-list-corruption-on-a-failed-replace.patch --- diff --git a/queue-6.6/ice-use-read_once-to-access-cached-phc-time.patch b/queue-6.6/ice-use-read_once-to-access-cached-phc-time.patch new file mode 100644 index 0000000000..20d0421142 --- /dev/null +++ b/queue-6.6/ice-use-read_once-to-access-cached-phc-time.patch @@ -0,0 +1,39 @@ +From 2915681b89f817677ab9f1166d95b595bc144f5f Mon Sep 17 00:00:00 2001 +From: Sergey Temerkhanov +Date: Fri, 17 Jul 2026 11:53:30 -0700 +Subject: ice: use READ_ONCE() to access cached PHC time + +From: Sergey Temerkhanov + +commit 2915681b89f817677ab9f1166d95b595bc144f5f upstream. + +ptp.cached_phc_time is a 64-bit value updated by a periodic work item +on one CPU and read locklessly on another. On 32-bit or non-atomic +architectures this can result in a torn read. Use READ_ONCE() to +enforce a single atomic load. + +Fixes: 77a781155a65 ("ice: enable receive hardware timestamping") +Cc: stable@vger.kernel.org +Signed-off-by: Sergey Temerkhanov +Signed-off-by: Aleksandr Loktionov +Reviewed-by: Simon Horman +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20260717185340.3595286-9-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ice/ice_ptp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -595,7 +595,7 @@ static u64 ice_ptp_extend_40b_ts(struct + return 0; + } + +- return ice_ptp_extend_32b_ts(pf->ptp.cached_phc_time, ++ return ice_ptp_extend_32b_ts(READ_ONCE(pf->ptp.cached_phc_time), + (in_tstamp >> 8) & mask); + } + diff --git a/queue-6.6/ila-reload-ipv6-header-after-pskb_may_pull-in-checksum-adjust.patch b/queue-6.6/ila-reload-ipv6-header-after-pskb_may_pull-in-checksum-adjust.patch new file mode 100644 index 0000000000..9feade51a0 --- /dev/null +++ b/queue-6.6/ila-reload-ipv6-header-after-pskb_may_pull-in-checksum-adjust.patch @@ -0,0 +1,83 @@ +From 92d3817649df2b0b6a008a686c8275c88d7ef594 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Tue, 14 Jul 2026 07:49:03 -0400 +Subject: ila: reload IPv6 header after pskb_may_pull in checksum adjust + +From: Michael Bommarito + +commit 92d3817649df2b0b6a008a686c8275c88d7ef594 upstream. + +ila_csum_adjust_transport() caches ip6h = ipv6_hdr(skb) before calling +pskb_may_pull(). On a non-linear skb whose transport header sits in a page +fragment, pskb_may_pull() can call __pskb_pull_tail() / pskb_expand_head() +and free the old skb head, leaving ip6h dangling; the following +get_csum_diff(ip6h, p) then reads freed memory. ila_update_ipv6_locator() +uses ip6h (and the iaddr derived from it) again after the csum-adjust +call and additionally writes the new locator through that pointer. + +Impact: a remote IPv6 packet routed through a configured ILA +csum-adjust-transport route or receive-side mapping triggers a +slab-use-after-free in ila_update_ipv6_locator() (KASAN). The route or +mapping requires CAP_NET_ADMIN to configure, but trigger packets are +unauthenticated once it exists. + +Reload ip6h after each pskb_may_pull() in ila_csum_adjust_transport() +before the csum-diff read. In ila_update_ipv6_locator() only the +ILA_CSUM_ADJUST_TRANSPORT case pulls the skb, so reload ip6h and iaddr in +that case alone before the destination-address write; the neutral-map +modes never pull and keep their cached pointers. + +Fixes: 33f11d16142b ("ila: Create net/ipv6/ila directory") +Cc: stable@vger.kernel.org +Signed-off-by: Michael Bommarito +Reviewed-by: Simon Horman +Reviewed-by: Antoine Tenart +Link: https://patch.msgid.link/20260714114903.3763420-1-michael.bommarito@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ila/ila_common.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/net/ipv6/ila/ila_common.c ++++ b/net/ipv6/ila/ila_common.c +@@ -84,6 +84,7 @@ static void ila_csum_adjust_transport(st + struct tcphdr *th = (struct tcphdr *) + (skb_network_header(skb) + nhoff); + ++ ip6h = ipv6_hdr(skb); + diff = get_csum_diff(ip6h, p); + inet_proto_csum_replace_by_diff(&th->check, skb, + diff, true, true); +@@ -95,6 +96,7 @@ static void ila_csum_adjust_transport(st + (skb_network_header(skb) + nhoff); + + if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) { ++ ip6h = ipv6_hdr(skb); + diff = get_csum_diff(ip6h, p); + inet_proto_csum_replace_by_diff(&uh->check, skb, + diff, true, true); +@@ -109,6 +111,7 @@ static void ila_csum_adjust_transport(st + struct icmp6hdr *ih = (struct icmp6hdr *) + (skb_network_header(skb) + nhoff); + ++ ip6h = ipv6_hdr(skb); + diff = get_csum_diff(ip6h, p); + inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb, + diff, true, true); +@@ -126,6 +129,15 @@ void ila_update_ipv6_locator(struct sk_b + switch (p->csum_mode) { + case ILA_CSUM_ADJUST_TRANSPORT: + ila_csum_adjust_transport(skb, p); ++ /* ++ * ila_csum_adjust_transport() calls pskb_may_pull(), which can ++ * reallocate the skb head and leave ip6h (and the iaddr derived ++ * from it) dangling; reload both before the write below. The ++ * other csum modes do not pull, so their cached pointers stay ++ * valid. ++ */ ++ ip6h = ipv6_hdr(skb); ++ iaddr = ila_a2i(&ip6h->daddr); + break; + case ILA_CSUM_NEUTRAL_MAP: + if (sir2ila) { diff --git a/queue-6.6/mac802154-hold-an-interface-reference-across-the-scan-worker.patch b/queue-6.6/mac802154-hold-an-interface-reference-across-the-scan-worker.patch new file mode 100644 index 0000000000..498fe030c5 --- /dev/null +++ b/queue-6.6/mac802154-hold-an-interface-reference-across-the-scan-worker.patch @@ -0,0 +1,78 @@ +From 234e5e898b713bc0b3a631b6f002897f43d046c8 Mon Sep 17 00:00:00 2001 +From: Ibrahim Hashimov +Date: Tue, 21 Jul 2026 23:12:28 +0200 +Subject: mac802154: hold an interface reference across the scan worker + +From: Ibrahim Hashimov + +commit 234e5e898b713bc0b3a631b6f002897f43d046c8 upstream. + +mac802154_scan_worker() captures the scanning sub-interface under RCU +and then keeps dereferencing sdata->dev after rcu_read_unlock() and +outside the rtnl -- in the failure traces, in +mac802154_transmit_beacon_req() (skb->dev = sdata->dev), and in the +end_scan cleanup. Nothing keeps that netdev alive across the worker +iteration. + +A concurrent DEL_INTERFACE or PHY removal can unregister the interface +once the worker drops the rtnl between its two drv_set_channel() +sections. unregister_netdevice() frees the netdev asynchronously from +netdev_run_todo() with the rtnl already dropped, so neither holding the +rtnl nor the per-PHY IEEE802154_IS_SCANNING flag prevents a stale worker +iteration from dereferencing the freed netdev -- a KASAN +slab-use-after-free, reachable by racing TRIGGER_SCAN against +DEL_INTERFACE (both CAP_NET_ADMIN). + +Pin the netdev with netdev_hold() while the RCU read lock is still held, +and release it at every worker exit. + +Fixes: 57588c71177f ("mac802154: Handle passive scanning") +Cc: stable@vger.kernel.org +Signed-off-by: Ibrahim Hashimov +Link: https://patch.msgid.link/20260721211228.34578-1-security@auditcode.ai +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/mac802154/scan.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/net/mac802154/scan.c ++++ b/net/mac802154/scan.c +@@ -179,6 +179,7 @@ void mac802154_scan_worker(struct work_s + enum nl802154_scan_types scan_req_type; + struct ieee802154_sub_if_data *sdata; + unsigned int scan_duration = 0; ++ netdevice_tracker dev_tracker; + struct wpan_phy *wpan_phy; + u8 scan_req_duration; + u8 page, channel; +@@ -209,6 +210,14 @@ void mac802154_scan_worker(struct work_s + return; + } + ++ /* ++ * sdata->dev is dereferenced below after rcu_read_unlock() and outside ++ * the rtnl, and a concurrent DEL_INTERFACE / PHY teardown can free it ++ * asynchronously from netdev_run_todo(). Pin it with a reference taken ++ * while the RCU read lock is still held, and drop it at every exit. ++ */ ++ netdev_hold(sdata->dev, &dev_tracker, GFP_ATOMIC); ++ + wpan_phy = scan_req->wpan_phy; + scan_req_type = scan_req->type; + scan_req_duration = scan_req->duration; +@@ -262,12 +271,14 @@ void mac802154_scan_worker(struct work_s + "Scan page %u channel %u for %ums\n", + page, channel, jiffies_to_msecs(scan_duration)); + queue_delayed_work(local->mac_wq, &local->scan_work, scan_duration); ++ netdev_put(sdata->dev, &dev_tracker); + return; + + end_scan: + rtnl_lock(); + mac802154_scan_cleanup_locked(local, sdata, false); + rtnl_unlock(); ++ netdev_put(sdata->dev, &dev_tracker); + } + + int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata, diff --git a/queue-6.6/mac802154-llsec-reject-frames-shorter-than-the-authentication-tag.patch b/queue-6.6/mac802154-llsec-reject-frames-shorter-than-the-authentication-tag.patch new file mode 100644 index 0000000000..efb11839a3 --- /dev/null +++ b/queue-6.6/mac802154-llsec-reject-frames-shorter-than-the-authentication-tag.patch @@ -0,0 +1,55 @@ +From fd3a3f28ed60c6af4b2a39933b151d6b27842c3b Mon Sep 17 00:00:00 2001 +From: Doruk Tan Ozturk +Date: Thu, 16 Jul 2026 21:34:23 +0200 +Subject: mac802154: llsec: reject frames shorter than the authentication tag + +From: Doruk Tan Ozturk + +commit fd3a3f28ed60c6af4b2a39933b151d6b27842c3b upstream. + +llsec_do_decrypt_auth() computes the associated-data length for the +AEAD request as + + assoclen += datalen - authlen; + +where datalen is the number of bytes after the MAC header and authlen +(4, 8 or 16) is the length of the authentication tag. Nothing verifies +that the frame actually carries at least authlen payload bytes. A +secured frame whose payload is shorter than the tag makes +datalen - authlen negative; assoclen is then passed to +aead_request_set_ad() as an unsigned value close to 4 GiB, so +crypto_aead_decrypt() walks far off the end of the scatterlist that +only spans the real frame. + +The frame is fully attacker-controlled and reaches this path from any +IEEE 802.15.4 peer in radio range. Reject frames whose payload is +shorter than the authentication tag before the subtraction. + +Dynamically reproduced on a KASAN kernel as a general-protection-fault +in the AEAD scatterwalk, and the fix confirmed. + +Fixes: 4c14a2fb5d14 ("mac802154: add llsec decryption method") +Cc: stable@vger.kernel.org +Reviewed-by: Simon Horman +Signed-off-by: Doruk Tan Ozturk +Link: https://patch.msgid.link/20260716193423.32498-1-doruk@0sec.ai +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/mac802154/llsec.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/mac802154/llsec.c ++++ b/net/mac802154/llsec.c +@@ -891,6 +891,11 @@ llsec_do_decrypt_auth(struct sk_buff *sk + data = skb_mac_header(skb) + skb->mac_len; + datalen = skb_tail_pointer(skb) - data; + ++ if (datalen < authlen) { ++ kfree_sensitive(req); ++ return -EBADMSG; ++ } ++ + sg_init_one(&sg, skb_mac_header(skb), assoclen + datalen); + + if (!(hdr->sec.level & IEEE802154_SCF_SECLEVEL_ENC)) { diff --git a/queue-6.6/mctp-serial-handle-zero-length-frames-to-prevent-rx-buffer-overflow.patch b/queue-6.6/mctp-serial-handle-zero-length-frames-to-prevent-rx-buffer-overflow.patch new file mode 100644 index 0000000000..14a2225949 --- /dev/null +++ b/queue-6.6/mctp-serial-handle-zero-length-frames-to-prevent-rx-buffer-overflow.patch @@ -0,0 +1,93 @@ +From 793b9b729f1e8de57be8c8daf1a9838be96cabed Mon Sep 17 00:00:00 2001 +From: Doruk Tan Ozturk +Date: Wed, 15 Jul 2026 10:20:21 +0200 +Subject: mctp: serial: handle zero-length frames to prevent rx buffer overflow + +From: Doruk Tan Ozturk + +commit 793b9b729f1e8de57be8c8daf1a9838be96cabed upstream. + +The MCTP serial receive state machine reads a frame length byte in +mctp_serial_push_header() case 2 and validates it upper-bound-only: + + if (c > MCTP_SERIAL_FRAME_MTU) { + dev->rxstate = STATE_ERR; + } else { + dev->rxlen = c; + dev->rxpos = 0; + dev->rxstate = STATE_DATA; + ... + } + +A length of zero passes this check, so rxlen is set to 0 and the state +machine advances to STATE_DATA. In mctp_serial_push() STATE_DATA, the +incoming byte is stored and rxpos incremented before the terminator is +tested: + + dev->rxbuf[dev->rxpos] = c; + dev->rxpos++; + dev->rxstate = STATE_DATA; + if (dev->rxpos == dev->rxlen) { + dev->rxpos = 0; + dev->rxstate = STATE_TRAILER; + } + +With rxlen == 0 the "rxpos == rxlen" terminator can never fire (rxpos is +already 1 on the first data byte), so subsequent bytes are written past +the end of the fixed 74-byte rxbuf, which is the last member of the +netdev private area. Every following data byte is an attacker-controlled +1-byte out-of-bounds heap write, and the overflow continues until a +frame (0x7e) or escape byte resets the parser -- effectively unbounded. + +Reaching this requires CAP_NET_ADMIN to attach the N_MCTP line +discipline and bring the resulting mctpserialN netdev up, after which +the bytes arrive via the tty receive path. + +Route a zero-length frame straight to STATE_TRAILER instead of +STATE_DATA. The trailer/framing bytes are still consumed, and the frame +resolves to a zero-length skb that the MCTP core rejects; the parser +never enters STATE_DATA with rxlen == 0, so the out-of-bounds write can +no longer occur. + +KASAN, on a frame of 0x7e 0x01 0x00 followed by data bytes (before this +change): + + UBSAN: array-index-out-of-bounds in drivers/net/mctp/mctp-serial.c:370 + index 74 is out of range for type 'u8 [74]' + BUG: KASAN: slab-out-of-bounds in mctp_serial_tty_receive_buf + Write of size 1 at addr ... by task kworker/u16:0 + mctp_serial_tty_receive_buf + tty_ldisc_receive_buf + flush_to_ldisc + Allocated by task 152: + alloc_netdev_mqs + mctp_serial_open + +v2: route zero-length frames to STATE_TRAILER instead of STATE_ERR so + the trailer/framing bytes are still consumed (Jeremy Kerr). + +Found by 0sec automated security-research tooling (https://0sec.ai). +Fixes: a0c2ccd9b5ad ("mctp: Add MCTP-over-serial transport binding") +Cc: stable@vger.kernel.org +Suggested-by: Jeremy Kerr +Assisted-by: 0sec:multi-model +Signed-off-by: Doruk Tan Ozturk +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260715082021.46315-1-doruk@0sec.ai +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/mctp/mctp-serial.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/mctp/mctp-serial.c ++++ b/drivers/net/mctp/mctp-serial.c +@@ -316,7 +316,7 @@ static void mctp_serial_push_header(stru + } else { + dev->rxlen = c; + dev->rxpos = 0; +- dev->rxstate = STATE_DATA; ++ dev->rxstate = c > 0 ? STATE_DATA : STATE_TRAILER; + dev->rxfcs = crc_ccitt_byte(dev->rxfcs, c); + } + break; diff --git a/queue-6.6/pppoe-reload-header-pointer-after-dev_hard_header.patch b/queue-6.6/pppoe-reload-header-pointer-after-dev_hard_header.patch new file mode 100644 index 0000000000..0bb9dff988 --- /dev/null +++ b/queue-6.6/pppoe-reload-header-pointer-after-dev_hard_header.patch @@ -0,0 +1,44 @@ +From e9c238f6fe42fb1b4dba3a578277de32cb487937 Mon Sep 17 00:00:00 2001 +From: Asim Viladi Oglu Manizada +Date: Wed, 22 Jul 2026 09:38:43 +0000 +Subject: pppoe: reload header pointer after dev_hard_header() + +From: Asim Viladi Oglu Manizada + +commit e9c238f6fe42fb1b4dba3a578277de32cb487937 upstream. + +pppoe_sendmsg() saves a pointer to the PPPoE header before calling +dev_hard_header(). Device header callbacks are allowed to reallocate the +skb head, invalidating pointers into it. + +This can happen when a send is blocked in copy_from_user() while the first +non-Ethernet port is added to an empty team device. The team's delegated +GRE header callback then expands the skb head. PPPoE subsequently writes +six bytes through the stale pointer into the freed head. + +Reload the PPPoE header through the skb's network-header offset after +device header creation. pskb_expand_head() updates that offset when it +relocates the head. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Signed-off-by: Asim Viladi Oglu Manizada +Reviewed-by: Vadim Fedorenko +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20260722093814.3017176-1-manizada@pm.me +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ppp/pppoe.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -900,6 +900,7 @@ static int pppoe_sendmsg(struct socket * + dev_hard_header(skb, dev, ETH_P_PPP_SES, + po->pppoe_pa.remote, NULL, total_len); + ++ ph = pppoe_hdr(skb); + memcpy(ph, &hdr, sizeof(struct pppoe_hdr)); + + ph->length = htons(total_len); diff --git a/queue-6.6/series b/queue-6.6/series index df3d79cb9f..20ea501d32 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -328,3 +328,11 @@ proc-fix-broken-error-paths-for-namespace-links.patch selftests-ftrace-reset-triggers-at-top-level-before-instance-loop.patch rbd-reset-positive-result-codes-to-zero-in-object-map-update-path.patch ksmbd-defer-destroy_previous_session-until-after-ntlm-authentication.patch +ice-use-read_once-to-access-cached-phc-time.patch +ila-reload-ipv6-header-after-pskb_may_pull-in-checksum-adjust.patch +mac802154-hold-an-interface-reference-across-the-scan-worker.patch +mac802154-llsec-reject-frames-shorter-than-the-authentication-tag.patch +mctp-serial-handle-zero-length-frames-to-prevent-rx-buffer-overflow.patch +pppoe-reload-header-pointer-after-dev_hard_header.patch +tipc-clear-sock-sk-on-the-failed-insert-path-in-tipc_sk_create.patch +vxlan-mdb-fix-source-list-corruption-on-a-failed-replace.patch diff --git a/queue-6.6/tipc-clear-sock-sk-on-the-failed-insert-path-in-tipc_sk_create.patch b/queue-6.6/tipc-clear-sock-sk-on-the-failed-insert-path-in-tipc_sk_create.patch new file mode 100644 index 0000000000..bf27e3de57 --- /dev/null +++ b/queue-6.6/tipc-clear-sock-sk-on-the-failed-insert-path-in-tipc_sk_create.patch @@ -0,0 +1,82 @@ +From ba0533fc163f905fe817cfabdf8ed4058da44800 Mon Sep 17 00:00:00 2001 +From: Daehyeon Ko <4ncienth@gmail.com> +Date: Tue, 14 Jul 2026 22:19:39 +0900 +Subject: tipc: clear sock->sk on the failed-insert path in tipc_sk_create() + +From: Daehyeon Ko <4ncienth@gmail.com> + +commit ba0533fc163f905fe817cfabdf8ed4058da44800 upstream. + +When tipc_sk_create() fails to insert the new socket (tipc_sk_insert() +returns non-zero), its error path frees the sk with sk_free() but leaves +sock->sk pointing at the freed object: + + if (tipc_sk_insert(tsk)) { + sk_free(sk); + pr_warn("Socket create failed; port number exhausted\n"); + return -EINVAL; + } + +This is harmless for plain socket(): the syscall layer clears sock->ops +before releasing, so tipc_release() is never called. It is not harmless +on the accept() path. tipc_accept() creates the pre-allocated child +socket with tipc_sk_create(net, new_sock, 0, kern); on failure it leaves +new_sock->sk dangling and new_sock->ops non-NULL, and do_accept() then +fput()s the new file, so __sock_release() -> tipc_release() runs +lock_sock(new_sock->sk) on the freed sk -- a use-after-free write of the +sk_lock spinlock. + +tipc_release() already guards this exact "failed accept() releases a +pre-allocated child" case with "if (sk == NULL) return 0;", but the +guard is bypassed because tipc_sk_create() left sock->sk non-NULL +(dangling) rather than NULL. + +Clear sock->sk on the failed-insert path so the existing tipc_release() +NULL check fires and the use-after-free is avoided. + +The tipc_sk_insert() failure is reached when the per-netns socket +rhashtable hits its max_size (tsk_rht_params.max_size = 1048576, ~2M +elements) -- i.e. once a netns holds ~2M TIPC sockets every insert +returns -E2BIG. + + BUG: KASAN: slab-use-after-free in lock_sock_nested (net/core/sock.c:3839) + Write of size 8 at addr ffff8880047cdc38 by task init/1 + lock_sock_nested (net/core/sock.c:3839) + tipc_release (net/tipc/socket.c:638) + __sock_release (net/socket.c:710) + sock_close (net/socket.c:1501) + __fput (fs/file_table.c:512) + Allocated by task 1: + sk_alloc (net/core/sock.c:2308) + tipc_sk_create (net/tipc/socket.c:487) + tipc_accept (net/tipc/socket.c:2744) + do_accept (net/socket.c:2034) + Freed by task 1: + __sk_destruct (net/core/sock.c:2391) + tipc_sk_create (net/tipc/socket.c:504) + tipc_accept (net/tipc/socket.c:2744) + do_accept (net/socket.c:2034) + +Fixes: 00aff3590fc0 ("net: tipc: fix possible refcount leak in tipc_sk_create()") +Cc: stable@vger.kernel.org +Reviewed-by: Tung Nguyen +Reviewed-by: Breno Leitao +Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260714131939.1255974-1-4ncienth@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/socket.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -504,6 +504,7 @@ static int tipc_sk_create(struct net *ne + tipc_set_sk_state(sk, TIPC_OPEN); + if (tipc_sk_insert(tsk)) { + sk_free(sk); ++ sock->sk = NULL; + pr_warn("Socket create failed; port number exhausted\n"); + return -EINVAL; + } diff --git a/queue-6.6/vxlan-mdb-fix-source-list-corruption-on-a-failed-replace.patch b/queue-6.6/vxlan-mdb-fix-source-list-corruption-on-a-failed-replace.patch new file mode 100644 index 0000000000..a25538fef7 --- /dev/null +++ b/queue-6.6/vxlan-mdb-fix-source-list-corruption-on-a-failed-replace.patch @@ -0,0 +1,131 @@ +From dcd9b465965422b9654f6026e8a2fa8984f74c3c Mon Sep 17 00:00:00 2001 +From: James Raphael Tiovalen +Date: Tue, 21 Jul 2026 00:04:24 +0800 +Subject: vxlan: mdb: Fix source list corruption on a failed replace + +From: James Raphael Tiovalen + +commit dcd9b465965422b9654f6026e8a2fa8984f74c3c upstream. + +When replacing the source list of an MDB remote entry, all existing +sources are first marked for deletion and vxlan_mdb_remote_srcs_add() +is then called to add the new source list. Sources present in the new +list have their deletion mark cleared, and any sources left marked +afterwards are removed. + +If vxlan_mdb_remote_srcs_add() fails partway through, its error path +deletes all entries on the remote's source list. That rollback is only +correct for its other caller, vxlan_mdb_remote_add(), where the remote +was just allocated and the list contains solely entries added during +the call. On the replace path the list also holds pre-existing sources, +so a failed replace tears them down together with their (S, G) +forwarding entries instead of leaving the entry unchanged. + +This is reachable from an existing (*, G) remote. An EXCLUDE filter +that loses sources starts forwarding traffic that should be blocked, +while an INCLUDE filter that loses sources drops traffic that should be +forwarded. + +Mark entries created during the current pass with a new +VXLAN_SGRP_F_NEW flag. On failure, delete only those entries and clear +the deletion mark on the pre-existing ones, so a failed replace leaves +the source list untouched. Retain the flag until the whole operation +succeeds and then clear it. Also stop vxlan_mdb_remote_src_add() from +deleting a pre-existing entry it only looked up when adding that +entry's forwarding entry fails. + +Fixes: a3a48de5eade ("vxlan: mdb: Add MDB control path support") +Cc: stable@vger.kernel.org +Signed-off-by: James Raphael Tiovalen +Reviewed-by: Ido Schimmel +Reviewed-by: Antoine Tenart +Reviewed-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20260720160428.249356-1-jamestiotio@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan/vxlan_mdb.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +--- a/drivers/net/vxlan/vxlan_mdb.c ++++ b/drivers/net/vxlan/vxlan_mdb.c +@@ -42,6 +42,7 @@ struct vxlan_mdb_remote { + }; + + #define VXLAN_SGRP_F_DELETE BIT(0) ++#define VXLAN_SGRP_F_NEW BIT(1) + + struct vxlan_mdb_src_entry { + struct hlist_node node; +@@ -838,6 +839,7 @@ vxlan_mdb_remote_src_add(const struct vx + ent = vxlan_mdb_remote_src_entry_add(remote, &src->addr); + if (!ent) + return -ENOMEM; ++ ent->flags |= VXLAN_SGRP_F_NEW; + } else if (!(cfg->nlflags & NLM_F_REPLACE)) { + NL_SET_ERR_MSG_MOD(extack, "Source entry already exists"); + return -EEXIST; +@@ -847,15 +849,16 @@ vxlan_mdb_remote_src_add(const struct vx + if (err) + goto err_src_del; + +- /* Clear flags in case source entry was marked for deletion as part of +- * replace flow. ++ /* Clear the deletion mark so the entry survives the replace sweep. ++ * The new mark is retained until the whole operation succeeds. + */ +- ent->flags = 0; ++ ent->flags &= ~VXLAN_SGRP_F_DELETE; + + return 0; + + err_src_del: +- vxlan_mdb_remote_src_entry_del(ent); ++ if (ent->flags & VXLAN_SGRP_F_NEW) ++ vxlan_mdb_remote_src_entry_del(ent); + return err; + } + +@@ -883,11 +886,19 @@ static int vxlan_mdb_remote_srcs_add(con + goto err_src_del; + } + ++ hlist_for_each_entry(ent, &remote->src_list, node) ++ ent->flags &= ~VXLAN_SGRP_F_NEW; ++ + return 0; + + err_src_del: +- hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node) +- vxlan_mdb_remote_src_del(cfg->vxlan, &cfg->group, remote, ent); ++ hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node) { ++ if (ent->flags & VXLAN_SGRP_F_NEW) ++ vxlan_mdb_remote_src_del(cfg->vxlan, &cfg->group, remote, ++ ent); ++ else ++ ent->flags &= ~VXLAN_SGRP_F_DELETE; ++ } + return err; + } + +@@ -1053,7 +1064,7 @@ vxlan_mdb_remote_srcs_replace(const stru + + err = vxlan_mdb_remote_srcs_add(cfg, remote, extack); + if (err) +- goto err_clear_delete; ++ return err; + + hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node) { + if (ent->flags & VXLAN_SGRP_F_DELETE) +@@ -1062,11 +1073,6 @@ vxlan_mdb_remote_srcs_replace(const stru + } + + return 0; +- +-err_clear_delete: +- hlist_for_each_entry(ent, &remote->src_list, node) +- ent->flags &= ~VXLAN_SGRP_F_DELETE; +- return err; + } + + static int vxlan_mdb_remote_replace(const struct vxlan_mdb_config *cfg,