6.12.111-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 390/1102 wifi: rsi: avoid reading TKIP MIC keys for non-TKIP ciphers
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit 843fe9bc583b7686ca68312ac9319c9240a73c03 ]
rsi_hal_load_key() copies tx_mic_key and rx_mic_key from data[16] and data[24] whenever key data is present. Those offsets are only part of the 32-byte TKIP key layout. Shorter keys used by other ciphers, such as CCMP, do not provide those bytes, so the unconditional copies can read past the supplied key buffer.
Only copy the MIC keys for TKIP, and reject malformed TKIP keys that are shorter than the expected 32-byte layout.
--- drivers/net/wireless/rsi/rsi_91x_mgmt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/wireless/rsi/rsi_91x_mgmt.c +4 -2
@@ -848,8 +848,10 @@ int rsi_hal_load_key(struct rsi_common *common, }else {memcpy (&set_key->key[0 ][0 ], data, key_len); } -memcpy (set_key->tx_mic_key, &data[16 ],8 ); -memcpy (set_key->rx_mic_key, &data[24 ],8 ); +if (cipher ==WLAN_CIPHER_SUITE_TKIP ) { +memcpy (set_key->tx_mic_key, &data[16 ],8 ); +memcpy (set_key->rx_mic_key, &data[24 ],8 ); + } }else {memset (&set_key[FRAME_DESC_SZ ],0 , frame_len -FRAME_DESC_SZ ); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 391/1102 wifi: libertas: reject short monitor TX frames
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit 13ff543e0b2c713aedeaadadde686686e949dc78 ]
In monitor mode, lbs_hard_start_xmit() casts skb->data to a radiotap TX header, skips that header, and then copies the 802.11 destination address from offset 4 in the remaining frame. The generic length check only rejects zero-length and oversized skbs, so a short monitor frame can be read past the end of the skb data.
Require enough bytes for the radiotap TX header and the destination address field before using the monitor-mode header layout.
--- drivers/net/wireless/marvell/libertas/tx.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/wireless/marvell/libertas/tx.c +7 -0
@@ -117,6 +117,13 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)if (priv->wdev->iftype ==NL80211_IFTYPE_MONITOR ) {struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data; +if (skb->len <sizeof (*rtap_hdr) +4 +ETH_ALEN ) { +lbs_deb_tx ("tx err: short monitor frame %u\n" , skb->len); + dev->stats.tx_dropped++; + dev->stats.tx_errors++; + goto free; + } +/* set txpd fields from the radiotap header */ txpd->tx_control =cpu_to_le32 (convert_radiotap_rate_to_mv (rtap_hdr->rate));
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 392/1102 wifi: cfg80211: validate assoc response length before status and IE access
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit b760113aeca2e9362d56bf9e9263373ffe6c8eb3 ]
cfg80211_rx_assoc_resp() initialises the status and response-IE fields of cfg80211_connect_resp_params from the management frame before proving that the frame is long enough for those offsets. S1G and regular association responses also have different IE offsets, but the S1G path only patched resp_ie after the unsafe initialiser had already run.
Defer resp_ie, resp_ie_len, and status to after the link-iteration loop. Use a bool to remember whether the frame is S1G, then validate the appropriate minimum length and set all three fields in a single if/else block. Funnel short-frame and SME-reject cleanup through a shared free_bss label for the abandon paths.
--- net/wireless/mlme.c | 56 ++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-)
net/wireless/mlme.c +35 -21
@@ -32,14 +32,10 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, .timeout_reason = NL80211_TIMEOUT_UNSPECIFIED, .req_ie = data->req_ies, .req_ie_len = data->req_ies_len, - .resp_ie = mgmt->u.assoc_resp.variable, - .resp_ie_len = data->len - - offsetof(struct ieee80211_mgmt , - u.assoc_resp.variable), - .status = le16_to_cpu(mgmt->u.assoc_resp.status_code), .ap_mld_addr = data->ap_mld_addr, };unsigned int link_id; +bool is_s1g = false;for (link_id =0 ; link_id <ARRAY_SIZE (data->links); link_id++) { cr.links[link_id].status = data->links[link_id].status;
@@ -60,16 +56,32 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,if (cr.links[link_id].bss->channel->band ==NL80211_BAND_S1GHZ ) {WARN_ON (link_id); - cr.resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable; - cr.resp_ie_len = data->len - - offsetof(struct ieee80211_mgmt , - u.s1g_assoc_resp.variable); + is_s1g = true; }if (cr.ap_mld_addr) cr.valid_links |=BIT (link_id); } +if (is_s1g) { +if (data->len < offsetof(struct ieee80211_mgmt , + u.s1g_assoc_resp.variable)) + goto free_bss; + cr.resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable; + cr.resp_ie_len = data->len - + offsetof(struct ieee80211_mgmt , + u.s1g_assoc_resp.variable); + }else { +if (data->len < offsetof(struct ieee80211_mgmt , + u.assoc_resp.variable)) + goto free_bss; + cr.resp_ie = mgmt->u.assoc_resp.variable; + cr.resp_ie_len = data->len - + offsetof(struct ieee80211_mgmt , + u.assoc_resp.variable); + } + cr.status =le16_to_cpu (mgmt->u.assoc_resp.status_code); +trace_cfg80211_send_rx_assoc (dev, data);/*
@@ -78,22 +90,24 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,* and got a reject -- we only try again with an assoc * frame instead of reassoc. */ -if (cfg80211_sme_rx_assoc_resp (wdev, cr.status)) { -for (link_id =0 ; link_id <ARRAY_SIZE (data->links); link_id++) { -struct cfg80211_bss *bss = data->links[link_id].bss; - -if (!bss) -continue ; - -cfg80211_unhold_bss (bss_from_pub (bss)); -cfg80211_put_bss (wiphy, bss); - } -return ; - } +if (cfg80211_sme_rx_assoc_resp (wdev, cr.status)) + goto free_bss;nl80211_send_rx_assoc (rdev, dev, data);/* update current_bss etc., consumes the bss reference */ __cfg80211_connect_result (dev, &cr, cr.status ==WLAN_STATUS_SUCCESS ); +return ; + +free_bss: +for (link_id =0 ; link_id <ARRAY_SIZE (data->links); link_id++) { +struct cfg80211_bss *bss = data->links[link_id].bss; + +if (!bss) +continue ; + +cfg80211_unhold_bss (bss_from_pub (bss)); +cfg80211_put_bss (wiphy, bss); + } }EXPORT_SYMBOL (cfg80211_rx_assoc_resp);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 393/1102 ksmbd: find bound sessions during reauthentication
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit faf8578c77f3d846aca9cd882c293e03eafcc6df ]
A session bound to an additional connection is stored in the session channel list, but it is not added to that connection's local session table. After the binding exchange completes, conn->binding is cleared.
A later SESSION_SETUP reauthentication on the bound channel only searches the local session table. It fails to find the session and returns STATUS_USER_SESSION_DELETED instead of processing authentication and returning STATUS_LOGON_FAILURE for invalid credentials.
If the local lookup fails, look up the session globally and accept it only when the current connection is registered in its channel list. This keeps unbound connections from using the session while allowing reauthentication on an established channel.
This fixes smb2.session.bind_invalid_auth.
--- fs/smb/server/smb2pdu.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/smb/server/smb2pdu.c +7 -0
@@ -1804,6 +1804,13 @@ int smb2_sess_setup(struct ksmbd_work *work) }else { sess =ksmbd_session_lookup (conn,le64_to_cpu (req->hdr.SessionId)); +if (!sess) { + sess =ksmbd_session_lookup_slowpath (le64_to_cpu (req->hdr.SessionId)); +if (sess && !lookup_chann_list (sess, conn)) { +ksmbd_user_session_put (sess); + sess =NULL ; + } + }if (!sess) { rc = -ENOENT ; goto out_err;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 394/1102 ksmbd: mark invalid session responses as signed
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit 9e8ad620ddfde5a5f4ef58372e3805e9388cb0f4 ]
When a signed request uses a session that is not registered on the connection, ksmbd returns STATUS_USER_SESSION_DELETED before reaching the normal response signing path. The response therefore lacks SMB2_FLAGS_SIGNED.
Clients that require signing check this flag before handling STATUS_USER_SESSION_DELETED and replace the server status with STATUS_ACCESS_DENIED when it is absent. The protocol permits this error response to skip signature verification because the connection has no matching session key.
Preserve SMB2_FLAGS_SIGNED on the early error response when the request was signed. This lets the client propagate STATUS_USER_SESSION_DELETED. It fixes smb2.session.bind2.
--- fs/smb/server/server.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/smb/server/server.c +6 -0
@@ -197,6 +197,12 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,else conn->ops->set_rsp_status (work,STATUS_USER_SESSION_DELETED ); +if (conn->ops->is_sign_req (work, conn->ops->get_cmd_val (work))) { +struct smb2_hdr *rsp_hdr; + + rsp_hdr =ksmbd_resp_buf_curr (work); + rsp_hdr->Flags |=SMB2_FLAGS_SIGNED ; + } goto send; }else if (rc >0 ) { rc = conn->ops->get_ksmbd_tcon (work);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 395/1102 ksmbd: validate SID namespace before mapping IDs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit fbe0bb2b75eb3c61e8464486506253d1b471240b ]
sid_to_id() currently treats the last subauthority of any owner or group SID as a Unix uid or gid. For example, this maps Everyone (S-1-1-0) to uid 0 and BUILTIN\Users (S-1-5-32-545) to gid 545.
When an SMB2 CREATE security descriptor contains those SIDs, ksmbd attempts to change the newly created file to the bogus Unix ownership. notify_change() then returns -EPERM, which makes smb2.create.aclfile fail with NT_STATUS_SHARING_VIOLATION.
Validate the SID prefix before extracting its RID. Only server-domain owner SIDs and S-1-22-2 Unix group SIDs have local ID representations. Treat other valid Windows SIDs as unmapped so their original values can still be preserved in the NT ACL xattr.
--- fs/smb/server/smbacl.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
fs/smb/server/smbacl.c +17 -4
@@ -258,6 +258,7 @@ static int sid_to_id(struct mnt_idmap *idmap, struct smb_sid *psid, uint sidtype, struct smb_fattr *fattr) { + const struct smb_sid *sid_prefix;int rc = -EINVAL ;/*
@@ -279,6 +280,12 @@ static int sid_to_id(struct mnt_idmap *idmap,kuid_t uid;uid_t id; +/* Only the server domain RID has a local uid representation. */ + sid_prefix = &server_conf.domain_sid; +if (psid->num_subauth != sid_prefix->num_subauth +1 || +compare_sids (psid, sid_prefix)) +return -EINVAL ; + id =le32_to_cpu (psid->sub_auth[psid->num_subauth -1 ]); uid =KUIDT_INIT (id); uid =from_vfsuid (idmap, &init_user_ns,VFSUIDT_INIT (uid));
@@ -290,6 +297,12 @@ static int sid_to_id(struct mnt_idmap *idmap,kgid_t gid;gid_t id; +/* Local gids are represented by S-1-22-2-<gid>. */ + sid_prefix = &sid_unix_groups; +if (psid->num_subauth != sid_prefix->num_subauth +1 || +compare_sids (psid, sid_prefix)) +return -EINVAL ; + id =le32_to_cpu (psid->sub_auth[psid->num_subauth -1 ]); gid =KGIDT_INIT (id); gid =from_vfsgid (idmap, &init_user_ns,VFSGIDT_INIT (gid));
@@ -916,9 +929,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd, rc =sid_to_id (idmap, owner_sid_ptr,SIDOWNER , fattr);if (rc) { -pr_err ("%s: Error %d mapping Owner SID to uid\n" , - __func__, rc); +ksmbd_debug (SMB ,"Owner SID has no Unix uid mapping\n" ); owner_sid_ptr =NULL ; + rc =0 ; } }
@@ -934,9 +947,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd, } rc =sid_to_id (idmap, group_sid_ptr,SIDUNIX_GROUP , fattr);if (rc) { -pr_err ("%s: Error %d mapping Group SID to gid\n" , - __func__, rc); +ksmbd_debug (SMB ,"Group SID has no Unix gid mapping\n" ); group_sid_ptr =NULL ; + rc =0 ; } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 396/1102 wifi: cfg80211: validate rx/tx MLME callback frame lengths before access
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit d5e4586546974179feca305a94e07fac3e9727fe ]
cfg80211_rx_mlme_mgmt() and cfg80211_tx_mlme_mgmt() call tracepoints before rejecting frames shorter than the frame-control field. After that, they only require len >= 2 before dispatching into subtype handlers that assume their fixed fields are present.
The frames that trip this are not shorter than 2 bytes; they are short relative to their subtype. mwifiex is a concrete in-tree example on the length side: mwifiex_process_mgmt_packet() only requires a 4-address ieee80211_hdr plus the 2-byte firmware length prefix before handing the frame to cfg80211_rx_mlme_mgmt(). After stripping the length prefix and removing addr4, pkt_len can be exactly 24: a bare 3-address management header with no reason-code body. The existing WARN_ON(len < 2) does not fire on such a frame, and cfg80211_process_deauth() then reads u.deauth.reason_code as a two-byte access starting at offset 24, immediately past the 24-byte buffer.
Add a frame-control length gate, then validate each subtype's minimum frame size in an if/else-if chain that mirrors the dispatch logic. Trace only after the frame is known to be well-formed.
Side effects of this change:
- The WARN_ON(len < 2) is dropped. It only guarded the frame_control read, never the subtype fixed fields, and it does not fire on the frames that actually trigger the out-of-bounds read (which are >= 2). The len >= 2 check is kept as the guard before dereferencing frame_control, but without the warning: these are exported callbacks and a malformed frame from a driver should be dropped silently rather than backtraced.
- cfg80211_tx_mlme_mgmt() previously routed every non-deauth subtype through disassociation handling; it now silently ignores unrecognised subtypes.
--- net/wireless/mlme.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-)
net/wireless/mlme.c +37 -8
@@ -164,19 +164,35 @@ void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len) {struct wireless_dev *wdev = dev->ieee80211_ptr;struct ieee80211_mgmt *mgmt = (void *)buf; +__le16 fc;lockdep_assert_wiphy (wdev->wiphy); -trace_cfg80211_rx_mlme_mgmt (dev, buf, len); +if (len <sizeof (fc)) +return ; + + fc = mgmt->frame_control; -if (WARN_ON (len <2 )) +if (ieee80211_is_auth (fc)) { + if (len < offsetofend(struct ieee80211_mgmt, u.auth.status_code)) +return ; + }else if (ieee80211_is_deauth (fc)) { + if (len < offsetofend(struct ieee80211_mgmt, u.deauth.reason_code)) +return ; + }else if (ieee80211_is_disassoc (fc)) { + if (len < offsetofend(struct ieee80211_mgmt, u.disassoc.reason_code)) +return ; + }else {return ; + } + +trace_cfg80211_rx_mlme_mgmt (dev, buf, len); -if (ieee80211_is_auth (mgmt->frame_control)) +if (ieee80211_is_auth (fc))cfg80211_process_auth (wdev, buf, len); -else if (ieee80211_is_deauth (mgmt->frame_control)) +else if (ieee80211_is_deauth (fc))cfg80211_process_deauth (wdev, buf, len, false); -else if (ieee80211_is_disassoc (mgmt->frame_control)) +else cfg80211_process_disassoc (wdev, buf, len, false); }EXPORT_SYMBOL (cfg80211_rx_mlme_mgmt);
@@ -229,15 +245,28 @@ void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len, {struct wireless_dev *wdev = dev->ieee80211_ptr;struct ieee80211_mgmt *mgmt = (void *)buf; +__le16 fc;lockdep_assert_wiphy (wdev->wiphy); -trace_cfg80211_tx_mlme_mgmt (dev, buf, len, reconnect); +if (len <sizeof (fc)) +return ; -if (WARN_ON (len <2 )) + fc = mgmt->frame_control; + +if (ieee80211_is_deauth (fc)) { + if (len < offsetofend(struct ieee80211_mgmt, u.deauth.reason_code)) +return ; + }else if (ieee80211_is_disassoc (fc)) { + if (len < offsetofend(struct ieee80211_mgmt, u.disassoc.reason_code)) +return ; + }else {return ; + } + +trace_cfg80211_tx_mlme_mgmt (dev, buf, len, reconnect); -if (ieee80211_is_deauth (mgmt->frame_control)) +if (ieee80211_is_deauth (fc))cfg80211_process_deauth (wdev, buf, len, reconnect);else cfg80211_process_disassoc (wdev, buf, len, reconnect);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 397/1102 wifi: mac80211: ibss: wait for in-flight TX on disconnect
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pagadala Yesu Anjaneyulu <[email protected]>
[ Upstream commit d0e69d9afa59b93c30294eba89b1f15f69e91105 ]
While leaving an IBSS in ieee80211_ibss_disconnect() mac80211 flushes stations, turns the carrier off and immediately tells the driver to leave as well. While there may be synchronize_net() in station flush and in this code later, packets can still be transmitted due to cross-CPU race conditions after carrier off is set. Therefore, it's possible for a race to happen where a TX to the driver occurs while or after telling it to leave the IBSS. This can be confusing to drivers, and in the case of iwlwifi leads to an attempt to use invalid queues.
Move netif_carrier_off() to occur before sta_info_flush() during IBSS disconnect, and add synchronize_net() if flushing didn't, so that the synchronize_net() always happens between turning the carrier off and telling the driver, avoiding this race.
--- net/mac80211/ibss.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
net/mac80211/ibss.c +3 -6
@@ -682,7 +682,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata) ifibss->state =IEEE80211_IBSS_MLME_SEARCH ; -sta_info_flush (sdata,-1 ); +netif_carrier_off (sdata->dev); +if (!sta_info_flush (sdata,-1 )) +synchronize_net ();spin_lock_bh (&ifibss->incomplete_lock);while (!list_empty (&ifibss->incomplete_stations)) {
@@ -696,8 +698,6 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata) }spin_unlock_bh (&ifibss->incomplete_lock); -netif_carrier_off (sdata->dev); - sdata->vif.cfg.ibss_joined = false; sdata->vif.cfg.ibss_creator = false; sdata->vif.bss_conf.enable_beacon = false;
@@ -724,7 +724,6 @@ static void ieee80211_csa_connection_drop_work(struct wiphy *wiphy, u.ibss.csa_connection_drop_work);ieee80211_ibss_disconnect (sdata); -synchronize_rcu ();skb_queue_purge (&sdata->skb_queue);/* trigger a scan to find another IBSS network to join */
@@ -1838,8 +1837,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)memset (&ifibss->ht_capa,0 ,sizeof (ifibss->ht_capa));memset (&ifibss->ht_capa_mask,0 ,sizeof (ifibss->ht_capa_mask)); -synchronize_rcu (); -skb_queue_purge (&sdata->skb_queue);del_timer_sync (&sdata->u.ibss.timer);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 398/1102 gpio: dwapb: Mask interrupts at hardware initialization
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liang Hao <[email protected]>
[ Upstream commit aaf7766ba3b99a3834319e7cf939838afc705574 ]
GPIO interrupts may retain stale state across warm reboots when peripherals remain powered. If a GPIO line is not explicitly configured for interrupts, this can result in interrupt storms due to missing handlers.
Fix this by ensuring all interrupts are masked and disabled at hardware initialization time via the init_hw() callback. Pending interrupts are also cleared to start from a known-safe state.
Interrupts will be unmasked only when explicitly configured by userspace or kernel drivers.
--- drivers/gpio/gpio-dwapb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/gpio/gpio-dwapb.c +17 -0
@@ -199,6 +199,22 @@ static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)dwapb_write (gpio,GPIO_INT_POLARITY , pol); } +static int dwapb_irq_init_hw (struct gpio_chip *gc) +{ +struct dwapb_gpio *gpio =to_dwapb_gpio (gc); + +/* +* GPIO interrupts may retain stale state across warm reboots when +* peripherals stay powered. Force a known-safe state before the GPIO +* irqchip and irq domain are set up. +*/ +dwapb_write (gpio,GPIO_INTEN ,0 ); +dwapb_write (gpio,GPIO_INTMASK ,0xffffffff ); +dwapb_write (gpio,GPIO_PORTA_EOI ,0xffffffff ); + +return 0 ; +} +static u32 dwapb_do_irq (struct dwapb_gpio *gpio) {struct gpio_chip *gc = &gpio->ports[0 ].gc;
@@ -461,6 +477,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, girq = &gc->irq; girq->handler = handle_bad_irq; girq->default_type =IRQ_TYPE_NONE ; + girq->init_hw = dwapb_irq_init_hw; port->pirq = pirq;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 399/1102 wifi: libipw: fix key index receive bound checks
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit 74ed3669f26803b1761c1f55403062bea44c3466 ]
libipw_rx() reads skb->data[hdrlen + 3] to extract the WEP key index in both the software-decrypt key selection path and the hardware-decrypted IV/ICV strip path. In both places the existing guard only checks skb->len >= hdrlen + 3, which proves bytes up to hdrlen + 2 but not the byte at hdrlen + 3.
Require hdrlen + 4 bytes before reading that item in both paths. This is a local source-boundary check only; it does not change the key index semantics.
--- drivers/net/wireless/intel/ipw2x00/libipw_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/intel/ipw2x00/libipw_rx.c +2 -2
@@ -417,7 +417,7 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, ieee->host_mc_decrypt : ieee->host_decrypt;if (can_be_decrypted) { -if (skb->len >= hdrlen +3 ) { +if (skb->len >= hdrlen +4 ) {/* Top two-bits of byte 3 are the key index */ keyidx = skb->data[hdrlen +3 ] >>6 ; }
@@ -663,7 +663,7 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,int trimlen =0 ;/* Top two-bits of byte 3 are the key index */ -if (skb->len >= hdrlen +3 ) +if (skb->len >= hdrlen +4 ) keyidx = skb->data[hdrlen +3 ] >>6 ;/* To strip off any security data which appears before the
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 400/1102 netfilter: ipset: mark the rcu locked areas properly
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jozsef Kadlecsik <[email protected]>
[ Upstream commit 5d0c22e73656d050daffad10a2ba8765ce8441c8 ]
When we bump the uref counter, there's no need to keep the rcu lock because the referred hash table can't disappear. Also, from the same reason in mtype_gc we need the rcu lock and not a spinlock.
--- net/netfilter/ipset/ip_set_hash_gen.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
net/netfilter/ipset/ip_set_hash_gen.h +5 -8
@@ -569,9 +569,10 @@ mtype_gc(struct work_struct *work) set = gc->set; h = set->data; -spin_lock_bh (&set->lock); - t =ipset_dereference_set (h->table, set); +rcu_read_lock_bh (); + t =rcu_dereference_bh (h->table);atomic_inc (&t->uref); +rcu_read_unlock_bh (); numof_locks =ahash_numof_locks (t->htable_bits); r = gc->region++;if (r >= numof_locks) {
@@ -580,7 +581,6 @@ mtype_gc(struct work_struct *work) next_run = (IPSET_GC_PERIOD (set->timeout) *HZ ) / numof_locks;if (next_run <HZ /10 ) next_run =HZ /10 ; -spin_unlock_bh (&set->lock);mtype_gc_do (set, h, t, r);
@@ -860,15 +860,13 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, key =HKEY (value, h->initval, t->htable_bits); r =ahash_region (key);atomic_inc (&t->uref); +rcu_read_unlock_bh (); elements = t->hregion[r].elements; maxelem = t->maxelem;if (elements >= maxelem) {u32 e; -if (SET_WITH_TIMEOUT (set)) { -rcu_read_unlock_bh (); +if (SET_WITH_TIMEOUT (set))mtype_gc_do (set, h, t, r); -rcu_read_lock_bh (); - } maxelem = h->maxelem; elements =0 ;for (e =0 ; e <ahash_numof_locks (t->htable_bits); e++)
@@ -876,7 +874,6 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,if (elements >= maxelem &&SET_WITH_FORCEADD (set)) forceadd = true; } -rcu_read_unlock_bh ();spin_lock_bh (&t->hregion[r].lock); n =rcu_dereference_bh (hbucket (t, key));
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 401/1102 wifi: rsi: validate beacon length before fixed buffer copy
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit 8ecdeb8b8a33b22c597299043c0dcfce50beb9ea ]
rsi_prepare_beacon() copies the mac80211 beacon frame after FRAME_DESC_SZ into a management skb whose usable tailroom may be smaller than MAX_MGMT_PKT_SIZE after alignment.
Validate the beacon length against the actual tailroom before the copy and skb_put(). Leave ownership of the management skb with the caller on error, matching the existing rsi_send_beacon() cleanup path.
--- drivers/net/wireless/rsi/rsi_91x_hal.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/wireless/rsi/rsi_91x_hal.c +8 -0
@@ -431,6 +431,7 @@ int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb)struct ieee80211_vif *vif;struct sk_buff *mac_bcn;u8 vap_id =0 , i; +unsigned int tailroom;u16 tim_offset =0 ;for (i =0 ; i <RSI_MAX_VIFS ; i++) {
@@ -480,6 +481,13 @@ int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb)if (mac_bcn->data[tim_offset +2 ] ==0 ) bcn_frm->frame_info |=cpu_to_le16 (RSI_DATA_DESC_DTIM_BEACON ); + tailroom =skb_tailroom (skb); +if (tailroom <FRAME_DESC_SZ || + mac_bcn->len > tailroom -FRAME_DESC_SZ ) { +dev_kfree_skb (mac_bcn); +return -EMSGSIZE ; + } +memcpy (&skb->data[FRAME_DESC_SZ ], mac_bcn->data, mac_bcn->len);skb_put (skb, mac_bcn->len +FRAME_DESC_SZ );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 402/1102 ASoC: rt712-sdca: reset codec at io_init to fix silent headphone
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianze Shao <[email protected]>
[ Upstream commit 4c9854ad3cdc7ce408453207f153bb910cc6f3c1 ]
On ThinkPad X1 Carbon Gen 13 (Lunar Lake, RT712-SDCA version VA) the 3.5mm headphone jack is silent after rebooting from Windows. rt712_sdca_va_io_init() gates rt712_sdca_calibration() on the persisted vendor SW_CONFIG1 flag, and io_init writes SW_CONFIG1=1 at the end regardless of whether the calibration succeeded. Across a warm reboot the codec keeps power, so SW_CONFIG1 stays unchanged, the calibration may be skipped, and the retained state can be invalid, leaving the headphone amp disabled.
This patch mimics the reset sequence in rt711-sdca.c, it adds an rt712_sdca_reset() helper, and calls it from io_init so the codec is reset before initialization. RT712_PARA_VERB_CTL, RT712_HIDDEN_REG_SW_RESET and RT712_HDA_LEGACY_RESET_CTL are already defined but were unused. The reset clears SW_CONFIG1 and the analog state so rt712_sdca_calibration() runs from a clean state and completes.
Problem reproducible: boot Windows (headphone is good) -> reboot to Linux (silent).
The reproducibility may depend on Windows' behaviour.
--- sound/soc/codecs/rt712-sdca.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
sound/soc/codecs/rt712-sdca.c +11 -0
@@ -1796,6 +1796,15 @@ static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712) } } +static void rt712_sdca_reset (struct rt712_sdca_priv *rt712) +{ +rt712_sdca_index_update_bits (rt712,RT712_VENDOR_REG , +RT712_PARA_VERB_CTL ,RT712_HIDDEN_REG_SW_RESET , +RT712_HIDDEN_REG_SW_RESET ); +rt712_sdca_index_update_bits (rt712,RT712_VENDOR_HDA_CTL , +RT712_HDA_LEGACY_RESET_CTL ,0x1 ,0x1 ); +} +int rt712_sdca_io_init (struct device *dev,struct sdw_slave *slave) {struct rt712_sdca_priv *rt712 =dev_get_drvdata (dev);
@@ -1824,6 +1833,8 @@ int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)pm_runtime_get_noresume (&slave->dev); +rt712_sdca_reset (rt712); +rt712_sdca_index_read (rt712,RT712_VENDOR_REG ,RT712_JD_PRODUCT_NUM , &val); rt712->hw_id = (val &0xf000 ) >>12 ; rt712->version_id = (val &0x0f00 ) >>8 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 403/1102 smb/client: reduce fallocate zero buffer allocation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <[email protected]>
[ Upstream commit 9e4ec3be67af41ab859302d7109b34976efd9258 ]
The fallocate emulation allocates a 1 MiB zero-filled buffer even though each SMB2_write request is limited to SMB2_MAX_BUFFER_SIZE, which is 64 KiB. A high-order 1 MiB allocation is more likely to fail on a fragmented system.
Allocate only the smaller of the requested range and SMB2_MAX_BUFFER_SIZE, and reuse that zero-filled buffer for every write request. Also reject a successful write that makes no progress to avoid looping indefinitely.
This reduces the contiguous allocation required by fallocate emulation without changing the written data or range semantics.
--- fs/smb/client/smb2ops.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/smb/client/smb2ops.c +4 -3
@@ -3442,7 +3442,7 @@ static int smb3_simple_fallocate_write_range(unsigned int xid, char *buf) {struct cifs_io_parms io_parms = {0 }; -int nbytes; +unsigned int nbytes;int rc =0 ;struct kvec iov[2 ];
@@ -3463,9 +3463,10 @@ static int smb3_simple_fallocate_write_range(unsigned int xid, rc =SMB2_write (xid, &io_parms, &nbytes, iov,1 );if (rc)break ; +if (!nbytes) +return -EIO ;if (nbytes > len)return -EINVAL ; - buf += nbytes; off += nbytes; len -= nbytes; }
@@ -3495,7 +3496,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,if (rc) goto out; - buf =kvzalloc (1024 *1024 ,GFP_KERNEL ); + buf =kvzalloc (min_t (loff_t, len,SMB2_MAX_BUFFER_SIZE ),GFP_KERNEL );if (buf ==NULL ) { rc = -ENOMEM ; goto out;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 404/1102 cifs: Fix support for creating SFU socket
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár <[email protected]>
[ Upstream commit dde3929e8d901ae9a7c29d0577ce9ca5cb4db35d ]
SFU sockets are natively supported by Interix 3.0 subsystem and also by later versions. It is part of Microsoft SFU (Windows Services for UNIX) and Microsoft SUA (Subsystem for UNIX-based Applications). They can be created and existing (stored on local disk or remote SMB share) can be recognized.
SFU sockets are recognized also by NFS server included in Windows Server. Windows NFS server versions since Windows Server 2012 uses new reparse point format for storing new sockets, but still can recognize this old format (also in the latest Windows Server 2022 version).
SFU-style socket is a regular file which has system attribute set and content of the file is one zero byte.
These SFU-style sockets are already recognized by Linux SMB client.
But Linux SMB client is currently creating new SFU socket in different format which is not compatible with all those SFU applications. Fix this by creating new sockets in correct SFU format which would be recognized by all SFU, SUA, NFS and existing Linux SMB clients.
This change affects only creating new sockets when mount option -o sfu is used.
--- fs/smb/client/smb2ops.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
fs/smb/client/smb2ops.c +3 -4
@@ -5216,10 +5216,9 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode, data = (u8 *)symname_utf16;break ;case S_IFSOCK : - type_len =8 ; -strscpy (type,"LnxSOCK" ); - data = (u8 *)&pdev; - data_len =sizeof (pdev); +/* SFU socket is system file with one zero byte */ + type_len =1 ; + type[0 ] ='\0' ;break ;case S_IFIFO : type_len =8 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 405/1102 smb/client: zero-initialize stack-allocated cifs_open_info_data
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <[email protected]>
[ Upstream commit 8fce4cf4369c766a3293a05419500cbfde72e60d ]
Stack-allocated cifs_open_info_data may contain random data. This can make some fields have wrong value if they are not set later.
--- fs/smb/client/link.c | 2 +- fs/smb/client/smb1ops.c | 2 +- fs/smb/client/smb2ops.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
fs/smb/client/link.c +1 -1
@@ -257,7 +257,7 @@ cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,struct cifs_open_parms oparms;struct cifs_io_parms io_parms = {0 };int buf_type =CIFS_NO_BUFFER ; -struct cifs_open_info_data query_data; +struct cifs_open_info_data query_data = {}; oparms = (struct cifs_open_parms ) { .tcon = tcon,
fs/smb/client/smb1ops.c +1 -1
@@ -971,7 +971,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,struct cifs_open_parms oparms;struct cifsFileInfo *open_file;FILE_BASIC_INFO new_buf; -struct cifs_open_info_data query_data; +struct cifs_open_info_data query_data = {};__le64 write_time = buf->LastWriteTime;struct cifsInodeInfo *cinode =CIFS_I (inode);struct cifs_sb_info *cifs_sb =CIFS_SB (inode->i_sb);
fs/smb/client/smb2ops.c +1 -1
@@ -5167,7 +5167,7 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode, {struct TCP_Server_Info *server = tcon->ses->server;struct cifs_open_parms oparms; -struct cifs_open_info_data idata; +struct cifs_open_info_data idata = {};struct cifs_io_parms io_parms = {};struct cifs_sb_info *cifs_sb =CIFS_SB (inode->i_sb);struct cifs_fid fid;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 406/1102 ALSA: hda/realtek: Fix speakers on MECHREVO WUJIE Series
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Bowen <[email protected]>
[ Upstream commit 9064637fb2a80b43105900a47d414997630e5b6b ]
The internal speakers on the MECHREVO WUJIE Series are silent, while the headphone output works correctly.
The BIOS reports NID 0x1b on the Realtek ALC233 codec as unconnected with pin configuration 0x411111f0. However, the pin is connected to an internal speaker.
Overriding NID 0x1b with 0x90170150 makes the HDA generic parser detect both 0x14 and 0x1b as speaker outputs and restores internal speaker playback.
Add a pin configuration fixup for the affected PCI SSID c011:1d05.
Tested on a MECHREVO WUJIE Series laptop with board WUJIE Series-Lark4-LNL and firmware EM_LNL326_V1.0.23.
--- sound/pci/hda/patch_realtek.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/pci/hda/patch_realtek.c +9 -0
@@ -8046,6 +8046,7 @@ enum {ALC275_FIXUP_DELL_XPS ,ALC293_FIXUP_LENOVO_SPK_NOISE ,ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY , +ALC233_FIXUP_WUJIE_SPEAKERS ,ALC233_FIXUP_LENOVO_L2MH_LOW_ENLED ,ALC255_FIXUP_DELL_SPK_NOISE , ALC225_FIXUP_DISABLE_MIC_VREF,
@@ -8282,6 +8283,13 @@ static void alc287_fixup_lenovo_yoga_book_9i(struct hda_codec *codec, }static const struct hda_fixup alc269_fixups[] = { + [ALC233_FIXUP_WUJIE_SPEAKERS ] = { + .type =HDA_FIXUP_PINS , + .v.pins = (const struct hda_pintbl []) { + {0x1b ,0x90170150 },/* internal speaker */ + { } + }, + }, [ALC269_FIXUP_GPIO2 ] = { .type =HDA_FIXUP_FUNC , .v.func = alc_fixup_gpio2,
@@ -11676,6 +11684,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x8086 ,0x2080 ,"Intel NUC 8 Rugged" ,ALC256_FIXUP_INTEL_NUC8_RUGGED ),SND_PCI_QUIRK (0x8086 ,0x2081 ,"Intel NUC 10" ,ALC256_FIXUP_INTEL_NUC10 ),SND_PCI_QUIRK (0x8086 ,0x3038 ,"Intel NUC 13" ,ALC295_FIXUP_CHROME_BOOK ), +SND_PCI_QUIRK (0xc011 ,0x1d05 ,"MECHREVO WUJIE Series" ,ALC233_FIXUP_WUJIE_SPEAKERS ),SND_PCI_QUIRK (0xf111 ,0x0001 ,"Framework Laptop" ,ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0xf111 ,0x0006 ,"Framework Laptop" ,ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0xf111, 0x0009, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 407/1102 ALSA: hda/realtek - Add quirk for HP Victus 15-fa0xxx (MB 8A50)
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rohit Sinha <[email protected]>
[ Upstream commit 5c3f4b583c25911fad9890b463632761291f65ab ]
The mute LED on HP Victus 15-fa0xxx (board ID 8A50) uses ALC245 but requires a quirk to work. This patch enables the existing ALC245_FIXUP_HP_MUTE_LED_COEFBIT quirk for the device.
Tested on my HP Victus 15-fa0xxx. The LED behaviour works as intended.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10999,6 +10999,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x103c ,0x8a30 ,"HP Envy 17" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x103c ,0x8a31 ,"HP Envy 15" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x103c ,0x8a4f ,"HP Victus 15-fa0xxx (MB 8A4F)" ,ALC245_FIXUP_HP_MUTE_LED_COEFBIT ), +SND_PCI_QUIRK (0x103c ,0x8a50 ,"HP Victus 15-fa0xxx (MB 8A50)" ,ALC245_FIXUP_HP_MUTE_LED_COEFBIT ),SND_PCI_QUIRK (0x103c ,0x8a6e ,"HP EDNA 360" ,ALC287_FIXUP_CS35L41_I2C_4 ),SND_PCI_QUIRK (0x103c ,0x8a74 ,"HP ProBook 440 G8 Notebook PC" ,ALC236_FIXUP_HP_GPIO_LED ), SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 408/1102 ALSA: hda: cs35l56: Fail if wmfw file is missing
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <[email protected]>
[ Upstream commit 07ae060d35900977a93d4a05ec995b06c85c2552 ]
Fail cs35l56_hda_fw_load() and log an error if it didn't find a wmfw file and the BIOS didn't patch the firmware already. Also remove a section of code from cs35l56_hda_request_firmware_files() that attempted to find a .bin if a .wmfw was not found.
The CS35L56 ROM can only provide default audio in SoundWire mode. A wmfw is needed to enable I2S audio. Also none of the customer-specific .bin files are compatible with the ROM firmware. So a .wmfw file is always required.
--- sound/pci/hda/cs35l56_hda.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-)
sound/pci/hda/cs35l56_hda.c +9 -21
@@ -521,20 +521,6 @@ static void cs35l56_hda_request_firmware_files(struct cs35l56_hda *cs35l56, NULL, "bin");return ; } - -/* -* Check for system-specific bin files without wmfw before -* falling back to generic firmware -*/ -if (amp_name) -cs35l56_hda_request_firmware_file (cs35l56, coeff_firmware, coeff_filename, - base_name, system_name, amp_name,"bin" ); -if (!*coeff_firmware) -cs35l56_hda_request_firmware_file (cs35l56, coeff_firmware, coeff_filename, - base_name, system_name,NULL ,"bin" ); - -if (*coeff_firmware) -return ; } ret = cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,
@@ -622,13 +608,15 @@ static void cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56) &wmfw_firmware, &wmfw_filename, &coeff_firmware, &coeff_filename); -/* -* If the BIOS didn't patch the firmware a bin file is mandatory to -* enable the ASP· -*/ -if (!coeff_firmware && firmware_missing) { -dev_err (cs35l56->base.dev,".bin file required but not found\n" ); - goto err_fw_release; +/* If the BIOS didn't patch the firmware a wmfw and bin file are mandatory */ +if (firmware_missing) { +if (!wmfw_firmware) { +dev_err (cs35l56->base.dev,".%s file required but not found\n" ,"wmfw" ); + goto err_fw_release; + }else if (!coeff_firmware) { +dev_err (cs35l56->base.dev,".%s file required but not found\n" ,"bin" ); + goto err_fw_release; + } }mutex_lock (&cs35l56->base.irq_lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 409/1102 cifs: Fix support for creating SFU fifo
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár <[email protected]>
[ Upstream commit 608362facd2d0f2667f68b7f42207707d59a0071 ]
SFU fifos are natively supported (created and recognized) at least by:
- Microsoft POSIX subsystem
- OpenNT/Interix subsystem
- Microsoft SFU (Windows Services for UNIX)
- Microsoft SUA (Subsystem for UNIX-based Applications)
- Windows NFS server (up to the Windows Server 2008 R2)
Windows NFS server since Windows Server 2012 uses new reparse point format for storing new fifos, but still can recognize this old format (also in the latest Windows Server 2022 version).
SFU-style fifo is empty regular file which has system attribute set.
These SFU-style fifos are already recognized by Linux SMB client.
But Linux SMB client is currently creating new SFU fifos in different format which is not compatible with all those SFU-style consumers. Fix this by creating new fifos in correct SFU format which would be recognized by all those applications and also by existing Linux SMB clients.
This change affects only creating new fifos when mount option -o sfu is used.
--- fs/smb/client/smb2ops.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/smb/client/smb2ops.c +2 -4
@@ -5221,10 +5221,8 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode, type[0 ] ='\0' ;break ;case S_IFIFO : - type_len =8 ; -strscpy (type,"LnxFIFO" ); - data = (u8 *)&pdev; - data_len =sizeof (pdev); +/* SFU fifo is system file which is empty */ + type_len =0 ;break ;default : rc = -EPERM ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 410/1102 btrfs: only account delalloc bytes for regular file inodes in btrfs_getattr()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chen <[email protected]>
[ Upstream commit 9411aafdf352b8d72668732af5a37dcb27383e25 ]
btrfs_getattr() unconditionally reads BTRFS_I(inode)->new_delalloc_bytes and adds it (sector-aligned) to stat->blocks for every inode type. However, new_delalloc_bytes lives in a union with last_dir_index_offset:
union {
u64 new_delalloc_bytes; /* files only */
u64 last_dir_index_offset; /* directories only */
};
For a directory inode this memory holds last_dir_index_offset, which is set during directory logging (e.g. flush_dir_items_batch()) to the offset of the last logged BTRFS_DIR_INDEX_KEY. That offset grows with the number of entries ever created in the directory (dir indexes are monotonic and never reused), so it can be arbitrarily large.
As a result, after a directory has been logged (e.g. via an fsync that triggers directory logging), btrfs_getattr() reports inflated st_blocks for that directory. The inflation is purely in-core and disappears after the inode is evicted and reloaded (btrfs_alloc_inode() zeroes the union), e.g. after a remount.
Reproducer (on a btrfs filesystem):
D=/mnt/btrfs/d
mkdir -p $D
for i in $(seq 1 20000); do touch $D/f$i; done
sync # commit, push dir index high
touch $D/trigger # dirty the dir in a new transaction
xfs_io -c fsync $D # log the directory -> sets last_dir_index_offset
stat -c '%b' $D # st_blocks is now inflated (e.g. 40)
# umount + mount -> st_blocks drops back to the correct value
The evict path already knows this union is type-dependent and guards the corresponding WARN_ON with !S_ISDIR() in btrfs_destroy_inode(); only btrfs_getattr() was missing the equivalent check.
Only read new_delalloc_bytes for regular files, which are the only inodes that ever set it.
--- fs/btrfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/btrfs/inode.c +2 -1
@@ -7877,7 +7877,8 @@ static int btrfs_getattr(struct mnt_idmap *idmap, stat->result_mask |=STATX_SUBVOL ;spin_lock (&BTRFS_I (inode)->lock); - delalloc_bytes =BTRFS_I (inode)->new_delalloc_bytes; + delalloc_bytes =S_ISREG (inode->i_mode) ? +BTRFS_I (inode)->new_delalloc_bytes :0 ; inode_bytes =inode_get_bytes (inode);spin_unlock (&BTRFS_I (inode)->lock); stat->blocks = (ALIGN(inode_bytes, blocksize) +
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 411/1102 btrfs: fix use-after-free on reloc root after error in insert_dirty_subvol()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 83201804efa4a5168be754e1dfc9b2faee760cac ]
If during relocation we fail in insert_dirty_subvol() because btrfs_update_reloc_root() returned an error, we will leave a root's reloc_root field pointing to a reloc root that was freed instead of NULL, resulting later in a use-after-free, or double free attempt during unmount.
The sequence of steps is this:
1) During relocation the call to btrfs_update_reloc_root() in insert_dirty_subvol() fails, so insert_dirty_subvol() returns the error to merge_reloc_root() without adding the root to the list rc->dirty_subvol_roots;
2) Then merge_reloc_root() aborts the current transaction because insert_dirty_subvol() returned an error;
3) Up the call chain, merge_reloc_roots() gets the error, adds the reloc root for root X to the local reloc_roots list and jumps to the 'out' label, where it calls free_reloc_roots() to free all the reloc roots in the local reloc_roots list. This frees the reloc root for root X;
4) We go up the call chain to relocate_block_group() which calls clean_dirty_subvols() to go over dirty roots and set their ->reloc_root field to NULL, but root X is not in the dirty_subvol_roots list, so its ->reloc_root still points to a reloc root;
5) Relocation finishes, with an error and a transaction abort, but the ->reloc_root field for root X still points to the reloc root that was freed in step 3;
6) When unmounting the fs we end up calling:
btrfs_free_fs_roots()
btrfs_drop_and_free_fs_root()
--> calls btrfs_put_root() against root X's ->reloc_root
which is not NULL and points to the already freed reloc root in step 4 above
Resulting in a use-after-free to a double free attempt.
Syzbot reported this with the following dmesg/syslog:
[ 106.004389][ T5339] BTRFS error (device loop0 state A): Transaction aborted (error -5) [ 106.014266][ T5339] BTRFS: error (device loop0 state A) in merge_reloc_root:1655: errno=-5 IO failure [ 106.021891][ T1061] BTRFS error (device loop0 state A): error while writing out transaction: -5 [ 106.026964][ T1061] BTRFS warning (device loop0 state A): Skipping commit of aborted transaction. [ 106.033807][ T5340] BTRFS error (device loop0 state A): bdev /dev/loop0 errs: wr 3, rd 0, flush 0, corrupt 0, gen 0 [ 106.039265][ T1061] BTRFS: error (device loop0 state A) in cleanup_transaction:2067: errno=-5 IO failure [ 106.044382][ T5339] BTRFS info (device loop0 state EA): forced readonly [ 106.074329][ T5339] BTRFS: error (device loop0 state EA) in merge_reloc_roots:1887: errno=-5 IO failure [ 106.081004][ T5356] BTRFS info (device loop0 state EA): scrub: started on devid 1 [ 106.085611][ T5339] BTRFS info (device loop0 state EA): balance: ended with status: -30 [ 106.089517][ T5356] BTRFS info (device loop0 state EA): scrub: not finished on devid 1 with status: -30 [ 106.662365][ T5338] BTRFS info (device loop0 state EA): last unmount of filesystem 3a375e4e-b156-4d76-a2ad-16e198ce1409 [ 106.682946][ T5338] ================================================================== [ 106.686574][ T5338] BUG: KASAN: slab-use-after-free in btrfs_put_root+0x2f/0x250 [ 106.690090][ T5338] Write of size 4 at addr ffff88803f978630 by task syz.0.0/5338 [ 106.693173][ T5338] [ 106.694279][ T5338] CPU: 0 UID: 0 PID: 5338 Comm: syz.0.0 Not tainted syzkaller #0 PREEMPT(full) [ 106.694293][ T5338] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 106.694300][ T5338] Call Trace: [ 106.694308][ T5338] <TASK> [ 106.694314][ T5338] dump_stack_lvl+0xe8/0x150 [ 106.694331][ T5338] print_address_description+0x55/0x1e0 [ 106.694343][ T5338] ? btrfs_put_root+0x2f/0x250 [ 106.694358][ T5338] print_report+0x58/0x70 [ 106.694368][ T5338] kasan_report+0x117/0x150 [ 106.694384][ T5338] ? btrfs_put_root+0x2f/0x250 [ 106.694399][ T5338] kasan_check_range+0x264/0x2c0 [ 106.694416][ T5338] btrfs_put_root+0x2f/0x250 [ 106.694430][ T5338] btrfs_drop_and_free_fs_root+0x160/0x210 [ 106.694447][ T5338] btrfs_free_fs_roots+0x2f9/0x3c0 [ 106.694464][ T5338] ? __pfx_btrfs_free_fs_roots+0x10/0x10 [ 106.694479][ T5338] ? free_root_pointers+0x5bf/0x5f0 [ 106.694494][ T5338] close_ctree+0x798/0x12d0 [ 106.694511][ T5338] ? __pfx_close_ctree+0x10/0x10 [ 106.694526][ T5338] ? _raw_spin_unlock_irqrestore+0x74/0x80 [ 106.694599][ T5338] ? rcu_preempt_deferred_qs_irqrestore+0x906/0xbc0 [ 106.694620][ T5338] ? __rcu_read_unlock+0x83/0xe0 [ 106.694636][ T5338] ? btrfs_put_super+0x48/0x1c0 [ 106.694652][ T5338] ? __pfx_btrfs_put_super+0x10/0x10 [ 106.694667][ T5338] generic_shutdown_super+0x13d/0x2d0 [ 106.694682][ T5338] kill_anon_super+0x3b/0x70 [ 106.694695][ T5338] btrfs_kill_super+0x41/0x50 [ 106.694710][ T5338] deactivate_locked_super+0xbc/0x130 [ 106.694722][ T5338] cleanup_mnt+0x437/0x4d0 [ 106.694736][ T5338] ? _raw_spin_unlock_irq+0x23/0x50 [ 106.694752][ T5338] task_work_run+0x1d9/0x270 [ 106.694769][ T5338] ? __pfx_task_work_run+0x10/0x10 [ 106.694784][ T5338] ? do_raw_spin_unlock+0x4d/0x210 [ 106.694802][ T5338] do_exit+0x70f/0x22c0 [ 106.694817][ T5338] ? trace_irq_disable+0x3b/0x140 [ 106.694835][ T5338] ? __pfx_do_exit+0x10/0x10 [ 106.694848][ T5338] ? preempt_schedule_thunk+0x16/0x30 [ 106.694863][ T5338] ? preempt_schedule_common+0x82/0xd0 [ 106.694878][ T5338] ? preempt_schedule_thunk+0x16/0x30 [ 106.694892][ T5338] do_group_exit+0x21b/0x2d0 [ 106.694906][ T5338] ? entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 106.694918][ T5338] __x64_sys_exit_group+0x3f/0x40 [ 106.694932][ T5338] x64_sys_call+0x221a/0x2240 [ 106.694944][ T5338] do_syscall_64+0x174/0x580 [ 106.694954][ T5338] ? clear_bhb_loop+0x40/0x90 [ 106.694967][ T5338] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 106.694978][ T5338] RIP: 0033:0x7f958ef9ce59 [ 106.694988][ T5338] Code: Unable to access opcode bytes at 0x7f958ef9ce2f. [ 106.694994][ T5338] RSP: 002b:00007fffd4058318 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 [ 106.695008][ T5338] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f958ef9ce59 [ 106.695015][ T5338] RDX: 00007f958c3f8000 RSI: 0000000000000000 RDI: 0000000000000000 [ 106.695022][ T5338] RBP: 0000000000000003 R08: 0000000000000000 R09: 00007f958f1e73e0 [ 106.695028][ T5338] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 [ 106.695034][ T5338] R13: 00007f958f1e73e0 R14: 0000000000000003 R15: 00007fffd40583d0 [ 106.695046][ T5338] </TASK> [ 106.695050][ T5338] [ 106.821635][ T5338] Allocated by task 1061: [ 106.823446][ T5338] kasan_save_track+0x3e/0x80 [ 106.825498][ T5338] __kasan_kmalloc+0x93/0xb0 [ 106.827381][ T5338] __kmalloc_cache_noprof+0x31c/0x660 [ 106.829525][ T5338] btrfs_alloc_root+0x75/0x930 [ 106.831458][ T5338] read_tree_root_path+0x127/0xb00 [ 106.833556][ T5338] btrfs_read_tree_root+0x34/0x60 [ 106.835553][ T5338] create_reloc_root+0x6b3/0xcb0 [ 106.837556][ T5338] btrfs_init_reloc_root+0x2ec/0x4b0 [ 106.839557][ T5338] record_root_in_trans+0x2ab/0x350 [ 106.841685][ T5338] btrfs_record_root_in_trans+0x15c/0x180 [ 106.844237][ T5338] start_transaction+0x39c/0x1820 [ 106.846638][ T5338] btrfs_finish_one_ordered+0x88e/0x2680 [ 106.849436][ T5338] btrfs_work_helper+0x37b/0xc20 [ 106.851549][ T5338] process_scheduled_works+0xb5d/0x1860 [ 106.853807][ T5338] worker_thread+0xa53/0xfc0 [ 106.855773][ T5338] kthread+0x389/0x470 [ 106.857548][ T5338] ret_from_fork+0x514/0xb70 [ 106.859493][ T5338] ret_from_fork_asm+0x1a/0x30 [ 106.861504][ T5338] [ 106.862527][ T5338] Freed by task 5339: [ 106.864224][ T5338] kasan_save_track+0x3e/0x80 [ 106.866180][ T5338] kasan_save_free_info+0x46/0x50 [ 106.868371][ T5338] __kasan_slab_free+0x5c/0x80 [ 106.870462][ T5338] kfree+0x1c5/0x640 [ 106.872180][ T5338] __del_reloc_root+0x341/0x3b0 [ 106.874290][ T5338] free_reloc_roots+0x5f/0x90 [ 106.876282][ T5338] merge_reloc_roots+0x73f/0x8a0 [ 106.878489][ T5338] relocate_block_group+0xbcc/0xe70 [ 106.880742][ T5338] do_nonremap_reloc+0xa8/0x5b0 [ 106.882885][ T5338] btrfs_relocate_block_group+0x7e6/0xc40 [ 106.885336][ T5338] btrfs_relocate_chunk+0x115/0x820 [ 106.887502][ T5338] __btrfs_balance+0x1db0/0x2ae0 [ 106.889543][ T5338] btrfs_balance+0xaf3/0x11b0 [ 106.891456][ T5338] btrfs_ioctl_balance+0x3d3/0x610 [ 106.893672][ T5338] __se_sys_ioctl+0xfc/0x170 [ 106.895530][ T5338] do_syscall_64+0x174/0x580 [ 106.897518][ T5338] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 106.900101][ T5338] [ 106.901123][ T5338] The buggy address belongs to the object at ffff88803f978000 [ 106.901123][ T5338] which belongs to the cache kmalloc-4k of size 4096 [ 106.906907][ T5338] The buggy address is located 1584 bytes inside of [ 106.906907][ T5338] freed 4096-byte region [ffff88803f978000, ffff88803f979000) [ 106.912980][ T5338] [ 106.914022][ T5338] The buggy address belongs to the physical page: [ 106.916716][ T5338] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x3f978 [ 106.920390][ T5338] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [ 106.923834][ T5338] flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff) [ 106.927104][ T5338] page_type: f5(slab) [ 106.928898][ T5338] raw: 04fff00000000040 ffff88801ac42140 dead000000000122 0000000000000000 [ 106.932507][ T5338] raw: 0000000000000000 0000000800040004 00000000f5000000 0000000000000000 [ 106.936193][ T5338] head: 04fff00000000040 ffff88801ac42140 dead000000000122 0000000000000000 [ 106.939856][ T5338] head: 0000000000000000 0000000800040004 00000000f5000000 0000000000000000 [ 106.943601][ T5338] head: 04fff00000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff [ 106.947268][ T5338] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008 [ 106.950988][ T5338] page dumped because: kasan: bad access detected [ 106.953710][ T5338] page_owner tracks the page as allocated [ 106.956198][ T5338] page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 24, tgid 24 (kworker/u4:2), ts 105728970387, free_ts 29540875453 [ 106.964984][ T5338] post_alloc_hook+0x22d/0x280 [ 106.966956][ T5338] get_page_from_freelist+0x2593/0x2610 [ 106.969307][ T5338] __alloc_frozen_pages_noprof+0x18d/0x380 [ 106.971839][ T5338] allocate_slab+0x77/0x660 [ 106.973709][ T5338] refill_objects+0x339/0x3d0 [ 106.975696][ T5338] __pcs_replace_empty_main+0x321/0x720 [ 106.978136][ T5338] __kmalloc_node_track_caller_noprof+0x572/0x7b0 [ 106.981009][ T5338] __alloc_skb+0x2c1/0x7d0 [ 106.982983][ T5338] nsim_dev_trap_report_work+0x29a/0xb90 [ 106.985356][ T5338] process_scheduled_works+0xb5d/0x1860 [ 106.987710][ T5338] worker_thread+0xa53/0xfc0 [ 106.989847][ T5338] kthread+0x389/0x470 [ 106.991727][ T5338] ret_from_fork+0x514/0xb70 [ 106.993722][ T5338] ret_from_fork_asm+0x1a/0x30 [ 106.995900][ T5338] page last free pid 77 tgid 77 stack trace: [ 106.998479][ T5338] __free_frozen_pages+0xc1c/0xd30 [ 107.000819][ T5338] vfree+0x1d1/0x2f0 [ 107.002631][ T5338] delayed_vfree_work+0x55/0x80 [ 107.004848][ T5338] process_scheduled_works+0xb5d/0x1860 [ 107.007366][ T5338] worker_thread+0xa53/0xfc0 [ 107.009388][ T5338] kthread+0x389/0x470 [ 107.011177][ T5338] ret_from_fork+0x514/0xb70 [ 107.013313][ T5338] ret_from_fork_asm+0x1a/0x30 [ 107.015454][ T5338] [ 107.016460][ T5338] Memory state around the buggy address: [ 107.019052][ T5338] ffff88803f978500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 107.022691][ T5338] ffff88803f978580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 107.026264][ T5338] >ffff88803f978600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 107.029721][ T5338] ^ [ 107.032062][ T5338] ffff88803f978680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 107.035547][ T5338] ffff88803f978700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 107.038865][ T5338] ==================================================================
Fix this by resetting a root's ->reloc_root if we get an error while trying to merge a reloc root.
--- fs/btrfs/relocation.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-)
fs/btrfs/relocation.c +33 -9
@@ -1555,6 +1555,17 @@ static int insert_dirty_subvol(struct btrfs_trans_handle *trans,return 0 ; } +static void clear_reloc_root (struct btrfs_root *root) +{ + root->reloc_root =NULL ; +/* +* Need barrier to ensure clear_bit() only happens after +* root->reloc_root = NULL. Pairs with have_reloc_root(). +*/ +smp_wmb (); +clear_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state); +} +static int clean_dirty_subvols (struct reloc_control *rc) {struct btrfs_root *root;
@@ -1569,13 +1580,7 @@ static int clean_dirty_subvols(struct reloc_control *rc)struct btrfs_root *reloc_root = root->reloc_root;list_del_init (&root->reloc_dirty_list); - root->reloc_root =NULL ; -/* -* Need barrier to ensure clear_bit() only happens after -* root->reloc_root = NULL. Pairs with have_reloc_root. -*/ -smp_wmb (); -clear_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state); +clear_reloc_root (root);if (reloc_root) {/* * btrfs_drop_snapshot drops our ref we hold for
@@ -1961,13 +1966,32 @@ void merge_reloc_roots(struct reloc_control *rc) goto out; } ret =merge_reloc_root (rc, root); -btrfs_put_root (root);if (ret) { -if (list_empty (&reloc_root->root_list)) +/* +* Clear the reloc root since below we will call +* free_reloc_roots(), otherwise we leave +* root->reloc_root pointing to a freed reloc +* root and trigger a use-after-free during +* unmount or elsewhere. +*/ +clear_reloc_root (root); +btrfs_put_root (root); +/* +* We are adding the reloc_root to the local +* reloc_roots list, so we add a ref for this +* list which will be dropped below by the call +* to free_reloc_roots(). +*/ +if (list_empty (&reloc_root->root_list)) {list_add_tail (&reloc_root->root_list, &reloc_roots); +btrfs_grab_root (reloc_root); + } +/* Now drop the ref for root->reloc_root. */ +btrfs_put_root (reloc_root); goto out; } +btrfs_put_root (root); }else {if (!IS_ERR (root)) {if (root->reloc_root == reloc_root) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 412/1102 spi: dw-dma: Wait for controller idle before completing Tx
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang YuWei <[email protected]>
[ Upstream commit 0bcd59706aeda8a5d48ba656bab74cb26f2b423e ]
dw_spi_dma_wait_tx_done() polls dw_spi_dma_tx_busy(), which only checks DW_SPI_SR_TF_EMPT. An empty TX FIFO merely means the last data word has been moved into the shift register; the transfer is not complete on the bus until DW_SPI_SR_BUSY is also cleared. As a result the wait can return while the controller is still shifting out the final word.
Any caller that tears down or reconfigures the controller right after the transfer can then lose the tail of the transfer.
The memory-operation path in spi-dw-core.c already waits for both DW_SPI_SR_BUSY == 0 and DW_SPI_SR_TF_EMPT == 1. Use the same completion condition in the DMA path so the transfer is guaranteed to be finished on the bus before the wait returns.
--- drivers/spi/spi-dw-dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/spi/spi-dw-dma.c +2 -1
@@ -281,7 +281,8 @@ static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed)static inline bool dw_spi_dma_tx_busy (struct dw_spi *dws) { -return !(dw_readl (dws,DW_SPI_SR ) &DW_SPI_SR_TF_EMPT ); +return (dw_readl (dws,DW_SPI_SR ) & + (DW_SPI_SR_BUSY |DW_SPI_SR_TF_EMPT )) !=DW_SPI_SR_TF_EMPT ; } static int dw_spi_dma_wait_tx_done(struct dw_spi *dws,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 413/1102 wifi: iwlwifi: mvm: validate sta_id in BA window status notif
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 6aa77efaea9efea92e3090c35ad348fd759a3cf3 ]
BA_WINDOW_STATUS_NOTIFICATION_ID extracts a 5-bit sta_id from the firmware notification and uses it to index fw_id_to_mac_id[] without bounds checking. Validate sta_id before array access to prevent out-of-bounds indexing.
--- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/wireless/intel/iwlwifi/mvm/rx.c +5 -0
@@ -1335,6 +1335,11 @@ void iwl_mvm_window_status_notif(struct iwl_mvm *mvm,/* get the station */ sta_id = (ratid &BA_WINDOW_STATUS_STA_ID_MSK ) >>BA_WINDOW_STATUS_STA_ID_POS ; +if (IWL_FW_CHECK (mvm, + sta_id >= mvm->fw->ucode_capa.num_stations, +"Invalid sta id (%d) in BA window status notification\n" , + sta_id)) +continue ; sta =rcu_dereference (mvm->fw_id_to_mac_id[sta_id]);if (IS_ERR_OR_NULL (sta))continue ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 414/1102 btrfs: fix reloc root cleanup in merge_reloc_roots()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit b78fe9563e2d5ae47805f1e5dc722c91fd30e1f8 ]
If the root we got has zero root refs in its root item, we are resetting the root's ->reloc_root without using barriers like we do everywhere else. Sashiko complained about this while reviewing another patch, and it's correct (see the Link tag below).
Also, we should not clear BTRFS_ROOT_DEAD_RELOC_TREE from the root unless the root points to the reloc root we have.
Fix this by using clear_reloc_root(), which issues the memory barrier after setting the root's ->reloc_root to NULL and before clearing the bit BTRFS_ROOT_DEAD_RELOC_TREE from the root.
--- fs/btrfs/relocation.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/btrfs/relocation.c +2 -3
@@ -1995,11 +1995,10 @@ void merge_reloc_roots(struct reloc_control *rc) }else {if (!IS_ERR (root)) {if (root->reloc_root == reloc_root) { - root->reloc_root =NULL ; +clear_reloc_root (root); +/* Drop the ref for root->reloc_root. */ btrfs_put_root (reloc_root); } -clear_bit (BTRFS_ROOT_DEAD_RELOC_TREE , - &root->state);btrfs_put_root (root); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 415/1102 wifi: iwlwifi: mvm: validate mac_link_id in session protect notif
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 71245daf7d58a3c407c7e1422facce13ff6a584b ]
Check the mac_id before accessing the vif_id_to_mac array.
--- drivers/net/wireless/intel/iwlwifi/mvm/time-event.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +5 -0
@@ -964,6 +964,11 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,struct iwl_mvm_vif *mvmvif;unsigned int notif_link_id; +if (IWL_FW_CHECK (mvm, id >=ARRAY_SIZE (mvm->vif_id_to_mac), +"Invalid mac_link_id (%d) in session protect notif\n" , + id)) +return ; +rcu_read_lock ();if (ver <=2 ) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 416/1102 wifi: iwlwifi: mvm: fix an off-by-1 boundary check
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit d77aff138c9ec6c8562f4c2c9f262d3d9c4b4cb8 ]
Before looking at the 11th byte, check the length is big enough.
--- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +1 -1
@@ -3616,7 +3616,7 @@ static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, elem =cfg80211_find_elem (WLAN_EID_EXT_CAPABILITY , ies->data, ies->len); -if (!elem || elem->datalen <10 || +if (!elem || elem->datalen <11 || !(elem->data[10 ] &WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT )) { data->tolerated = false;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 417/1102 wifi: iwlwifi: mvm: parse beacon notif per layout
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit b77c6f50b1f80414cb3f542ae72e532ed90fc7f7 ]
The beacon TX notification can arrive in different layouts, and fields must be read only after selecting the expected format.
Parse gp2 and TSF from the matching notification structure in each branch, and keep using the parsed gp2 for CSA countdown and debug output. Drop the obsolete cached gp2 field.
--- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 25 +++++++++++-------- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 1 - drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 --- 3 files changed, 15 insertions(+), 14 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +15 -10
@@ -1515,49 +1515,54 @@ void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, {struct iwl_rx_packet *pkt =rxb_addr (rxb);unsigned int pkt_len =iwl_rx_packet_payload_len (pkt); -struct iwl_extended_beacon_notif *beacon = (void *)pkt->data; -struct iwl_extended_beacon_notif_v5 *beacon_v5 = (void *)pkt->data;struct ieee80211_vif *csa_vif;struct ieee80211_vif *tx_blocked_vif;struct agg_tx_status *agg_status; +u32 beacon_gp2;u16 status;lockdep_assert_held (&mvm->mutex); - mvm->ap_last_beacon_gp2 =le32_to_cpu (beacon->gp2); -if (!iwl_mvm_is_short_beacon_notif_supported (mvm)) { +struct iwl_extended_beacon_notif_v5 *beacon = (void *)pkt->data;struct iwl_tx_resp *beacon_notify_hdr = - &beacon_v5->beacon_notify_hdr; + &beacon->beacon_notify_hdr; -if (unlikely (pkt_len <sizeof (*beacon_v5))) +if (unlikely (pkt_len <sizeof (*beacon)))return ; - mvm->ibss_manager = beacon_v5->ibss_mgr_status !=0 ; + beacon_gp2 =le32_to_cpu (beacon->gp2); + + mvm->ibss_manager = beacon->ibss_mgr_status !=0 ; agg_status =iwl_mvm_get_agg_status (mvm, beacon_notify_hdr); status =le16_to_cpu (agg_status->status) &TX_STATUS_MSK ;IWL_DEBUG_RX (mvm,"beacon status %#x retries:%d tsf:0x%016llX gp2:0x%X rate:%d\n" , status, beacon_notify_hdr->failure_frame,le64_to_cpu (beacon->tsf), - mvm->ap_last_beacon_gp2, + beacon_gp2,le32_to_cpu (beacon_notify_hdr->initial_rate)); }else { +const struct iwl_extended_beacon_notif *beacon = + (void *)pkt->data; +if (unlikely (pkt_len <sizeof (*beacon)))return ; + beacon_gp2 =le32_to_cpu (beacon->gp2); + mvm->ibss_manager = beacon->ibss_mgr_status !=0 ; status =le32_to_cpu (beacon->status) &TX_STATUS_MSK ;IWL_DEBUG_RX (mvm,"beacon status %#x tsf:0x%016llX gp2:0x%X\n" , status,le64_to_cpu (beacon->tsf), - mvm->ap_last_beacon_gp2); + beacon_gp2); } csa_vif =rcu_dereference_protected (mvm->csa_vif,lockdep_is_held (&mvm->mutex));if (unlikely (csa_vif && csa_vif->bss_conf.csa_active)) -iwl_mvm_csa_count_down (mvm, csa_vif, mvm->ap_last_beacon_gp2, +iwl_mvm_csa_count_down (mvm, csa_vif, beacon_gp2, (status ==TX_STATUS_SUCCESS )); tx_blocked_vif = rcu_dereference_protected(mvm->csa_tx_blocked_vif,
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +0 -1
@@ -3189,7 +3189,6 @@ void iwl_mvm_stop_ap_ibss_common(struct iwl_mvm *mvm, } mvmvif->ap_ibss_active = false; - mvm->ap_last_beacon_gp2 =0 ;if (vif->type ==NL80211_IFTYPE_AP && !vif->p2p) { iwl_mvm_vif_set_low_latency(mvmvif, false,
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +0 -3
@@ -1263,9 +1263,6 @@ struct iwl_mvm {struct ieee80211_vif __rcu *csa_tx_blocked_vif;u8 csa_tx_block_bcn_timeout; -/* system time of last beacon (for AP/GO interface) */ -u32 ap_last_beacon_gp2; -/* indicates that we transmitted the last beacon */ bool ibss_manager;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 418/1102 wifi: iwlwifi: mvm: fix sched scan IE sizing
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 4f155d262b31b9b17e0f9856bdabe0968eb4930f ]
Scheduled scan built the probe request before iwl_mvm_scan_fits(), so oversized IEs could be copied into the fixed preq buffer before length validation. Move iwl_mvm_build_scan_probe() after the fits check.
Also advertise max_sched_scan_ie_len using iwl_mvm_max_scan_ie_len() so userspace limits account for driver-inserted DS/TPC bytes.
--- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 4 +--- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +1 -3
@@ -619,9 +619,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->max_sched_scan_reqs =1 ; hw->wiphy->max_sched_scan_ssids =PROBE_OPTION_MAX ; hw->wiphy->max_match_sets =iwl_umac_scan_get_max_profiles (mvm->fw); -/* we create the 802.11 header and zero length SSID IE. */ - hw->wiphy->max_sched_scan_ie_len = -SCAN_OFFLOAD_PROBE_REQ_SIZE -24 -2 ; + hw->wiphy->max_sched_scan_ie_len =iwl_mvm_max_scan_ie_len (mvm); hw->wiphy->max_sched_scan_plans =IWL_MAX_SCHED_SCAN_PLANS ; hw->wiphy->max_sched_scan_plan_interval =U16_MAX ;
drivers/net/wireless/intel/iwlwifi/mvm/scan.c +2 -2
@@ -3149,8 +3149,6 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,if (ret)return ret; -iwl_mvm_build_scan_probe (mvm, vif, ies, ¶ms); -/* for 6 GHZ band only PSC channels need to be added */ for (i =0 ; i < params.n_channels; i++) {struct ieee80211_channel *channel = params.channels[i];
@@ -3184,6 +3182,8 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, goto out; } +iwl_mvm_build_scan_probe (mvm, vif, ies, ¶ms); + uid =iwl_mvm_build_scan_cmd (mvm, vif, &hcmd, ¶ms, type);if (uid <0 ) { ret = uid;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 419/1102 wifi: iwlwifi: pcie: null RX pointers after free
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 2c79d7a7b583050c9f58041465cb46fe3483ab5d ]
When iwl_pcie_tx_init() fails after RX init, nic init unwinds via iwl_pcie_rx_free().
The freed RX members stayed non-NULL on the live transport object, so later teardown or retry could touch stale RX state. Set rx_pool, global_table, rxq, and alloc_page to NULL after free to make repeated cleanup and retry paths safe.
--- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/pcie/rx.c +7 -2
@@ -1,6 +1,6 @@// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* -* Copyright (C) 2003-2014, 2018-2024 Intel Corporation +* Copyright (C) 2003-2014, 2018-2024, 2026 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */
@@ -1241,11 +1241,16 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) } }kfree (trans_pcie->rx_pool); + trans_pcie->rx_pool =NULL ;kfree (trans_pcie->global_table); + trans_pcie->global_table =NULL ;kfree (trans_pcie->rxq); + trans_pcie->rxq =NULL ; -if (trans_pcie->alloc_page) +if (trans_pcie->alloc_page) {__free_pages (trans_pcie->alloc_page, trans_pcie->rx_page_order); + trans_pcie->alloc_page =NULL ; + } } static void iwl_pcie_rx_move_to_allocator(struct iwl_rxq *rxq,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 420/1102 ALSA: hda/realtek: Add quirk for HP EliteBook 830 G8 (8AB8) to enable mute LEDs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcel Kłos <[email protected]>
[ Upstream commit 728d34ebf91c0e80b63a66b237dd0dfc5a8e5b4d ]
The sound and microphone mute LEDs do not function on this newer revision of the board (8AB8) while they do on the older 880D models. I have verified this on another laptop which was manufactured before the one with the issue.
Added the ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED from a G9 model, which uses the same codec, to make it work. Tested on kernel version 7.1.3 on the aforementioned newer revision notebook.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -11007,6 +11007,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x103c ,0x8aa3 ,"HP ProBook 450 G9 (MB 8AA1)" ,ALC236_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8aa8 ,"HP EliteBook 640 G9 (MB 8AA6)" ,ALC236_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8aab ,"HP EliteBook 650 G9 (MB 8AA9)" ,ALC236_FIXUP_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x8ab8 ,"HP EliteBook 830 G8 Notebook PC (MB 8AB8)" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8ab9 ,"HP EliteBook 840 G8 (MB 8AB8)" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8abb ,"HP ZBook Firefly 14 G9" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ), SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 421/1102 blk-cgroup: fix leaks and online flag on radix_tree_insert failure
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tao Cui <[email protected]>
[ Upstream commit dbbca20764382b4d411ec2918f4e278ffe547acc ]
When radix_tree_insert() fails in blkg_create(), the error path has two issues:
1. blkg->online is set to true unconditionally, even when the blkg was never fully inserted. Move the assignment inside the success block.
2. The error path calls blkg_put() without first calling percpu_ref_kill(). Because the refcount is still in percpu mode, percpu_ref_put() only does this_cpu_sub() without checking for zero, so blkg_release() is never triggered. This permanently leaks the blkg memory, its percpu iostat, policy data, the parent blkg reference, and the cgroup css reference — the latter preventing the cgroup from ever being destroyed.
Fix by replacing blkg_put() with percpu_ref_kill(), matching the pattern used in blkg_destroy().
--- block/blk-cgroup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
block/blk-cgroup.c +2 -2
@@ -432,15 +432,15 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg, struct gendisk *disk, blkg->pd[i]->online = true; } } + blkg->online = true; } - blkg->online = true;spin_unlock (&blkcg->lock);if (!ret)return blkg;/* @blkg failed fully initialized, use the usual release path */ -blkg_put (blkg); +percpu_ref_kill (&blkg->refcnt);return ERR_PTR (ret); err_put_css:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 422/1102 smb/client: flush dirty data before punching a hole
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <[email protected]>
[ Upstream commit d7d2adcd022baade5cab65ca492ce63421ce3a6e ]
Punching a hole after a large buffered write may leave the range reported as data. Reproduce it with:
xfs_io -f \
-c "pwrite -b 3m -S 0x61 0 3m" \
-c "fpunch 1m 1m" \
-c "seek -h 0" \
-c "seek -d 1m" \
/mnt/test/reproPunching 1 MiB at offset 1 MiB should produce:
0 1 MiB 2 MiB 3 MiB | DATA | HOLE | DATA | EOF
Instead, the entire file is reported as data. SEEK_HOLE(0) returns EOF, and SEEK_DATA(1M) returns 1M.
This happens because a dirty folio spanning the punched range can be written back after the punch and refill the hole.
Fix this by flushing and waiting for dirty data in the punched range before invalidating the page cache and issuing FSCTL_SET_ZERO_DATA.
The xfstests generic/539 pass against Samba/ksmbd with this change.
--- fs/smb/client/smb2ops.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/smb/client/smb2ops.c +9 -0
@@ -3391,6 +3391,15 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, goto out;filemap_invalidate_lock (inode->i_mapping); +/* +* Flush dirty data first, otherwise a dirty folio spanning the punched +* range may be written back after the ioctl and refill the hole. +*/ + rc =filemap_write_and_wait_range (inode->i_mapping, offset, + offset + len -1 ); +if (rc <0 ) + goto unlock; +/* * We implement the punch hole through ioctl, so we need remove the page * caches first, otherwise the data may be inconsistent with the server.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 423/1102 ASoC: Intel: sof_sdw: Add quirks for new Dell laptops
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Keepax <[email protected]>
[ Upstream commit efd80de2de9d06ddf0eee55ca11b04e39bfc7cd8 ]
A couple of new Dell laptops are shipping using the sidecar amp configuration. Add the required kernel quirk to enable.
--- sound/soc/intel/boards/sof_sdw.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/intel/boards/sof_sdw.c +2 -0
@@ -687,6 +687,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { };static const struct snd_pci_quirk sof_sdw_ssid_quirk_table[] = { +SND_PCI_QUIRK (0x1028 ,0x0e53 ,"Dell XPS WCL" ,SOC_SDW_SIDECAR_AMPS ), +SND_PCI_QUIRK (0x1028 ,0x0e54 ,"Dell XPS PTL" ,SOC_SDW_SIDECAR_AMPS ),SND_PCI_QUIRK (0x1043 ,0x1e13 ,"ASUS Zenbook S14" ,SOC_SDW_CODEC_MIC ),SND_PCI_QUIRK (0x1043 ,0x1f43 ,"ASUS Zenbook S16" ,SOC_SDW_CODEC_MIC ), {}
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 424/1102 wifi: iwlwifi: mvm: validate TX_CMD response layout
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 8d70881707b47353359df57df12f6de67fdacdd2 ]
TX_CMD parsing uses frame_count to walk status entries and then read the trailing SCD SSN. Make the minimum-length check follow that exact runtime layout calculation before parsing the payload.
For new TX API, reject TX_CMD responses with frame_count != 1 and warn/return in the aggregation handler to document that aggregated accounting is expected via BA notifications.
--- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+)
drivers/net/wireless/intel/iwlwifi/mvm/tx.c +34 -0
@@ -1690,6 +1690,17 @@ static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm *mvm,return val &0xFFF ; } +static inline size_t iwl_mvm_tx_resp_min_len (struct iwl_mvm *mvm, +struct iwl_tx_resp *tx_resp) +{ +struct agg_tx_status *agg_status = +iwl_mvm_get_agg_status (mvm, tx_resp); + +/* The aggregate response ends with a trailing SCD SSN __le32 word. */ +return (u8 *)(agg_status + tx_resp->frame_count) - (u8 *)tx_resp + +sizeof (__le32); +} +static void iwl_mvm_rx_tx_cmd_single (struct iwl_mvm *mvm,struct iwl_rx_packet *pkt) {
@@ -1998,6 +2009,9 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,int queue =SEQ_TO_QUEUE (sequence);struct ieee80211_sta *sta; +if (WARN_ON_ONCE (iwl_mvm_has_new_tx_api (mvm))) +return ; +if (WARN_ON_ONCE (queue <IWL_MVM_DQA_MIN_DATA_QUEUE && (queue !=IWL_MVM_DQA_BSS_CLIENT_QUEUE )))return ;
@@ -2032,6 +2046,26 @@ void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) {struct iwl_rx_packet *pkt =rxb_addr (rxb);struct iwl_tx_resp *tx_resp = (void *)pkt->data; +size_t min_len; + +if (IWL_FW_CHECK (mvm, !tx_resp->frame_count, +"invalid TX_CMD frame_count %u\n" , + tx_resp->frame_count)) +return ; + +if (IWL_FW_CHECK (mvm, +iwl_mvm_has_new_tx_api (mvm) && + tx_resp->frame_count !=1 , +"invalid TX_CMD frame_count %u for new TX API\n" , + tx_resp->frame_count)) +return ; + + min_len =iwl_mvm_tx_resp_min_len (mvm, tx_resp); +if (IWL_FW_CHECK (mvm,iwl_rx_packet_payload_len (pkt) < min_len, +"invalid TX_CMD len %u (frame_count %u, min %zu)\n" , +iwl_rx_packet_payload_len (pkt), tx_resp->frame_count, + min_len)) +return ;if (tx_resp->frame_count ==1 )iwl_mvm_rx_tx_cmd_single (mvm, pkt);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 425/1102 wifi: iwlwifi: mvm: fix a possible underflow
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 0cb5260a1027a43f8cdb961e128f2ddd42e46832 ]
We shouldn't trust the firmware about the length of the wowlan packet.
--- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/d3.c +15 -4
@@ -1536,6 +1536,10 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,if (WARN_ON_ONCE (truncated <0 )) truncated =0 ; +/* this would be a firmware bug */ +if (WARN_ON_ONCE (pktsize <sizeof (*hdr))) +return ; +if (ieee80211_is_data (hdr->frame_control)) {int hdrlen =ieee80211_hdrlen (hdr->frame_control);int ivlen =0 , icvlen =4 ;/* also FCS */
@@ -1544,10 +1548,6 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,if (!pkt) goto report; -skb_put_data (pkt, pktdata, hdrlen); - pktdata += hdrlen; - pktsize -= hdrlen; -if (ieee80211_has_protected (hdr->frame_control)) {/* * This is unlocked and using gtk_i(c)vlen,
@@ -1573,6 +1573,17 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, truncated =0 ; } +if (IWL_FW_CHECK (mvm, + pktsize <= hdrlen + ivlen + icvlen, +"pktsize is too small %d\n" , + pktsize)) { +kfree_skb (pkt); +return ; + } + +skb_put_data (pkt, pktdata, hdrlen); + pktdata += hdrlen; + pktsize -= hdrlen; pktsize -= ivlen + icvlen; pktdata += ivlen;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 426/1102 arm64: fixmap: Allow 256K early_ioremap() at any offset
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Peng <[email protected]>
[ Upstream commit 21fc7ec93f8b633b60d5bddef2f1529ff6b36185 ]
NR_FIX_BTMAPS is the per-slot page limit for early_ioremap(). Since __early_ioremap() maps the page-aligned physical range, a 256K request can require one extra page when the physical address is not page-aligned.
Reserve one extra page per slot so the 256K mapping budget is usable regardless of the initial page offset.
--- arch/arm64/include/asm/fixmap.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm64/include/asm/fixmap.h +5 -1
@@ -72,8 +72,12 @@ enum fixed_addresses {/* * Temporary boot-time mappings, used by early_ioremap(), * before ioremap() is functional. +* +* Reserve one extra page so a 256K mapping may start at any +* offset within a page. early_ioremap() maps the page-aligned +* physical range, so the initial offset can consume an extra page. */ -#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE) +#define NR_FIX_BTMAPS ((SZ_256K / PAGE_SIZE) + 1)#define FIX_BTMAPS_SLOTS 7#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 427/1102 wifi: iwlwifi: mvm: add a check on the tid coming from the firmware
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 0e4c0d83267261cf67ec9690856edf4a56bb7dfc ]
ba_notif->tid is a firmware-controlled u8 that is used directly as an array index into tid_data[] without any validation. Add a bounds check against IWL_MAX_TID_COUNT before dereferencing the array.
--- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/intel/iwlwifi/mvm/tx.c +3 -0
@@ -2308,6 +2308,9 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) ba_notif = (void *)pkt->data; sta_id = ba_notif->sta_id; tid = ba_notif->tid; +if (IWL_FW_CHECK (mvm, tid >=ARRAY_SIZE (mvmsta->tid_data), +"invalid TID %d in BA notif\n" , tid)) +return ;/* "flow" corresponds to Tx queue */ txq =le16_to_cpu (ba_notif->scd_flow);/* "ssn" is start of block-ack Tx window, corresponds to index
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 428/1102 wifi: iwlwifi: mvm: fix out-of-bounds tid_data access in BA notif
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 94d3982806c7f194b23484befde12934dda23064 ]
mvmsta->tid_data was indexed by the TFD loop counter 'i' instead of the actual TID value 'tid'. This writes lq_color into a random tid_data slot unrelated to the BA entry.
Since multi-TID blockack is not really in use, 'i' was always 0 and no harm was done.
Add a out-of-bound check before accessing the array.
--- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/tx.c +7 -1
@@ -2284,8 +2284,14 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)if (tid ==IWL_MGMT_TID ) tid =IWL_MAX_TID_COUNT ; +if (IWL_FW_CHECK (mvm, tid >= +ARRAY_SIZE (mvmsta->tid_data), +"invalid TID %d in compressed BA\n" , + tid)) +continue ; +if (mvmsta) - mvmsta->tid_data[i].lq_color = lq_color; + mvmsta->tid_data[tid].lq_color = lq_color; iwl_mvm_tx_reclaim(mvm, sta_id, tid, (int)(le16_to_cpu(ba_tfd->q_num)),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 429/1102 arm64: kprobes: Allow reentering kprobes while single-stepping
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pu Hu <[email protected]>
[ Upstream commit 23f851ac0078a908bf3422d6467ebc1db5828c46 ]
A kprobe can be hit while another kprobe is in KPROBE_HIT_SS state. This can happen when tracing or perf code runs from the debug exception path while the first kprobe is preparing or executing its out-of-line single-step instruction.
Currently arm64 treats a kprobe hit in KPROBE_HIT_SS as unrecoverable, the same as a hit in KPROBE_REENTER. This is too strict. A hit in KPROBE_HIT_SS is still a one-level reentry and can be handled by saving the current kprobe state and setting up single-step for the new probe, just like reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE.
The truly unrecoverable case is hitting another kprobe while already in KPROBE_REENTER, because the reentry save area has already been consumed.
Move KPROBE_HIT_SS to the recoverable reentry cases and leave KPROBE_REENTER as the unrecoverable nested reentry case.
This change also requires saving saved_irqflag in struct prev_kprobe. When a nested kprobe calls kprobes_save_local_irqflag(), it overwrites kcb->saved_irqflag with the currently masked DAIF value, losing the outer kprobe's original DAIF state. Without this fix, when the outer kprobe's single-step finishes, kprobes_restore_local_irqflag() applies the wrong DAIF mask and leaves interrupts permanently disabled.
Extend struct prev_kprobe with a saved_irqflag field and save/restore it alongside kp and status. This ensures the outer kprobe's original interrupt state is preserved across reentry.
This mirrors the x86 fix in commit 6a5022a56ac3 ("kprobes/x86: Allow to handle reentered kprobe on single-stepping").
--- arch/arm64/include/asm/kprobes.h | 6 ++++++ arch/arm64/kernel/probes/kprobes.c | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-)
arch/arm64/include/asm/kprobes.h +6 -0
@@ -26,6 +26,12 @@struct prev_kprobe {struct kprobe *kp;unsigned int status; + +/* +* The original DAIF state of the outer kprobe, saved here before +* a nested kprobe overwrites kcb->saved_irqflag during reentry. +*/ +unsigned long saved_irqflag; };/* per-cpu kprobe control block */
arch/arm64/kernel/probes/kprobes.c +22 -1
@@ -173,12 +173,27 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) { kcb->prev_kprobe.kp =kprobe_running (); kcb->prev_kprobe.status = kcb->kprobe_status; + +/* +* Save the outer kprobe's original DAIF flags before the nested +* kprobe calls kprobes_save_local_irqflag() and overwrites +* kcb->saved_irqflag. Without this, the outer kprobe will restore +* the wrong DAIF state and leave interrupts permanently masked. +*/ + kcb->prev_kprobe.saved_irqflag = kcb->saved_irqflag; }static void __kprobes restore_previous_kprobe (struct kprobe_ctlblk *kcb) {__this_cpu_write (current_kprobe, kcb->prev_kprobe.kp); kcb->kprobe_status = kcb->prev_kprobe.status; + +/* +* Restore the outer kprobe's saved_irqflag so that when its +* single-step completes, kprobes_restore_local_irqflag() uses +* the correct original DAIF value. +*/ + kcb->saved_irqflag = kcb->prev_kprobe.saved_irqflag; }static void __kprobes set_current_kprobe (struct kprobe *p)
@@ -239,10 +254,16 @@ static int __kprobes reenter_kprobe(struct kprobe *p,switch (kcb->kprobe_status) {case KPROBE_HIT_SSDONE :case KPROBE_HIT_ACTIVE : +case KPROBE_HIT_SS : +/* +* A probe can be hit while another kprobe is preparing or +* executing its XOL single-step instruction. This is still a +* recoverable one-level reentry, so handle it in the same way as +* reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE. +*/ kprobes_inc_nmissed_count (p);setup_singlestep (p, regs, kcb,1 );break ; -case KPROBE_HIT_SS :case KPROBE_REENTER :pr_warn ("Failed to recover from reentered kprobes.\n" );dump_kprobe (p);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 430/1102 drm/amd/pm/si: Dont schedule thermal work when queue isnt initialized
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit f8922d5a946699fc2bdc7660e6778bd6726bf8b8 ]
When DPM is turned off with the amdgpu.dpm=0 module parameter, the thermal work queue isn't initialized so we shouldn't schedule any work on it.
--- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +1 -1
@@ -7666,7 +7666,7 @@ static int si_dpm_process_interrupt(struct amdgpu_device *adev,break ; } -if (queue_thermal) +if (queue_thermal && amdgpu_dpm)schedule_work (&adev->pm.dpm.thermal.work);return 0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 431/1102 ALSA: hda/realtek: Add quirk for HP Pavilion x360
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 02bbbf05d19f49c5cc9f249dd8844b2a7f2a2b8c ]
HP Pavilion x360 sets a bogus PCI SSID (103c:0000), hence the driver picks up a wrong quirk entry, resulting in an almost silent output. And yet, the existing quirk for x390 doesn't seem sufficing, and we need the extra setup for the amp.
This patch adds the quirk entry for the codec SSID (103c:8486) to initialize the amp via COEF verbs and chains to the existing quirk for another x360 model to address the silent output.
--- sound/pci/hda/patch_realtek.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
sound/pci/hda/patch_realtek.c +15 -0
@@ -8087,6 +8087,7 @@ enum {ALC256_FIXUP_HUAWEI_MACH_WX9_PINS ,ALC298_FIXUP_HUAWEI_MBX_STEREO ,ALC295_FIXUP_HP_X360 , +ALC295_FIXUP_HP_PAVILION_X360 ,ALC221_FIXUP_HP_HEADSET_MIC ,ALC285_FIXUP_LENOVO_HEADPHONE_NOISE , ALC295_FIXUP_HP_AUTO_MUTE,
@@ -9372,6 +9373,19 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id =ALC269_FIXUP_HP_MUTE_LED_MIC3 }, + [ALC295_FIXUP_HP_PAVILION_X360] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb []) { +/* force amp gain and processing state */ + {0x20 ,AC_VERB_SET_COEF_INDEX ,0x07 }, + {0x20 ,AC_VERB_SET_PROC_COEF ,0x7770 }, + {0x20 ,AC_VERB_SET_COEF_INDEX ,0x0d }, + {0x20 ,AC_VERB_SET_PROC_COEF ,0x3000 }, + {} + }, + .chained = true, + .chain_id =ALC295_FIXUP_HP_X360 + }, [ALC221_FIXUP_HP_HEADSET_MIC] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl []) {
@@ -10868,6 +10882,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x103c ,0x82c0 ,"HP G3 mini premium" ,ALC221_FIXUP_HP_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x103c ,0x83b9 ,"HP Spectre x360" ,ALC269_FIXUP_HP_MUTE_LED_MIC3 ),SND_PCI_QUIRK (0x103c ,0x841c ,"HP Pavilion 15-CK0xx" ,ALC269_FIXUP_HP_MUTE_LED_MIC3 ), +HDA_CODEC_QUIRK (0x103c ,0x8486 ,"HP Pavilion x360" ,ALC295_FIXUP_HP_PAVILION_X360 ),SND_PCI_QUIRK (0x103c ,0x8497 ,"HP Envy x360" ,ALC269_FIXUP_HP_MUTE_LED_MIC3 ),SND_PCI_QUIRK (0x103c ,0x84a6 ,"HP 250 G7 Notebook PC" ,ALC269_FIXUP_HP_LINE1_MIC1_LED ), SND_PCI_QUIRK(0x103c, 0x84ae, "HP 15-db0403ng", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 432/1102 wifi: iwlwifi: bound aligned TLV advance in FW parser
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit acad742714bdc70e7fd7f234323807c596828213 ]
Validate ALIGN(tlv_len, 4) against remaining parser length before consuming bytes from the firmware image.
This avoids length underflow on malformed TLVs.
--- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/iwl-drv.c +11 -2
@@ -706,6 +706,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,u32 build, paging_mem_size;int num_of_cpus;bool usniffer_req = false; +size_t aligned_tlv_len;if (len <sizeof (*ucode)) {IWL_ERR (drv,"uCode has invalid length: %zd\n" , len);
@@ -754,8 +755,16 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, len, tlv_len);return -EINVAL ; } - len -=ALIGN (tlv_len,4 ); - data +=sizeof (*tlv) +ALIGN (tlv_len,4 ); + + aligned_tlv_len =ALIGN (tlv_len,4 ); +if (len < aligned_tlv_len) { +IWL_ERR (drv,"invalid aligned TLV len: %zd/%zu\n" , + len, aligned_tlv_len); +return -EINVAL ; + } + + len -= aligned_tlv_len; + data +=sizeof (*tlv) + aligned_tlv_len;switch (tlv_type) {case IWL_UCODE_TLV_INST :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 433/1102 ALSA: usb-audio: Add FIXED_RATE quirk for JBL Quantum650 Wireless
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel C. Ribeiro <[email protected]>
[ Upstream commit f6d6a4147ace0c417035f65b021027c209c75190 ]
JBL Quantum650 Wireless (0ecb:2125) requires the same workaround that was used for JBL Quantum610 and Quantum810 for limiting the sample rate. Without it, the capture (microphone) stream fails to work. Setting the QUIRK_FLAG_FIXED_RATE flag, as done for the sibling models, makes both playback and capture work correctly.
--- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
@@ -2265,6 +2265,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIXER_MIN_MUTE),DEVICE_FLG (0x0ecb ,0x205c ,/* JBL Quantum610 Wireless */ QUIRK_FLAG_FIXED_RATE ), +DEVICE_FLG (0x0ecb ,0x2125 ,/* JBL Quantum650 Wireless */ +QUIRK_FLAG_FIXED_RATE ),DEVICE_FLG (0x0ecb ,0x2069 ,/* JBL Quantum810 Wireless */ QUIRK_FLAG_FIXED_RATE ), DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 434/1102 wifi: iwlwifi: acpi: validate WGDS table revision index
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
[ Upstream commit 954e821f42aaca56073ca830c5fd4bcf1a89048c ]
Check tbl_rev bounds before BIT(tbl_rev) to avoid undefined shifts when firmware reports an invalid revision value.
--- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/wireless/intel/iwlwifi/fw/acpi.c +5 -0
@@ -740,6 +740,11 @@ int iwl_acpi_get_wgds_table(struct iwl_fw_runtime *fwrt) min_size, max_size, &tbl_rev);if (!IS_ERR (wifi_pkg)) { +if (tbl_rev <0 || + tbl_rev >=BITS_PER_BYTE * +sizeof (rev_data[idx].revisions)) +continue ; +if (!(BIT (tbl_rev) & rev_data[idx].revisions))continue ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 435/1102 ALSA: hda/realtek: Add HDA_CODEC_QUIRK for Samsung 750XBE/730XBE
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Heng <[email protected]>
[ Upstream commit 740b3c6780ec1f65aba2bc99a3f41d70bdb13477 ]
Add a codec SSID quirk for Samsung ELECTRONICS 750XBE/730XBE using HDA_CODEC_QUIRK() instead of SND_PCI_QUIRK(), because the alsa-info report from this device does not expose a PCI subsystem ID, only the HDA codec subsystem ID (0x144d:0xc824) is available.
This applies ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET to fix sound being very low and distorted on the headphone jack of this system.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -11363,6 +11363,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x144d ,0xc1a6 ,"Samsung Galaxy Book Pro 360 (NP930QBD)" ,ALC298_FIXUP_SAMSUNG_AMP ),SND_PCI_QUIRK (0x144d ,0xc740 ,"Samsung Ativ book 8 (NP870Z5G)" ,ALC269_FIXUP_ATIV_BOOK_8 ),SND_PCI_QUIRK (0x144d ,0xc812 ,"Samsung Notebook Pen S (NT950SBE-X58)" ,ALC298_FIXUP_SAMSUNG_AMP ), +HDA_CODEC_QUIRK (0x144d ,0xc824 ,"Samsung ELECTRONICS (750XBE/730XBE)" ,ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET ),SND_PCI_QUIRK (0x144d ,0xc830 ,"Samsung Galaxy Book Ion (NT950XCJ-X716A)" ,ALC298_FIXUP_SAMSUNG_AMP ),SND_PCI_QUIRK (0x144d ,0xc832 ,"Samsung Galaxy Book Flex Alpha (NP730QCJ)" ,ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET ), SND_PCI_QUIRK(0x144d, 0xca03, "Samsung Galaxy Book2 Pro 360 (NP930QED)", ALC298_FIXUP_SAMSUNG_AMP),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 436/1102 wifi: mwifiex: replace one-element arrays with flexible array members
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Georgi Valkov <[email protected]>
[ Upstream commit 1cb5845a58d8e1f85d5766c6fbcbfddf96c212a1 ]
Replace deprecated one-element arrays with flexible array members. CONFIG_FORTIFY_SOURCE reports the following warning when one-element arrays are used as variable-length buffers:
sta_cmd.c:1033 mwifiex_sta_prepare_cmd
memcpy: detected field-spanning write (size 84) of single field "domain->triplet" at .../marvell/mwifiex/sta_cmd.c:1033 (size 3)
Convert affected structs to use flexible array members.
- Preserve existing wire layouts.
- Use DECLARE_FLEX_ARRAY() for structs inside affected unions.
Tested-on: WRT3200ACM, OpenWrt
--- drivers/net/wireless/marvell/mwifiex/fw.h | 18 +++++++++--------- drivers/net/wireless/marvell/mwifiex/join.c | 8 ++++---- drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-)
drivers/net/wireless/marvell/mwifiex/fw.h +9 -9
@@ -818,7 +818,7 @@ struct chan_band_param_set {struct mwifiex_ie_types_chan_band_list_param_set {struct mwifiex_ie_types_header header; -struct chan_band_param_set chan_band_param[1 ]; +struct chan_band_param_set chan_band_param[]; } __packed;struct mwifiex_ie_types_rates_param_set {
@@ -881,7 +881,7 @@ struct mwifiex_ie_types_wildcard_ssid_params {#define TSF_DATA_SIZE 8struct mwifiex_ie_types_tsf_timestamp {struct mwifiex_ie_types_header header; -u8 tsf_data[1 ]; +u8 tsf_data[]; } __packed;struct mwifiex_cf_param_set {
@@ -898,8 +898,8 @@ struct mwifiex_ibss_param_set {struct mwifiex_ie_types_ss_param_set {struct mwifiex_ie_types_header header;union { -struct mwifiex_cf_param_set cf_param_set[1 ]; -struct mwifiex_ibss_param_set ibss_param_set[1 ]; + DECLARE_FLEX_ARRAY(struct mwifiex_cf_param_set, cf_param_set); + DECLARE_FLEX_ARRAY(struct mwifiex_ibss_param_set, ibss_param_set); } cf_ibss; } __packed;
@@ -917,8 +917,8 @@ struct mwifiex_ds_param_set {struct mwifiex_ie_types_phy_param_set {struct mwifiex_ie_types_header header;union { -struct mwifiex_fh_param_set fh_param_set[1 ]; -struct mwifiex_ds_param_set ds_param_set[1 ]; + DECLARE_FLEX_ARRAY(struct mwifiex_fh_param_set, fh_param_set); + DECLARE_FLEX_ARRAY(struct mwifiex_ds_param_set, ds_param_set); } fh_ds; } __packed;
@@ -1378,7 +1378,7 @@ struct host_cmd_ds_802_11_snmp_mib {__le16 query_type;__le16 oid;__le16 buf_size; -u8 value[1 ]; +u8 value[]; } __packed;struct mwifiex_rate_scope {
@@ -1546,7 +1546,7 @@ struct mwifiex_scan_cmd_config {* TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set * WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set */ -u8 tlv_buf[1 ];/* SSID TLV(s) and ChanList TLVs are stored +u8 tlv_buf[];/* SSID TLV(s) and ChanList TLVs are stored here */ } __packed;
@@ -1678,7 +1678,7 @@ struct host_cmd_ds_802_11_bg_scan_query_rsp {struct mwifiex_ietypes_domain_param_set {struct mwifiex_ie_types_header header;u8 country_code[IEEE80211_COUNTRY_STRING_LEN ]; -struct ieee80211_country_ie_triplet triplet[1 ]; +struct ieee80211_country_ie_triplet triplet[]; } __packed;struct host_cmd_ds_802_11d_domain_info {
drivers/net/wireless/marvell/mwifiex/join.c +4 -4
@@ -421,15 +421,15 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos; phy_tlv->header.type =cpu_to_le16 (WLAN_EID_DS_PARAMS ); - phy_tlv->header.len =cpu_to_le16 (sizeof (phy_tlv->fh_ds.ds_param_set)); -memcpy (&phy_tlv->fh_ds.ds_param_set, + phy_tlv->header.len =cpu_to_le16 (sizeof (*phy_tlv->fh_ds.ds_param_set)); +memcpy (phy_tlv->fh_ds.ds_param_set, &bss_desc->phy_param_set.ds_param_set.current_chan, -sizeof (phy_tlv->fh_ds.ds_param_set)); +sizeof (*phy_tlv->fh_ds.ds_param_set)); pos +=sizeof (phy_tlv->header) +le16_to_cpu (phy_tlv->header.len); ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos; ss_tlv->header.type =cpu_to_le16 (WLAN_EID_CF_PARAMS ); - ss_tlv->header.len =cpu_to_le16 (sizeof (ss_tlv->cf_ibss.cf_param_set)); + ss_tlv->header.len =cpu_to_le16 (sizeof (*ss_tlv->cf_ibss.cf_param_set)); pos +=sizeof (ss_tlv->header) +le16_to_cpu (ss_tlv->header.len);/* Get the common rates supported between the driver and the BSS Desc */
drivers/net/wireless/marvell/mwifiex/sta_cmd.c +1 -1
@@ -108,7 +108,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); cmd->command =cpu_to_le16 (HostCmd_CMD_802_11_SNMP_MIB); cmd->size =cpu_to_le16 (sizeof (struct host_cmd_ds_802_11_snmp_mib ) - -1 +S_DS_GEN ); + +S_DS_GEN ); snmp_mib->oid =cpu_to_le16 ((u16 )cmd_oid);if (cmd_action == HostCmd_ACT_GEN_GET) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 437/1102 smb: client: bound dirent name against end of SMB response in cifs_filldir
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jay Vadayath <[email protected]>
[ Upstream commit f8cf09a53a0dc1da298e9dd0ba5f21710cf119d6 ]
cifs_filldir() copies the entry name out of an SMB1 TRANS2_FIND_FIRST / FIND_NEXT response using a length (de.namelen) supplied by the server. The kmalloc'd SMB response buffer is bounded, but nothing checks that de.name + de.namelen still lies inside that buffer before the eventual filldir64() -> verify_dirent_name() -> memchr() reads namelen bytes.
A hostile SMB1 server that returns an oversized FileNameLength in a directory entry therefore causes memchr() to read past the end of the response slab buffer. Reachable from any user who can list a directory on a CIFS mount served by an attacker-controlled server (getdents64() on the mounted directory):
BUG: KASAN: slab-out-of-bounds in memchr+0x71/0x80 Read of size 1 at addr ffff88800e0640cc by task poc/115 Call Trace: dump_stack_lvl+0x64/0x80 print_report+0xce/0x620 kasan_report+0xec/0x120 memchr+0x71/0x80 filldir64+0x4c/0x6a0 cifs_filldir.constprop.0+0x9bb/0x1e00 cifs_readdir+0x2101/0x3380 iterate_dir+0x19c/0x520 __x64_sys_getdents64+0x126/0x210 do_syscall_64+0x107/0x5a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Pass the end-of-response pointer down to cifs_filldir() and reject entries whose name would extend past that boundary.
This bug was discovered by Artiphishell's vTriage pipeline, which generated a userspace reproducer (an emulated hostile SMB1 server plus a getdents64() client) that reliably triggers the KASAN report on an unpatched kernel. The fix below was drafted with the Claude coding assistant; a userspace reproducer is available on request.
--- fs/smb/client/readdir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
fs/smb/client/readdir.c +7 -2
@@ -934,7 +934,7 @@ static bool cifs_dir_emit(struct dir_context *ctx,static int cifs_filldir (char *find_entry,struct file *file,struct dir_context *ctx,char *scratch_buf,unsigned int max_len, -struct cached_fid *cfid) +char *end_of_smb,struct cached_fid *cfid) {struct cifsFileInfo *file_info = file->private_data;struct super_block *sb =file_inode (file)->i_sb;
@@ -955,6 +955,11 @@ static int cifs_filldir(char *find_entry, struct file *file,return -EINVAL ; } +if (de.name + de.namelen > end_of_smb) { +cifs_dbg (VFS ,"search entry name extends past end of SMB\n" ); +return -EINVAL ; + } +/* skip . and .. since we added them first */ if (cifs_entry_is_dot (&de, file_info->srch_inf.unicode))return 0 ;
@@ -1175,7 +1180,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)*/ *tmp_buf =0 ; rc =cifs_filldir (current_entry, file, ctx, - tmp_buf, max_len, cfid); + tmp_buf, max_len, end_of_smb, cfid);if (rc) {if (rc >0 ) rc =0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 438/1102 regulator: core: clamp voltage constraints before applying apply_uV
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kamal Wadhwa <[email protected]>
[ Upstream commit a45cc646a3aa83eb4ab4c7ed2685785ea51dc5e6 ]
machine_constraints_voltage() currently applies apply_uV against the machine-supplied [min_uV, max_uV] range, and only afterwards clamps that range down to what the regulator can actually supply (via ops->list_voltage()).
If the machine-supplied range is wider than the regulator's actual range, apply_uV's rounding can pick a selector outside the (correct) clamped range, so the regulator ends up programmed outside its clamped min/max. At bring-up this shows up as a voltage read-back outside the clamped range.
Fix this by moving the clamping block ahead of the apply_uV block, so apply_uV always targets an already-clamped range. Whether apply_uV should run is decided from the unclamped constraints beforehand and stored in a local bool, since clamping must not itself change whether apply_uV fires.
No functional change to the clamping logic itself, only its position relative to apply_uV. Its early return 0 exits become fallthroughs since the apply_uV logic now follows it.
--- drivers/regulator/core.c | 163 +++++++++++++++++++++------------------ 1 file changed, 90 insertions(+), 73 deletions(-)
drivers/regulator/core.c +90 -73
@@ -1180,10 +1180,98 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, {const struct regulator_ops *ops = rdev->desc->ops;int ret; +bool apply_uV; + +/* +* Decide up front, from the constraints as handed to us, whether +* apply_uV needs to run below. The clamping pass right after this +* may rewrite constraints->min_uV/max_uV (e.g. the fixed-voltage +* autoconfigure case), and we don't want that to change whether +* apply_uV fires. +*/ + apply_uV = rdev->constraints->apply_uV && + rdev->constraints->min_uV && rdev->constraints->max_uV; + +/* +* Constrain machine-level voltage specs to fit the actual range +* supported by this regulator before apply_uV (below) tries to +* force hardware to a value from that range: otherwise apply_uV +* can target a constraint value that doesn't correspond to any +* real voltage selector and fail registration outright, even +* though the clamping pass would have narrowed it to a value +* the regulator can actually hit. +*/ +if (ops->list_voltage && rdev->desc->n_voltages) { +int count = rdev->desc->n_voltages; +int i; +int min_uV =INT_MAX ; +int max_uV =INT_MIN ; +int cmin = constraints->min_uV; +int cmax = constraints->max_uV; + +/* it's safe to autoconfigure fixed-voltage supplies +* and the constraints are used by list_voltage. +*/ +if (count ==1 && !cmin) { + cmin =1 ; + cmax =INT_MAX ; + constraints->min_uV = cmin; + constraints->max_uV = cmax; + } + +/* voltage constraints are optional */ +if ((cmin ==0 ) && (cmax ==0 )) { +/* nothing more to do */ + +/* else require explicit machine-level constraints */ + }else if (cmin <=0 || cmax <=0 || cmax < cmin) { +rdev_err (rdev,"invalid voltage constraints\n" ); +return -EINVAL ; + +/* no need to loop voltages if range is continuous */ + }else if (rdev->desc->continuous_voltage_range) { +/* nothing more to do */ + + }else { +/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ +for (i =0 ; i < count; i++) { +int value; + + value = ops->list_voltage (rdev, i); +if (value <=0 ) +continue ; + +/* maybe adjust [min_uV..max_uV] */ +if (value >= cmin && value < min_uV) + min_uV = value; +if (value <= cmax && value > max_uV) + max_uV = value; + } + +/* final: [min_uV..max_uV] valid iff constraints valid */ +if (max_uV < min_uV) { +rdev_err (rdev, +"unsupportable voltage constraints %u-%uuV\n" , + min_uV, max_uV); +return -EINVAL ; + } + +/* use regulator's subset of machine constraints */ +if (constraints->min_uV < min_uV) { +rdev_dbg (rdev,"override min_uV, %d -> %d\n" , + constraints->min_uV, min_uV); + constraints->min_uV = min_uV; + } +if (constraints->max_uV > max_uV) { +rdev_dbg (rdev,"override max_uV, %d -> %d\n" , + constraints->max_uV, max_uV); + constraints->max_uV = max_uV; + } + } + }/* do we need to apply the constraint voltage */ -if (rdev->constraints->apply_uV && - rdev->constraints->min_uV && rdev->constraints->max_uV) { +if (apply_uV) {int target_min, target_max;int current_uV =regulator_get_voltage_rdev (rdev);
@@ -1238,77 +1326,6 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, } } -/* constrain machine-level voltage specs to fit -* the actual range supported by this regulator. -*/ -if (ops->list_voltage && rdev->desc->n_voltages) { -int count = rdev->desc->n_voltages; -int i; -int min_uV =INT_MAX ; -int max_uV =INT_MIN ; -int cmin = constraints->min_uV; -int cmax = constraints->max_uV; - -/* it's safe to autoconfigure fixed-voltage supplies -* and the constraints are used by list_voltage. -*/ -if (count ==1 && !cmin) { - cmin =1 ; - cmax =INT_MAX ; - constraints->min_uV = cmin; - constraints->max_uV = cmax; - } - -/* voltage constraints are optional */ -if ((cmin ==0 ) && (cmax ==0 )) -return 0 ; - -/* else require explicit machine-level constraints */ -if (cmin <=0 || cmax <=0 || cmax < cmin) { -rdev_err (rdev,"invalid voltage constraints\n" ); -return -EINVAL ; - } - -/* no need to loop voltages if range is continuous */ -if (rdev->desc->continuous_voltage_range) -return 0 ; - -/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ -for (i =0 ; i < count; i++) { -int value; - - value = ops->list_voltage (rdev, i); -if (value <=0 ) -continue ; - -/* maybe adjust [min_uV..max_uV] */ -if (value >= cmin && value < min_uV) - min_uV = value; -if (value <= cmax && value > max_uV) - max_uV = value; - } - -/* final: [min_uV..max_uV] valid iff constraints valid */ -if (max_uV < min_uV) { -rdev_err (rdev, -"unsupportable voltage constraints %u-%uuV\n" , - min_uV, max_uV); -return -EINVAL ; - } - -/* use regulator's subset of machine constraints */ -if (constraints->min_uV < min_uV) { -rdev_dbg (rdev,"override min_uV, %d -> %d\n" , - constraints->min_uV, min_uV); - constraints->min_uV = min_uV; - } -if (constraints->max_uV > max_uV) { -rdev_dbg (rdev,"override max_uV, %d -> %d\n" , - constraints->max_uV, max_uV); - constraints->max_uV = max_uV; - } - } -return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 439/1102 wifi: mac80211_hwsim: reject undersized HWSIM_ATTR_TX_INFO
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ibrahim Hashimov <[email protected]>
[ Upstream commit 3dc723ac78a6e4fa0fd49e27e487ed319da40a9f ]
hwsim_tx_info_frame_received_nl() casts the HWSIM_ATTR_TX_INFO payload to a struct hwsim_tx_rate * and unconditionally reads IEEE80211_TX_MAX_RATES entries (8 bytes) from it. The policy only bounds the attribute from above (NLA_BINARY .len is a maximum) and the op sets GENL_DONT_VALIDATE_STRICT, so a short or zero-length attribute is accepted and the loop reads past the payload.
Require the exact length in the policy, so a malformed attribute is rejected before the handler runs.
--- drivers/net/wireless/virtual/mac80211_hwsim.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/virtual/mac80211_hwsim.c +3 -3
@@ -903,9 +903,9 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { [HWSIM_ATTR_FLAGS] = { .type = NLA_U32 }, [HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 }, [HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 }, - [HWSIM_ATTR_TX_INFO] = { .type = NLA_BINARY, - .len =IEEE80211_TX_MAX_RATES * - sizeof(struct hwsim_tx_rate)}, + [HWSIM_ATTR_TX_INFO ] = +NLA_POLICY_EXACT_LEN (IEEE80211_TX_MAX_RATES * + sizeof(struct hwsim_tx_rate)), [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 }, [HWSIM_ATTR_CHANNELS] = { .type = NLA_U32 }, [HWSIM_ATTR_RADIO_ID] = { .type = NLA_U32 },
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 440/1102 ksmbd: preserve VFS inherited POSIX ACL mask
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit e148e567a9252643baa125cb65d7ae9c2c6cf68a ]
The VFS initializes a child's POSIX ACL from the parent's default ACL and the requested creation mode. Do not mutate the parent ACL or overwrite the child's VFS-computed access and default ACLs afterwards.
This preserves restrictive ACL_MASK entries and prevents SMB object creation from widening effective permissions.
--- fs/smb/server/vfs.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-)
fs/smb/server/vfs.c +1 -25
@@ -1965,10 +1965,6 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap, struct path *path, struct inode *parent_inode) { struct posix_acl *acls; -struct posix_acl_entry *pace; -struct dentry *dentry = path->dentry; -struct inode *inode =d_inode (dentry); -int rc, i;if (!IS_ENABLED (CONFIG_FS_POSIX_ACL ))return -EOPNOTSUPP ;
@@ -1976,27 +1972,7 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap, acls =get_inode_acl (parent_inode,ACL_TYPE_DEFAULT );if (IS_ERR_OR_NULL (acls))return -ENOENT ; - pace = acls->a_entries; - -for (i =0 ; i < acls->a_count; i++, pace++) { -if (pace->e_tag ==ACL_MASK ) { - pace->e_perm =0x07 ; -break ; - } - } - - rc =set_posix_acl (idmap, dentry,ACL_TYPE_ACCESS , acls); -if (rc <0 ) -ksmbd_debug (SMB ,"Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n" , - rc); -if (S_ISDIR (inode->i_mode)) { - rc =set_posix_acl (idmap, dentry,ACL_TYPE_DEFAULT , - acls); -if (rc <0 ) -ksmbd_debug (SMB ,"Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n" , - rc); - }posix_acl_release (acls); -return rc; +return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 441/1102 drm/gma500: return errors from Oaktrail HDMI I2C reads
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit 9b5ce5c496efd20c1c662cedba88465d39ec1f93 ]
xfer_read() waits for the HDMI I2C transaction to reach I2C_TRANSACTION_DONE, but it ignores both timeout and signal returns from wait_for_completion_interruptible_timeout(). If the interrupt never advances the transaction state, the loop can wait forever.
Return -ETIMEDOUT when the completion wait expires, propagate interrupted waits, and make the I2C master_xfer callback return the first transfer error instead of reporting a successful message count.
--- drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c +16 -5
@@ -95,6 +95,7 @@ static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)struct oaktrail_hdmi_dev *hdmi_dev =i2c_get_adapdata (adap);struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;u32 temp; +int ret; i2c_dev->status =I2C_STAT_INIT ; i2c_dev->msg = pmsg;
@@ -106,9 +107,14 @@ static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)HDMI_WRITE (HDMI_HI2CHCR , temp);HDMI_READ (HDMI_HI2CHCR ); -while (i2c_dev->status !=I2C_TRANSACTION_DONE ) -wait_for_completion_interruptible_timeout (&i2c_dev->complete, +while (i2c_dev->status !=I2C_TRANSACTION_DONE ) { + ret =wait_for_completion_interruptible_timeout (&i2c_dev->complete,10 *HZ ); +if (ret <0 ) +return ret; +if (!ret) +return -ETIMEDOUT ; + }return 0 ; }
@@ -127,7 +133,7 @@ static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap, {struct oaktrail_hdmi_dev *hdmi_dev =i2c_get_adapdata (adap);struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; -int i; +int i, ret =0 ;mutex_lock (&i2c_dev->i2c_lock);
@@ -139,9 +145,11 @@ static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap,for (i =0 ; i < num; i++) {if (pmsg->len && pmsg->buf) {if (pmsg->flags &I2C_M_RD ) -xfer_read (adap, pmsg); + ret =xfer_read (adap, pmsg);else -xfer_write (adap, pmsg); + ret =xfer_write (adap, pmsg); +if (ret) +break ; } pmsg++;/* next message */ }
@@ -151,6 +159,9 @@ static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap,mutex_unlock (&i2c_dev->i2c_lock); +if (ret) +return ret; +return i; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 442/1102 phonet: check register_netdevice_notifier() error in phonet_device_init()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Minhong He <[email protected]>
[ Upstream commit d1ff66b66151c14b084e88040512a064b1c1e493 ]
phonet_device_init() registers a netdevice notifier before calling phonet_netlink_register(), but does not check whether notifier registration succeeded. On failure, netlink setup still proceeds and init may return success without the notifier in place.
Also, the existing phonet_netlink_register() failure path called phonet_device_exit(), which runs rtnl_unregister_all() even though rtnl_register_many() already unwound any partial registration. Calling the full exit helper on a partial init is not correct.
Check each registration error, including proc_create_net(), and unwind only the steps that have succeeded so far, in reverse order.
--- net/phonet/pn_dev.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-)
net/phonet/pn_dev.c +24 -6
@@ -336,16 +336,34 @@ static struct pernet_operations phonet_net_ops = {/* Initialize Phonet devices list */ int __init phonet_device_init (void ) { -int err =register_pernet_subsys (&phonet_net_ops); +int err; + + err =register_pernet_subsys (&phonet_net_ops);if (err)return err; -proc_create_net ("pnresource" ,0 , init_net.proc_net, &pn_res_seq_ops, -sizeof (struct seq_net_private )); -register_netdevice_notifier (&phonet_device_notifier); +if (!proc_create_net ("pnresource" ,0 , init_net.proc_net, + &pn_res_seq_ops,sizeof (struct seq_net_private ))) { + err = -ENOMEM ; + goto err_pernet; + } + + err =register_netdevice_notifier (&phonet_device_notifier); +if (err) + goto err_proc; + err =phonet_netlink_register ();if (err) -phonet_device_exit (); + goto err_notifier; + +return 0 ; + +err_notifier: +unregister_netdevice_notifier (&phonet_device_notifier); +err_proc: +remove_proc_entry ("pnresource" , init_net.proc_net); +err_pernet: +unregister_pernet_subsys (&phonet_net_ops);return err; }
@@ -353,8 +371,8 @@ void phonet_device_exit(void) {rtnl_unregister_all (PF_PHONET );unregister_netdevice_notifier (&phonet_device_notifier); -unregister_pernet_subsys (&phonet_net_ops);remove_proc_entry ("pnresource" , init_net.proc_net); +unregister_pernet_subsys (&phonet_net_ops); }int phonet_route_add (struct net_device *dev,u8 daddr)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 443/1102 ALSA: usb-audio: Add dB map quirk for Razer Barracuda X 2.4
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Lindner <[email protected]>
[ Upstream commit acd8aa3c4b91a38c8521000790890bc9d1083f1d ]
The Razer Barracuda X 2.4 GHz USB headset dongle (0x1532:0x0552) reports a minimum volume register value of cval->min = -16800.
In UAC 1/256 dB units, -16800 corresponds to -65.625 dB. However, stock ALSA misinterprets this raw integer as 1/100 dB units (-168.00 dB), causing user-space audio servers (PipeWire / PulseAudio) to map their volume curves against an incorrectly wide range.
Add an explicit usbmix_dB_map entry overriding Unit 2 to -6562 (-65.62 dB) to accurately report the physical hardware attenuation bounds.
--- sound/usb/mixer_maps.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
sound/usb/mixer_maps.c +15 -0
@@ -344,6 +344,16 @@ static const struct usbmix_name_map bose_soundlink_map[] = { { 0 } /* terminator */ }; +/* +* Razer Barracuda X 2.4: Firmware reports cval->min = -16800 in 1/256 dB units +* (-65.62 dB), which stock ALSA misinterprets as a -168 dB floor +*/ +static const struct usbmix_dB_map razer_barracuda_x_2_4_dB = {-6562 ,0 }; +static const struct usbmix_name_map razer_barracuda_x_2_4_map[] = { + {2 ,NULL , .dB = &razer_barracuda_x_2_4_dB }, + {0 }/* terminator */ +}; +/* Sennheiser Communications Headset [PC 8], the dB value is reported as -6 negative maximum */ static const struct usbmix_dB_map sennheiser_pc8_dB = {-9500 ,0 };static const struct usbmix_name_map sennheiser_pc8_map[] = {
@@ -689,6 +699,11 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x17aa, 0x1046), .map = lenovo_p620_rear_map, }, + { +/* Razer Barracuda X 2.4 */ + .id = USB_ID(0x1532, 0x0552), + .map = razer_barracuda_x_2_4_map, + }, {/* Sennheiser Communications Headset [PC 8] */ .id = USB_ID(0x1395, 0x0025),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 444/1102 ALSA: hda/realtek: Add mute LED quirk for HP Laptop 14s-dr1xxx
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Madhavender Singh <[email protected]>
[ Upstream commit bf4fc9f33ec21595143132a3e7fb8b5d2c2261cd ]
This laptop with an ALC236 codec requires theALC236_FIXUP_HP_MUTE_LED_COEFBIT2
fixup for its mute LED to function correctly.
Add the subsystem ID 0x103c:0x86c8 to the quirk table to apply this fixup.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10899,6 +10899,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x103c ,0x869d ,"HP" ,ALC236_FIXUP_HP_MUTE_LED ),SND_PCI_QUIRK (0x103c ,0x86c1 ,"HP Laptop 15-da3001TU" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x86c7 ,"HP Envy AiO 32" ,ALC274_FIXUP_HP_ENVY_GPIO ), +SND_PCI_QUIRK (0x103c ,0x86c8 ,"HP Laptop 14s-dr1xxx" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x86e7 ,"HP Spectre x360 15-eb0xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_EB1 ),SND_PCI_QUIRK (0x103c ,0x863e ,"HP Spectre x360 15-df1xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_DF1 ), SND_PCI_QUIRK(0x103c, 0x86e8, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 445/1102 ice: pass the return value of skb_checksum_help()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Swiatkowski <[email protected]>
[ Upstream commit 2d19302f628853742c4828381abbd668c1315598 ]
skb_checksum_help() can fail. Pass its return value back to the caller.
Commonize this software path in goto.
Instead of just returning error try calculating software checksum first. There is a check for TSO in checksum_sw_fb.
--- drivers/net/ethernet/intel/ice/ice_txrx.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
drivers/net/ethernet/intel/ice/ice_txrx.c +9 -11
@@ -1857,7 +1857,7 @@ int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off) ret =ipv6_skip_exthdr (skb, exthdr - skb->data, &l4_proto, &frag_off);if (ret <0 ) -return -1 ; + goto checksum_sw_fb; }/* define outer transport */
@@ -1876,11 +1876,7 @@ int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off) l4.hdr =skb_inner_network_header (skb);break ;default : -if (first->tx_flags &ICE_TX_FLAGS_TSO ) -return -1 ; - -skb_checksum_help (skb); -return 0 ; + goto checksum_sw_fb; }/* compute outer L3 header size */
@@ -1939,7 +1935,7 @@ int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off)ipv6_skip_exthdr (skb, exthdr - skb->data, &l4_proto, &frag_off); }else { -return -1 ; + goto checksum_sw_fb; }/* compute inner L3 header size */
@@ -1968,15 +1964,17 @@ int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off)break ;default : -if (first->tx_flags &ICE_TX_FLAGS_TSO ) -return -1 ; -skb_checksum_help (skb); -return 0 ; + goto checksum_sw_fb; } off->td_cmd |= cmd; off->td_offset |= offset;return 1 ; + +checksum_sw_fb: +if (first->tx_flags &ICE_TX_FLAGS_TSO ) +return -1 ; +return skb_checksum_help (skb); }/**
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 446/1102 powerpc/pseries: Ensure vpa,slb_shadow & dtl are unregistered during crash
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vaibhav Jain <[email protected]>
[ Upstream commit 810d07fb4cf7577847f85a6fd6273b69cad8d580 ]
Currently pseries_kexec_cpu_down() skips unregistering vpa, slb_shadow and dtl areas during a crash and kexec shutdown path. It was done to avoid doing an HCALL while crashing. However recently Anushree reported that during kernel crash while the kdump kernel was coming up, Hypervisor reported invalid values for 'vpa.yield_count' while it dispatching L2-KVM Guest vcpus. The error manifested as debug build Hypervisor assert triggering to indicate possible VPA corruption.
Looking at the kexec cpu offline path it was discovered that during crash kernel doesn't unregister the VPA/SLB-Shadow/DTL area with Hypervisor. Instead it re-allocates and re-registers these areas for cpus during boot. During kexec boot the previously allocated areas can get overwritten with new content without hypervisor knowledge. This creates a small window where while kexec kernel boots and the L2-VCPUs are being dispatched, Hypervisor may try to read/write to a wrong memory area which previously belonged to older VPA.
Fix this possible race and memory corruption by updating pseries_kexec_cpu_down() to also unregister vpa,slb_shadow & dtl areas during a kernel crash.
--- arch/powerpc/platforms/pseries/kexec.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
arch/powerpc/platforms/pseries/kexec.c +8 -5
@@ -20,12 +20,15 @@void pseries_kexec_cpu_down (int crash_shutdown,int secondary) {/* -* Don't risk a hypervisor call if we're crashing -* XXX: Why? The hypervisor is not crashing. It might be better -* to at least attempt unregister to avoid the hypervisor stepping -* on our memory. +* Ensure vpa/slb_shadow/dtl cleanup even while we are crashing. +* Why? The hypervisor is not crashing so at least attempt unregister to +* avoid the hypervisor stepping on our memory. If hypervisor or kexec +* kernel steps on the old memory allocated to these areas before the +* new kexec-kernel happens to allocate and register new areas, +* the hypervisor will see invalid content which may cause +* unexpected behavior. */ -if (firmware_has_feature (FW_FEATURE_SPLPAR ) && !crash_shutdown) { +if (firmware_has_feature (FW_FEATURE_SPLPAR )) {int ret;int cpu =smp_processor_id ();int hwcpu =hard_smp_processor_id ();
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 447/1102 cifs: validate idmap key payload length
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Qiang <[email protected]>
[ Upstream commit 455488cd5054bcc59db40fa1cc2c004031a5b2a5 ]
The cifs.idmap key type stores its payload length in key->datalen, which is limited to U16_MAX. Accepting a larger key payload truncates the recorded length and can make later users interpret the payload using inconsistent bounds.
Reject oversized preparsed payloads before allocating or copying them. This keeps key->datalen consistent with the stored data for both inline and separately allocated idmap payloads.
--- fs/smb/client/cifsacl.c | 3 +++ 1 file changed, 3 insertions(+)
fs/smb/client/cifsacl.c +3 -0
@@ -69,6 +69,9 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) {char *payload; +if (prep->datalen >U16_MAX ) +return -EINVAL ; +/* * If the payload is less than or equal to the size of a pointer, then * an allocation here is wasteful. Just copy the data directly to the
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 448/1102 wifi: cfg80211: validate IEs in cfg80211_wext_siwgenie()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
[ Upstream commit a2f5286ca4f304d3fd469f01b96b518608912a5c ]
The KASAN allocation trace shows that a malformed IE buffer is stored via SIOCSIWGENIE (cfg80211_wext_siwgenie()) without any validation. The crash trace shows that a subsequent SIOCSIWESSID triggers a connection attempt which calls cfg80211_sme_get_conn_ies() to process the stored IE buffer, causing:
- An out-of-bounds read in skip_ie() which reads ies[pos+1] (the length byte) past the end of the 1-byte buffer.
- An integer underflow in the memcpy size argument when offs returned by ieee80211_ie_split() exceeds ies_len, causing unsigned subtraction to wrap to SIZE_MAX and triggering a fortify panic.
Fix this by validating the IE buffer in cfg80211_wext_siwgenie() before storing it.
--- net/wireless/wext-sme.c | 9 +++++++++ 1 file changed, 9 insertions(+)
net/wireless/wext-sme.c +9 -0
@@ -319,6 +319,15 @@ int cfg80211_wext_siwgenie(struct net_device *dev,return 0 ;if (ie_len) { +const struct element *elem; + +for_each_element (elem, extra, ie_len) { +/* nothing */ + } + +if (!for_each_element_completed (elem, extra, ie_len)) +return -EINVAL ; + ie =kmemdup (extra, ie_len,GFP_KERNEL );if (!ie)return -ENOMEM ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 449/1102 Bluetooth: RFCOMM: validate skb length in rfcomm_recv_frame
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiale Yao <[email protected]>
[ Upstream commit b230e5bf501c5edaf2eb0991cb862ac142031d4b ]
rfcomm_recv_frame() casts skb->data to struct rfcomm_hdr and dereferences hdr->addr and hdr->ctrl without validating skb->len first. A truncated frame with skb->len less than the minimum header size causes an out-of-bounds read of uninitialized memory. Additionally, a zero-length frame causes skb->len-- to underflow to UINT_MAX, making skb_tail_pointer() read far past the buffer.
Commit 23882b828c3c ("Bluetooth: RFCOMM: validate skb length in MCC handlers") fixed the same class of missing-length-check bugs in the MCC sub-handlers, but the top-level rfcomm_recv_frame() was left unfixed. KMSAN reports:
BUG: KMSAN: uninit-value in rfcomm_run
...
Uninit was created at:
__alloc_skb+0x474/0xb60
vhci_write+0xe9/0x870Fix this by rejecting frames smaller than sizeof(struct rfcomm_hdr) + 1 (the minimum frame must have a 3-byte header and a 1-byte FCS).
--- net/bluetooth/rfcomm/core.c | 5 +++++ 1 file changed, 5 insertions(+)
net/bluetooth/rfcomm/core.c +5 -0
@@ -1817,6 +1817,11 @@ static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,return s; } +if (skb->len <sizeof (*hdr) +1 ) { +kfree_skb (skb); +return s; + } + dlci =__get_dlci (hdr->addr); type =__get_type (hdr->ctrl);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 450/1102 ALSA: usb-audio: Add quirk for Corsair Virtuoso (later revision)
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Abrahamse <[email protected]>
[ Upstream commit cee046679655b4822f76efc9658f19efee9ac979 ]
Add USB mixer mapping quirk for later revisions of the Corsair Virtuoso headset with USB IDs 0x1b1c:0x0a43 (wired) and 0x1b1c:0x0a44 (wireless). These devices exhibit the same mixer label collision as earlier Virtuoso variants: all controls are labelled "Headset", causing applications like PulseAudio to move the sidetone control instead of the main playback volume.
--- sound/usb/mixer_maps.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
sound/usb/mixer_maps.c +10 -0
@@ -638,6 +638,16 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x1b1c, 0x0a42), .map = corsair_virtuoso_map, }, + { + /* Corsair Virtuoso (wired mode, later revision) */ + .id = USB_ID(0x1b1c, 0x0a43), + .map = corsair_virtuoso_map, + }, + { + /* Corsair Virtuoso (wireless mode, later revision) */ + .id = USB_ID(0x1b1c, 0x0a44), + .map = corsair_virtuoso_map, + }, { /* Corsair HS80 RGB Wireless (wired mode) */ .id = USB_ID(0x1b1c, 0x0a6a),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 451/1102 ata: libata-core: Disable LPM on some WD drives
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <[email protected]>
[ Upstream commit 356d8241cf3c7b07a4a491dbab43b5a41513ca86 ]
According to a user report WDC WD100EFGX-68CPLN0 and WDC WD102KFBX-68M95N0 have problems with LPM.
--- drivers/ata/libata-core.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/ata/libata-core.c +8 -0
@@ -4317,6 +4317,14 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { { "WDC WD3000JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, { "WDC WD3200JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, +/* +* WD drives with LPM issues (irrespective of supported SATA speeds). +* (Unlike ATA_QUIRK_WD_BROKEN_LPM, which is only applied if the drive +* exposes SATA Gen1 speed support, and SATA Gen1 speed support only.) +*/ + { "WDC WD100EFGX-68CPLN0", NULL, ATA_QUIRK_NOLPM }, + { "WDC WD102KFBX-68M95N0", NULL, ATA_QUIRK_NOLPM }, +/* * This sata dom device goes on a walkabout when the ATA_LOG_DIRECTORY * log page is accessed. Ensure we never ask for this log page with
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 452/1102 ALSA: hda/realtek: Add mute LED quirk for HP Victus 16-e0xxx (MB 88ED)
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Pragosa <[email protected]>
[ Upstream commit 630c45e92db44b738d1e9224c5f3c032c76a33ca ]
Add subsystem ID 103c:88ed to the existing HP Victus 16-e0xxx mute LED quirk list.
The HP Victus 16-e0xxx with subsystem ID 103c:88ed uses the same mute LED coefficient configuration as the already supported 103c:88eb variant.
The mute LED was verified by manually toggling coefficient index 0x0b (bit 3) using hda-verb. After adding the quirk, the LED is registered as hda::mute and follows the audio mute state.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -10967,6 +10967,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x103c ,0x88d0 ,"HP Pavilion 15-eh1xxx (mainboard 88D0)" ,ALC287_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x88dd ,"HP Pavilion 15z-ec200" ,ALC285_FIXUP_HP_MUTE_LED ),SND_PCI_QUIRK (0x103c ,0x88eb ,"HP Victus 16-e0xxx" ,ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT ), +SND_PCI_QUIRK (0x103c ,0x88ed ,"HP Victus 16-e0xxx (MB 88ED)" , +ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT ),SND_PCI_QUIRK (0x103c ,0x88ee ,"HP Victus 16-e0xxx (MB 88EE)" ,ALC245_FIXUP_HP_MUTE_LED_COEFBIT ),SND_PCI_QUIRK (0x103c ,0x8902 ,"HP OMEN 16" ,ALC285_FIXUP_HP_MUTE_LED ), SND_PCI_QUIRK(0x103c, 0x890e, "HP 255 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 453/1102 ata: libata-core: Disable LPM on WD Green 2.5 480GB
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <[email protected]>
[ Upstream commit d549df8a0ace611bff0a336a907f93420648b462 ]
According to a user report, the WD Green 2.5 480GB has problems with LPM.
--- drivers/ata/libata-core.c | 1 + 1 file changed, 1 insertion(+)
drivers/ata/libata-core.c +1 -0
@@ -4324,6 +4324,7 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {*/ { "WDC WD100EFGX-68CPLN0", NULL, ATA_QUIRK_NOLPM }, { "WDC WD102KFBX-68M95N0", NULL, ATA_QUIRK_NOLPM }, + { "WD Green 2.5 480GB", NULL, ATA_QUIRK_NOLPM },/* * This sata dom device goes on a walkabout when the ATA_LOG_DIRECTORY
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 454/1102 Drivers: hv: vmbus: add VTL2 redirect connection ID
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hardik Garg <[email protected]>
[ Upstream commit 92d0593128023cf93ae61b7728dcc3062f8d514f ]
VMBus sends CHANNELMSG_INITIATE_CONTACT through a Hyper-V message connection ID. Older protocol versions use VMBUS_MESSAGE_CONNECTION_ID, while protocol version 5.0 and newer normally use VMBUS_MESSAGE_CONNECTION_ID_4.
For a VTL2 kernel using VMBus protocol 5.0 or newer, the host may expect INITIATE_CONTACT on either the redirect connection ID or VMBUS_MESSAGE_CONNECTION_ID_4. There is no capability indication that identifies which ID is active, so the driver must determine it at runtime.
During VMBus negotiation, the redirect ID is tried first because it is used by VTL2 configurations with VMBus redirection enabled. If the redirect ID is unavailable, the host rejects it synchronously with HV_STATUS_INVALID_CONNECTION_ID, allowing fallback to the standard ID.
Return a distinct error for an invalid Initiate Contact connection ID so this fallback does not mask other post-message failures or protocol-version rejections. Preserve the existing connection ID selection for older protocol versions or when running below VTL2.
--- drivers/hv/connection.c | 47 +++++++++++++++++++++++---------------- drivers/hv/hyperv_vmbus.h | 2 ++ 2 files changed, 30 insertions(+), 19 deletions(-)
drivers/hv/connection.c +28 -19
@@ -71,7 +71,8 @@ module_param(max_version, uint, S_IRUGO);MODULE_PARM_DESC (max_version,"Maximal VMBus protocol version which can be negotiated" ); -int vmbus_negotiate_version (struct vmbus_channel_msginfo *msginfo,u32 version) +static int vmbus_try_connection_id (struct vmbus_channel_msginfo *msginfo, +u32 version,u32 connection_id) {int ret =0 ;struct vmbus_channel_initiate_contact *msg;
@@ -86,20 +87,20 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version) msg->vmbus_version_requested = version;/* -* VMBus protocol 5.0 (VERSION_WIN10_V5) and higher require that we must -* use VMBUS_MESSAGE_CONNECTION_ID_4 for the Initiate Contact Message, -* and for subsequent messages, we must use the Message Connection ID -* field in the host-returned Version Response Message. And, with -* VERSION_WIN10_V5 and higher, we don't use msg->interrupt_page, but we -* tell the host explicitly that we still use VMBUS_MESSAGE_SINT(2) for -* compatibility. +* For VMBus protocol 5.0 (VERSION_WIN10_V5) and higher, use the +* caller-supplied connection_id for the Initiate Contact message so +* the caller can implement the required retry scheme. For subsequent +* messages, use the Message Connection ID field in the host-returned +* Version Response message. With VERSION_WIN10_V5 and higher, we don't +* use msg->interrupt_page, but tell the host explicitly that we still +* use VMBUS_MESSAGE_SINT(2) for compatibility. * * On old hosts, we should always use VMBUS_MESSAGE_CONNECTION_ID (1). */ if (version >=VERSION_WIN10_V5 ) { msg->msg_sint =VMBUS_MESSAGE_SINT ; msg->msg_vtl = ms_hyperv.vtl; - vmbus_connection.msg_conn_id =VMBUS_MESSAGE_CONNECTION_ID_4 ; + vmbus_connection.msg_conn_id = connection_id; }else { msg->interrupt_page =virt_to_phys (vmbus_connection.int_page); vmbus_connection.msg_conn_id =VMBUS_MESSAGE_CONNECTION_ID ;
@@ -161,6 +162,22 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)return ret; } +int vmbus_negotiate_version (struct vmbus_channel_msginfo *msginfo,u32 version) +{ +int ret; + +/* Try the redirect ID first for VTL2 with VMBus protocol 5.0+. */ +if (version >=VERSION_WIN10_V5 && ms_hyperv.vtl ==2 ) { + ret =vmbus_try_connection_id (msginfo, version, +VMBUS_MESSAGE_CONNECTION_ID_REDIRECT ); +if (ret != -ENXIO ) +return ret; + } + +return vmbus_try_connection_id (msginfo, version, +VMBUS_MESSAGE_CONNECTION_ID_4 ); +} +/* * vmbus_connect - Sends a connect request on the partition service connection */
@@ -454,18 +471,10 @@ int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep)switch (ret) {case HV_STATUS_INVALID_CONNECTION_ID : -/* -* See vmbus_negotiate_version(): VMBus protocol 5.0 -* and higher require that we must use -* VMBUS_MESSAGE_CONNECTION_ID_4 for the Initiate -* Contact message, but on old hosts that only -* support VMBus protocol 4.0 or lower, here we get -* HV_STATUS_INVALID_CONNECTION_ID and we should -* return an error immediately without retrying. -*/ +/* Allow INITIATE_CONTACT to try another connection ID. */ hdr = buffer;if (hdr->msgtype ==CHANNELMSG_INITIATE_CONTACT ) -return -EINVAL ; +return -ENXIO ;/* * We could get this if we send messages too * frequently.
drivers/hv/hyperv_vmbus.h +2 -0
@@ -108,6 +108,8 @@ struct hv_input_post_message {enum {VMBUS_MESSAGE_CONNECTION_ID =1 ,VMBUS_MESSAGE_CONNECTION_ID_4 =4 , +/* VTL2 redirect connection ID for INITIATE_CONTACT. */ +VMBUS_MESSAGE_CONNECTION_ID_REDIRECT =0x800074 ,VMBUS_MESSAGE_PORT_ID =1 ,VMBUS_EVENT_CONNECTION_ID =2 ,VMBUS_EVENT_PORT_ID =2 ,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 455/1102 ASoC: amd: yc: Add DMI quirk for HP Victus Laptop 16-e1xxx
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Heng <[email protected]>
[ Upstream commit 38417f5fc8e3323218c19bd7e419eec4fb0697bd ]
Add DMI quirk to enable ACP6x sound card for HP Victus by HP Laptop 16-e1xxx, which fixes microphone not working issue.
Without this quirk, the DMIC on acp6x device is not properly enabled, causing the microphone to not work.
--- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +7 -0
@@ -668,6 +668,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "8E35"), } }, + { + .driver_data = &acp6x_card, + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"HP" ), + DMI_MATCH(DMI_PRODUCT_NAME, "Victus by HP Laptop 16-e1xxx"), + } + }, { .driver_data = &acp6x_card, .matches = {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 456/1102 vhost-scsi: flush backend after device ioctls
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jia Jia <[email protected]>
[ Upstream commit 22598f55a4c2b510b3df5e69e563387a963222ae ]
vhost-scsi translates guest response descriptors into userspace iovecs when commands are submitted. Target-core completes those commands asynchronously, so VHOST_SET_MEM_TABLE can replace the memory table while an in-flight command still retains response iovecs translated through the old table.
If the old mapping is reused after VHOST_SET_MEM_TABLE returns, command completion can write the response to an unrelated userspace object.
Flush the vhost-scsi backend after vhost_dev_ioctl() handles a device ioctl. This waits for in-flight commands that can still use the old response iovecs before the ioctl returns.
Message-ID: <[email protected]>
--- drivers/vhost/scsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/vhost/scsi.c +2 -1
@@ -2158,9 +2158,10 @@ vhost_scsi_ioctl(struct file *f,default :mutex_lock (&vs->dev.mutex); r =vhost_dev_ioctl (&vs->dev, ioctl, argp); -/* TODO: flush backend after dev ioctl. */ if (r == -ENOIOCTLCMD ) r =vhost_vring_ioctl (&vs->dev, ioctl, argp); +else +vhost_scsi_flush (vs);mutex_unlock (&vs->dev.mutex);return r; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 457/1102 hwmon: (corsair-psu) Fix linear11 calculation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit c6c4234928d2eb4f61fecb61067e612d9bdbd2ff ]
In corsairpsu_linear11_to_int(), the mantissa is extracted using bitwise operations and cast to s16 before being shifted left:
static int corsairpsu_linear11_to_int(const u16 val, const int scale)
{
...
const int mant = (((s16)(val & 0x7ff)) << 5) >> 5;
...
}Due to C integer promotion rules, the masked value (which is always positive) is promoted to a 32-bit integer before the left shift. As a result, the sign bit is never extended to bit 31 of the promoted integer.
When the device hardware reports a negative temperature in Linear11 format (such as an ambient temperature probe reporting sub-zero), the negative mantissa is parsed incorrectly as a massive positive value. For example, -1 becomes 2047, which scales to 2047 degrees Celsius.
Fix the problem by type casting the result of the left shift operation to s16.
Another problem is left-shifting of negative values. In C, the result of left-shifting negative values is undefined. Use a multiplication instead to avoid the problem.
Also use a local s64 variable to store temporary results, change the return value type from int to long, and clamp the final value to LONG_MIN and LONG_MAX to avoid under- and overflow issues while retaining as much information as possible.
--- drivers/hwmon/corsair-psu.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
drivers/hwmon/corsair-psu.c +14 -9
@@ -140,13 +140,18 @@ struct corsairpsu_data { };/* some values are SMBus LINEAR11 data which need a conversion */ -static int corsairpsu_linear11_to_int (const u16 val,const int scale) +static long corsairpsu_linear11_to_long (const u16 val,const int scale) {const int exp = ((s16 )val) >>11 ; -const int mant = (((s16)(val &0x7ff )) <<5 ) >>5 ; -const int result = mant * scale; +const int mant = ((s16)((val &0x7ff ) <<5 )) >>5 ; +s64 result = mant * scale; -return (exp >=0 ) ? (result << exp) : (result >> -exp); +if (exp >=0 ) + result *= (int )(1UL << exp); +else + result >>= -exp; + +return clamp (result,LONG_MIN ,LONG_MAX ); }/* the micro-controller uses percentage values to control pwm */
@@ -271,13 +276,13 @@ static int corsairpsu_get_value(struct corsairpsu_data *priv, u8 cmd, u8 rail, lcase PSU_CMD_RAIL_AMPS :case PSU_CMD_TEMP0 :case PSU_CMD_TEMP1 : - *val =corsairpsu_linear11_to_int (tmp &0xFFFF ,1000 ); + *val =corsairpsu_linear11_to_long (tmp &0xFFFF ,1000 );break ;case PSU_CMD_FAN : - *val =corsairpsu_linear11_to_int (tmp &0xFFFF ,1 ); + *val =corsairpsu_linear11_to_long (tmp &0xFFFF ,1 );break ;case PSU_CMD_FAN_PWM_ENABLE : - *val =corsairpsu_linear11_to_int (tmp &0xFFFF ,1 ); + *val =corsairpsu_linear11_to_long (tmp &0xFFFF ,1 );/* * 0 = automatic mode, means the micro-controller controls the fan using a plan * which can be modified, but changing this plan is not supported by this
@@ -291,12 +296,12 @@ static int corsairpsu_get_value(struct corsairpsu_data *priv, u8 cmd, u8 rail, l *val =2 ;break ;case PSU_CMD_FAN_PWM : - *val =corsairpsu_linear11_to_int (tmp &0xFFFF ,1 ); + *val =corsairpsu_linear11_to_long (tmp &0xFFFF ,1 ); *val =corsairpsu_dutycycle_to_pwm (*val);break ;case PSU_CMD_RAIL_WATTS :case PSU_CMD_TOTAL_WATTS : - *val =corsairpsu_linear11_to_int (tmp &0xFFFF ,1000000 ); + *val =corsairpsu_linear11_to_long (tmp &0xFFFF ,1000000 );break ;case PSU_CMD_TOTAL_UPTIME :case PSU_CMD_UPTIME :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 458/1102 ata: libata-core: Disable LPM on WDC WD141KFGX-68FH9N0
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <[email protected]>
[ Upstream commit 3971921a055330669b281962ff723d1abb76a58c ]
According to a user report, WDC WD141KFGX-68FH9N0 has problems with LPM.
--- drivers/ata/libata-core.c | 1 + 1 file changed, 1 insertion(+)
drivers/ata/libata-core.c +1 -0
@@ -4324,6 +4324,7 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {*/ { "WDC WD100EFGX-68CPLN0", NULL, ATA_QUIRK_NOLPM }, { "WDC WD102KFBX-68M95N0", NULL, ATA_QUIRK_NOLPM }, + { "WDC WD141KFGX-68FH9N0", NULL, ATA_QUIRK_NOLPM }, { "WD Green 2.5 480GB", NULL, ATA_QUIRK_NOLPM },/*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 459/1102 spi: dw: fix wrong RX_SAMPLE_DLY setting after resume
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <[email protected]>
[ Upstream commit 133c71b2c0bc976a4751f9e05ef7cdea67f964e5 ]
On platforms which need a non-zero rx sample delay, the RX_SAMPLE_DLY reg setting is lost after resume. The reason is that the reg may be reset to 0 after resuming, but dws->cur_rx_sample_dly doesn't know this fact. Fix this issue by clearing dws->cur_rx_sample_dly in dw_spi_shutdown_chip().
--- drivers/spi/spi-dw.h | 1 + 1 file changed, 1 insertion(+)
drivers/spi/spi-dw.h +1 -0
@@ -283,6 +283,7 @@ static inline void dw_spi_shutdown_chip(struct dw_spi *dws)dw_spi_enable_chip (dws,0 );dw_spi_set_clk (dws,0 ); dws->current_freq =0 ; + dws->cur_rx_sample_dly =0 ; }extern void dw_spi_set_cs (struct spi_device *spi,bool enable);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 460/1102 ASoC: rt5645: Perform the initial jack detect at probe
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rudi Heitbaum <[email protected]>
[ Upstream commit 54b279699279411c77c8afbc73b83c70740a7303 ]
The only initial jack detect is the rt5645_irq(0, rt5645) at the end of rt5645_set_jack_detect(). A card described with simple-audio-card has no machine driver to call that, so jack state is only ever sampled from an edge on hp-detect-gpios.
A headphone already in the socket at boot is therefore never noticed, and the card is silent with every mixer control set correctly. rt5645_jack_detect() is what force enables the "LDO2" and "Mic Det Power" supplies that the "HP amp" widget depends on, and what programs RT5645_CHARGE_PUMP away from its reset value, so without it "HP amp" cannot power up. Unplugging and replugging the jack is the only way to recover.
Do the detect at the end of the component probe when the driver owns a hp-detect GPIO and the codec's own jack detect is unused, which is the case that has no other trigger. A machine driver calling rt5645_set_jack_detect() later just repeats it.
--- sound/soc/codecs/rt5645.c | 4 ++++ 1 file changed, 4 insertions(+)
sound/soc/codecs/rt5645.c +4 -0
@@ -3495,6 +3495,10 @@ static int rt5645_probe(struct snd_soc_component *component)if (!rt5645->eq_param)return -ENOMEM ; +/* no machine driver to call rt5645_set_jack_detect(), so detect here */ +if (!rt5645->pdata.jd_mode && rt5645->gpiod_hp_det) +rt5645_irq (0 , rt5645); +return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 461/1102 scsi: core: Do not block on tag allocation in scsi_eh_lock_door()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zizhi Wo <[email protected]>
[ Upstream commit 732cb6bb37fd26863d5786522fb1997e7f5865b4 ]
scsi_eh_lock_door() is called from scsi_restart_operations() while the host is still in the SHOST_RECOVERY state, i.e. before the host is switched back to SHOST_RUNNING and scsi_run_host_queues() restarts the queues. It allocates a request via scsi_alloc_request() with no flags, so blk_mq_get_tag() may block waiting for a free sched tag when all tags are already in use.
Those tags can be held by commands that were just requeued by scsi_eh_flush_done_q() during error handling. Such commands cannot be dispatched until the host leaves SHOST_RECOVERY and scsi_run_host_queues() is called - which only happens *after* scsi_eh_lock_door() returns.
This forms a circular dependency:
- scsi_eh_lock_door(), running in the SCSI error handler thread, waits
for a sched tag held by a requeued command;
- the requeued command cannot complete and release its sched tag until the error handler thread leaves scsi_restart_operations() and restart the queues.
For devices with a single driver tag (e.g. USB storage) it is a guaranteed deadlock and I/O that can never be submitted. This problem has also been reproduced in our environment.
Locking the door is a best-effort operation, and scsi_eh_lock_door() already returns silently when the request allocation fails. Pass BLK_MQ_REQ_NOWAIT to scsi_alloc_request() so the allocation fails instead of blocking when no tag is available. This breaks the circular dependency and allows the error handler to finish restarting the queues, after which the pending commands are dispatched normally.
--- drivers/scsi/scsi_error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/scsi_error.c +1 -1
@@ -2137,7 +2137,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)struct scsi_cmnd *scmd;struct request *req; - req =scsi_alloc_request (sdev->request_queue,REQ_OP_DRV_IN ,0 ); + req =scsi_alloc_request (sdev->request_queue,REQ_OP_DRV_IN ,BLK_MQ_REQ_NOWAIT );if (IS_ERR (req))return ; scmd =blk_mq_rq_to_pdu (req);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 462/1102 ASoC: amd: yc: Add DMI quirk for HyperX OMEN Gaming Laptop 16-ap1xxx
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lin Xianglin <[email protected]>
[ Upstream commit fe21db8c5e7c2a9815a9be54a1f5d556f905506e ]
The HyperX OMEN Gaming Laptop 16-ap1xxx (HP board 8F06) has an internal digital microphone array attached to the AMD ACP PDM controller, but the acp6x machine driver does not register the DMIC sound card because this board is missing from the DMI quirk table, leaving the internal microphone unusable.
Add a DMI quirk entry for the HP board "8F06" so the acp6x DMIC capture card gets registered.
--- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +7 -0
@@ -668,6 +668,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "8E35"), } }, + { + .driver_data = &acp6x_card, + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"HP" ), + DMI_MATCH(DMI_BOARD_NAME, "8F06"), + } + }, { .driver_data = &acp6x_card, .matches = {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 463/1102 netfilter: nfnetlink_log: wait for rcu grace period before freeing pernet state
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
[ Upstream commit 33d1469b0124cc0baaea7a2032123b77a81e0940 ]
sashiko reports: "nfnl_log_net_exit() calls nf_log_unset(), which clears the logger pointer without an RCU grace period. Immediately after, ops_free_list() frees the per-net state while concurrent packets might still be executing nf_log_packet() under rcu_read_lock()."
Clear the pointer via .pre_exit to make sure rcu readers have completed before pernet storage is free'd. The change in nf_log_syslog.c is only done for consistency: it doesn't use pernet data.
--- net/netfilter/nf_log_syslog.c | 4 ++-- net/netfilter/nfnetlink_log.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-)
net/netfilter/nf_log_syslog.c +2 -2
@@ -1004,7 +1004,7 @@ static int __net_init nf_log_syslog_net_init(struct net *net)return ret; } -static void __net_exit nf_log_syslog_net_exit(struct net *net) +static void __net_exit nf_log_syslog_net_pre_exit(struct net *net) {nf_log_unset (net, &nf_ip_logger);nf_log_unset (net, &nf_arp_logger);
@@ -1015,7 +1015,7 @@ static void __net_exit nf_log_syslog_net_exit(struct net *net)static struct pernet_operations nf_log_syslog_net_ops = { .init = nf_log_syslog_net_init, - .exit = nf_log_syslog_net_exit, + .pre_exit = nf_log_syslog_net_pre_exit, };static int __init nf_log_syslog_init (void )
net/netfilter/nfnetlink_log.c +9 -4
@@ -1160,21 +1160,26 @@ static int __net_init nfnl_log_net_init(struct net *net)return 0 ; } -static void __net_exit nfnl_log_net_exit(struct net *net) +static void __net_exit nfnl_log_net_pre_exit(struct net *net) { -struct nfnl_log_net *log =nfnl_log_pernet (net); -unsigned int i; -#ifdef CONFIG_PROC_FS remove_proc_entry ("nfnetlink_log" , net->nf.proc_netfilter);#endif nf_log_unset (net, &nfulnl_logger); +} + +static void __net_exit nfnl_log_net_exit(struct net *net) +{ +struct nfnl_log_net *log =nfnl_log_pernet (net); +unsigned int i; +for (i =0 ; i <INSTANCE_BUCKETS ; i++)WARN_ON_ONCE (!hlist_empty (&log->instance_table[i])); }static struct pernet_operations nfnl_log_net_ops = { .init = nfnl_log_net_init, + .pre_exit = nfnl_log_net_pre_exit, .exit = nfnl_log_net_exit, .id = &nfnl_log_net_id, .size =sizeof (struct nfnl_log_net ),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 464/1102 Revert "ACPI: processor: Update cpuidle driver check in __acpi_processor_start()"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit fbf04215d9966da61feee3f4ec24dbf4544cfd0f ]
Revert commit 8a1b5d412cb4 ("ACPI: processor: Update cpuidle driver check in __acpi_processor_start()") which depends on commit 7a8c994cbb2d ("ACPI: processor: idle: Optimize ACPI idle driver registration") that got reverted.
--- drivers/acpi/processor_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/processor_driver.c +1 -1
@@ -166,7 +166,7 @@ static int __acpi_processor_start(struct acpi_device *device)if (result && !IS_ENABLED (CONFIG_ACPI_CPU_FREQ_PSS ))dev_dbg (&device->dev,"CPPC data invalid or not present\n" ); -if (cpuidle_get_driver () == &acpi_idle_driver) +if (!cpuidle_get_driver () ||cpuidle_get_driver () == &acpi_idle_driver)acpi_processor_power_init (pr);acpi_pss_perf_init (pr);
Signature · 1 line
2.53.0
Re: [PATCH 6.12 0464/1102] Revert "ACPI: processor: Update cpuidle driver check in __acpi_processor_start()"
Quoted 4 lines · Greg Kroah-Hartman
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
Quoted 9 lines
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit
fbf04215d9966da61feee3f4ec24dbf4544cfd0f]Revert commit
8a1b5d412cb4("ACPI: processor: Update cpuidle driver check in__acpi_processor_start()") which depends on commit7a8c994cbb2d("ACPI: processor: idle: Optimize ACPI idle driver registration") that got reverted.
^^^> Signed-off-by: Rafael J. Wysocki <[email protected]>
Quoted 10 lines
Signed-off-by Sasha Levin <[email protected]>--- drivers/acpi/processor_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/acpi/processor_driver.c +0
-0
drivers/acpi/processor_driver.c static int __acpi_processor_start(struct acpi_device *device) · line 170
Quoted 6 lines
drivers/acpi/processor_driver.c +1
-1@@ -166,7 +166,7 @@ static int __acpi_processor_start(struct acpi_device *device)if (result && !IS_ENABLED (CONFIG_ACPI_CPU_FREQ_PSS ))dev_dbg (&device->dev,"CPPC data invalid or not present\n" ); -if (cpuidle_get_driver () == &acpi_idle_driver) +if (!cpuidle_get_driver () ||cpuidle_get_driver () == &acpi_idle_driver)acpi_processor_power_init (pr);
Hi Greg/Sasha,
I checked the AI-assisted report for 5f5537db914c against the ACPI and cpuidle call paths in 6.12.y.
Upstream has, after reverting the registration optimization:
if (pr->flags.power) {
if (!acpi_processor_registered) {
acpi_processor_setup_cpuidle_states(pr);
retval = cpuidle_register_driver(&acpi_idle_driver);
if (retval)
return retval;
}
...
retval = cpuidle_register_device(dev);
}6.12.y has:
if (pr->flags.power) {
...
retval = cpuidle_register_device(dev);
}The one-line revert matches upstream fbf04215d996, but upstream applied it only after:
43ff36c4a5a574ee83b4b0d3f3d74f09a3a8c2d3
("Revert "ACPI: processor: idle: Optimize ACPI idle driver registration"")
The destination lacks that prerequisite and still contains the equivalent optimization as 7e6dc9f99870. Consequently, the restored no-driver branch can call acpi_processor_power_init() before a cpuidle driver is registered. cpuidle_register_device() then reaches code that dereferences drv->owner without a NULL-driver check.
so maybe we should drop this ?
thanks,
Harshit
Quoted 2 lines
drivers/acpi/processor_driver.c +0
-0acpi_pss_perf_init (pr);
Sasha Levin
maintainerRe: [PATCH 6.12 0464/1102] Revert "ACPI: processor: Update cpuidle driver check in __acpi_processor_start()"
Quoted 6 lines · Harshit Mogalapalli
The one-line revert matches upstream
fbf04215d996, but upstream applied it only after:
43ff36c4a5a574ee83b4b0d3f3d74f09a3a8c2d3
("Revert "ACPI: processor: idle: Optimize ACPI idle driver registration"")
[...]
Quoted 1 line
so maybe we should drop this ?
Dropped from the 6.12 and 6.6 queues, thanks.
Signature · 2 lines
Thanks, Sasha
Greg Kroah-Hartman
maintainerPATCH 465/1102 firmware: stratix10-svc: fix FCS SMC call kernel-doc
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Genevieve Chan <[email protected]>
[ Upstream commit 9b9a6e31bdd1ff20c3ffdab87431672d8bfc2a07 ]
Correct kernel-doc errors for two FCS SMC calls:
INTEL_SIP_SMC_FCS_SEND_CERTIFICATE:
- Describe as async to match STD_CALL_VAL usage
- Replace INTEL_SIP_SMC_FCS_REJECTED with INTEL_SIP_SMC_REJECTED
INTEL_SIP_SMC_FCS_GET_PROVISION_DATA:
- Replace FCS-specific status macros with standard status macros (INTEL_SIP_SMC_STATUS_ERROR and INTEL_SIP_SMC_STATUS_REJECTED)
- Restore return register documentation for a1 (mailbox error), a2 (physical address), and a3 (structure size)
--- include/linux/firmware/intel/stratix10-smc.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
include/linux/firmware/intel/stratix10-smc.h +7 -5
@@ -582,7 +582,7 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)/** * Request INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE -* Sync call to send a signed certificate +* Async call to send a signed certificate * * Call register usage: * a0 INTEL_SIP_SMC_FCS_SEND_CERTIFICATE
@@ -591,7 +591,7 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)* a3-a7 not used * * Return status: -* a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_FCS_REJECTED +* a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REJECTED * a1-a3 not used */ #define INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE 93
@@ -607,9 +607,11 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)* a1-a7 not used * * Return status: -* a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FCS_ERROR or -* INTEL_SIP_SMC_FCS_REJECTED -* a1-a3 not used +* a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_ERROR or +* INTEL_SIP_SMC_STATUS_REJECTED +* a1 mailbox error if a0 is INTEL_SIP_SMC_STATUS_ERROR +* a2 physical address for the structure of fuse and key hashes +* a3 the size of structure * */ #define INTEL_SIP_SMC_FUNCID_FCS_GET_PROVISION_DATA 94
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 466/1102 bpftool: Strip all -Wformat* flags from bootstrap libbpf build
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
[ Upstream commit a954c9e3168cdf0c3cad07b43dfc8ca2945d773a ]
Commit 9080b97689db ("bpftool: Pass host flags to bootstrap libbpf") started building the bootstrap libbpf with HOST_CFLAGS, stripping the warning options that are unsuitable for that build by filtering out -W -Wall -Wextra -Wformat -Wformat-signedness.
HOST_CFLAGS inherits EXTRA_WARNINGS, which includes -Wformat-security and -Wformat-y2k. The filter drops -Wall and -Wformat (the latter being what actually enables -Wformat), but leaves those two -Wformat-* children in LIBBPF_BOOTSTRAP_CFLAGS. Building the bootstrap libbpf with it then warns:
cc1: warning: '-Wformat-y2k' ignored without '-Wformat'
cc1: warning: '-Wformat-security' ignored without '-Wformat'
The warning is easy to miss in an in-tree build: tools/lib/bpf/Makefile re-adds -Wall via "override CFLAGS += -Wall", which re-enables -Wformat for the libbpf objects, so only libbpf's feature-detection probe (which uses the passed CFLAGS verbatim) leaks the two warnings. The standalone libbpf Makefile (github.com/libbpf/libbpf, used by the bpftool mirror) instead uses "CFLAGS ?= ... -Wall", which the passed-in CFLAGS overrides, so -Wall is never re-added and every bootstrap object warns.
Use a -Wformat% wildcard in the filter-out so the orphaned children are removed together with the parent.
--- tools/bpf/bpftool/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/bpf/bpftool/Makefile +1 -1
@@ -95,7 +95,7 @@ HOST_CFLAGS := $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),\ HOST_LDFLAGS := $(LDFLAGS) # Remove warnings for libbpf bootstrap build -LIBBPF_BOOTSTRAP_CFLAGS := $(filter-out -W -Wall -Wextra -Wformat -Wformat-signedness,$(HOST_CFLAGS)) +LIBBPF_BOOTSTRAP_CFLAGS := $(filter-out -W -Wall -Wextra -Wformat%,$(HOST_CFLAGS)) INSTALL ?= install RM ?= rm -f
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 467/1102 ksmbd: remove stale channels from all sessions on teardown
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gil Portnoy <[email protected]>
[ Upstream commit b10665730fbf6b5e45fe422badcbbc3f0df96ef5 ]
ksmbd_sessions_deregister() removes a connection's channels from other sessions' channel lists only while conn->binding is still set:
if (conn->binding) {
hash_for_each_safe(sessions_table, ...)
ksmbd_chann_del(conn, sess);
}conn->binding is a transient flag: it is cleared once a binding SESSION_SETUP completes, and also by a subsequent non-binding SESSION_SETUP on the same connection (a reauthentication on a bound channel, or a new SessionId==0 setup). A connection that has bound a channel into another session's ksmbd_chann_list and then clears conn->binding leaves that channel behind when it disconnects: the channel, whose chann->conn points at the now freed struct ksmbd_conn, stays on the owner session's list.
When the owning connection later tears down, the second loop dereferences the stale channel:
xa_for_each(&sess->ksmbd_chann_list, chann_id, chann) if (chann->conn != conn) ksmbd_conn_set_exiting(chann->conn); /* freed */
which is a use-after-free write into the freed ksmbd_conn (the same stale channel is also walked by show_proc_session() through /proc). The session is leaked as well, because its channel list never empties.
Remove the conn->binding gate so a connection always removes its channels from every session on teardown.
--- fs/smb/server/mgmt/user_session.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-)
fs/smb/server/mgmt/user_session.c +11 -14
@@ -247,22 +247,19 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn) {struct ksmbd_session *sess;unsigned long id; +struct hlist_node *tmp; +int bkt;down_write (&sessions_table_lock); -if (conn->binding) { -int bkt; -struct hlist_node *tmp; - -hash_for_each_safe (sessions_table, bkt, tmp, sess, hlist) { -if (!ksmbd_chann_del (conn, sess) && -xa_empty (&sess->ksmbd_chann_list)) { -hash_del (&sess->hlist); -down_write (&conn->session_lock); -xa_erase (&conn->sessions, sess->id); -up_write (&conn->session_lock); -if (atomic_dec_and_test (&sess->refcnt)) -ksmbd_session_destroy (sess); - } +hash_for_each_safe (sessions_table, bkt, tmp, sess, hlist) { +if (!ksmbd_chann_del (conn, sess) && +xa_empty (&sess->ksmbd_chann_list)) { +hash_del (&sess->hlist); +down_write (&conn->session_lock); +xa_erase (&conn->sessions, sess->id); +up_write (&conn->session_lock); +if (atomic_dec_and_test (&sess->refcnt)) +ksmbd_session_destroy (sess); } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 468/1102 Revert "bpf, s390: Clear fetch destination on faulting arena atomic"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit 1a26541b3f60ce447433a4c4dd56edb10d2cd580.
--- arch/s390/net/bpf_jit_comp.c | 11 ----------- 1 file changed, 11 deletions(-)
arch/s390/net/bpf_jit_comp.c +0 -11
@@ -782,8 +782,6 @@ static void bpf_jit_probe_atomic_pre(struct bpf_jit *jit, struct bpf_insn *insn, struct bpf_jit_probe *probe) { - int load_reg; - if (BPF_MODE(insn->code) != BPF_PROBE_ATOMIC) return;
@@ -793,14 +791,6 @@ static void bpf_jit_probe_atomic_pre(struct bpf_jit *jit,EMIT4 (0xb9080000 ,REG_W1 , insn->dst_reg); probe->arena_reg =REG_W1 ; probe->prg = jit->prg; -/* -* A read-modify-write carrying BPF_FETCH reads the old value into -* src_reg, or into r0 for a BPF_CMPXCHG. Clear that register on -* fault, the remaining atomics only write memory. -*/ - load_reg =bpf_atomic_load_reg (insn); -if (load_reg >=0 ) - probe->reg = reg2hex[load_reg]; } static int bpf_jit_probe_post(struct bpf_jit *jit, struct bpf_prog *fp,
@@ -1663,7 +1653,6 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,if (load_probe.prg !=-1 ) { probe.prg = jit->prg; probe.arena_reg = load_probe.arena_reg; - probe.reg = load_probe.reg; } loop_start = jit->prg;/* 0: {csy|csg} %w0,%src,off(%arena) */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 469/1102 Revert "ARM: 9481/2: breakpoint: CFI breakpoints only on demand"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit 22107402c2669b0163d43cc68901a2c4a59fa43a.
--- arch/arm/kernel/hw_breakpoint.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
arch/arm/kernel/hw_breakpoint.c +5 -6
@@ -929,6 +929,10 @@ static void hw_breakpoint_cfi_handler(struct pt_regs *regs) break; } } +#else +static void hw_breakpoint_cfi_handler (struct pt_regs *regs) +{ +}#endif /*
@@ -960,14 +964,9 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,case ARM_ENTRY_SYNC_WATCHPOINT :watchpoint_handler (addr, fsr, regs);break ; -#ifdef CONFIG_CFI case ARM_ENTRY_CFI_BREAKPOINT : -if (user_mode (regs)) - ret =1 ;/* Don't handle userspace BKPT */ -else -hw_breakpoint_cfi_handler (regs); +hw_breakpoint_cfi_handler (regs);break ; -#endif default : ret =1 ;/* Unhandled fault. */ }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 470/1102 wifi: mt76: mt7921: validate CLC firmware records
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laxman Acharya Padhya <[email protected]>
[ Upstream commit 9417c5818a0146980c2608fda94c908e604eb033 ]
The CLC region is supplied by firmware, but the loader trusts the region count and each record length. A malformed image can make the region table pointer precede the firmware buffer, make the record loop fail to advance, or index phy->clc past its end. Validate the table and record bounds before dereferencing or copying.
--- .../net/wireless/mediatek/mt76/mt7921/mcu.c | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +24 -4
@@ -412,7 +412,8 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)struct mt76_dev *mdev = &dev->mt76;struct mt792x_phy *phy = &dev->phy;const struct firmware *fw; -int ret, i, len, offset =0 ; +size_t clc_len, fw_data_len, len, offset =0 ; +int ret, i;u8 *clc_base =NULL , hw_encap =0 ; dev->phy.clc_chan_conf =0xff ;
@@ -438,13 +439,21 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name) } hdr = (const void *)(fw->data + fw->size -sizeof (*hdr)); +if (hdr->n_region > (fw->size -sizeof (*hdr)) /sizeof (*region)) { +dev_err (mdev->dev,"Invalid firmware region table\n" ); + ret = -EINVAL ; + goto out; + } + fw_data_len = fw->size -sizeof (*hdr) - + hdr->n_region *sizeof (*region); +for (i =0 ; i < hdr->n_region; i++) { region = (const void *)((const u8 *)hdr - (hdr->n_region - i) *sizeof (*region)); len =le32_to_cpu (region->len);/* check if we have valid buffer size */ -if (offset + len > fw->size) { +if (len > fw_data_len - offset) {dev_err (mdev->dev,"Invalid firmware region\n" ); ret = -EINVAL ; goto out;
@@ -461,8 +470,19 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)if (!clc_base) goto out; -for (offset =0 ; offset < len; offset +=le32_to_cpu (clc->len)) { +for (offset =0 ; offset < len; offset += clc_len) { +if (len - offset <sizeof (*clc)) { + ret = -EINVAL ; + goto out; + } + clc = (const struct mt7921_clc *)(clc_base + offset); + clc_len =le32_to_cpu (clc->len); +if (clc_len <sizeof (*clc) || clc_len > len - offset || + clc->idx >=ARRAY_SIZE (phy->clc)) { + ret = -EINVAL ; + goto out; + }/* do not init buf again if chip reset triggered */ if (phy->clc[clc->idx])
@@ -474,7 +494,7 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)continue ; phy->clc[clc->idx] =devm_kmemdup (mdev->dev, clc, -le32_to_cpu (clc->len), + clc_len,GFP_KERNEL );if (!phy->clc[clc->idx]) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 471/1102 wifi: mt76: mt7921: skip unknown CLC firmware records
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laxman Acharya Padhya <[email protected]>
[ Upstream commit 1a296bfd3e775e515233f746218824fc7dd5ff16 ]
Treat an out-of-range CLC index as newer firmware rather than a malformed image. linux-firmware 20260810 ships MT7922 records with idx 3, and rejecting them made mt7921e fail to probe.
Keep the record-length checks, and report those as errors so a truncated table is visible instead of a silent retry loop.
--- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +7 -2
@@ -472,18 +472,23 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)for (offset =0 ; offset < len; offset += clc_len) {if (len - offset <sizeof (*clc)) { +dev_err (mdev->dev,"Invalid CLC record\n" ); ret = -EINVAL ; goto out; } clc = (const struct mt7921_clc *)(clc_base + offset); clc_len =le32_to_cpu (clc->len); -if (clc_len <sizeof (*clc) || clc_len > len - offset || - clc->idx >=ARRAY_SIZE (phy->clc)) { +if (clc_len <sizeof (*clc) || clc_len > len - offset) { +dev_err (mdev->dev,"Invalid CLC record\n" ); ret = -EINVAL ; goto out; } +/* Newer firmware may add records this driver does not use yet */ +if (clc->idx >=ARRAY_SIZE (phy->clc)) +continue ; +/* do not init buf again if chip reset triggered */ if (phy->clc[clc->idx])continue ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 472/1102 mm/huge_memory: use folios memcg inside __folio_split()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit c299a2285d9d8bda4da024455de65e3d00de6f17 upstream.
Patch series "Honor XA_FLAGS_ACCOUNT in xas_split_alloc() and charge to folio's memcg", v3.
__GFP_ACCOUNT is needed for xarray node allocation accounting when XA_FLAGS_ACCOUNT is set. Commit 7b785645e8f13 ("mm: fix page cache convergence regression") fixed a workingset regression with it. xas_split_alloc() does not have it and needs to be fixed.
In addition, based on Sashiko's review[1] and Johannes' confirmation[2], to charge the right memcg, folio's memcg needs to be active during folio split. Add that before adding __GFP_ACCOUNT.
There is no workingset convergence regression related to missing __GFP_ACCOUNT in xas_split_alloc() and the impact to userspace should be minor.
This patch (of 2):
During a pagecache folio split, an xarray node allocation can happen and needs to charge at folio's memcg instead of folio split invoker's memcg, because for example folio split can happen during reclaim and reclaim's active memcg might not be folio's memcg. Switch to folio's memcg at the beginning and switch back afterwards.
--- mm/huge_memory.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
mm/huge_memory.c +10 -0
@@ -3420,6 +3420,7 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,/* reset xarray order to new order after split */ XA_STATE_ORDER (xas, &folio->mapping->i_pages, folio->index, new_order);bool is_anon =folio_test_anon (folio); +struct mem_cgroup *memcg, *old_memcg;struct address_space *mapping =NULL ;struct anon_vma *anon_vma =NULL ;int order =folio_order (folio);
@@ -3483,6 +3484,13 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,if (folio_test_writeback (folio))return -EBUSY ; +/* +* switch to folio's memcg as xarray node allocation can happen and +* needs to charge to it. +*/ + memcg =folio_memcg (folio); + old_memcg =set_active_memcg (memcg); +if (is_anon) {/* * The caller does not necessarily hold an mmap_lock that would
@@ -3629,6 +3637,8 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,if (mapping)i_mmap_unlock_read (mapping); out: +/* restore to caller's old_memcg */ +set_active_memcg (old_memcg);xas_destroy (&xas);if (order ==HPAGE_PMD_ORDER )count_vm_event (!ret ?THP_SPLIT_PAGE :THP_SPLIT_PAGE_FAILED );
Signature · 1 line
2.53.0
Re: [PATCH 6.12 0472/1102] mm/huge_memory: use folios memcg inside __folio_split()
Hi Greg/Sasha,
Quoted 71 lines · Greg Kroah-Hartman
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit
c299a2285d9d8bda4da024455de65e3d00de6f17upstream.Patch series "Honor
XA_FLAGS_ACCOUNTinxas_split_alloc()and charge to folio's memcg", v3.
__GFP_ACCOUNTis needed for xarray node allocation accounting whenXA_FLAGS_ACCOUNTis set. Commit7b785645e8f13("mm: fix page cache convergence regression") fixed a workingset regression with it.xas_split_alloc()does not have it and needs to be fixed.In addition, based on Sashiko's review[1] and Johannes' confirmation[2], to charge the right memcg, folio's memcg needs to be active during folio split. Add that before adding
__GFP_ACCOUNT.There is no workingset convergence regression related to missing
__GFP_ACCOUNTinxas_split_alloc()and the impact to userspace should be minor.This patch (of 2):
During a pagecache folio split, an xarray node allocation can happen and needs to charge at folio's memcg instead of folio split invoker's memcg, because for example folio split can happen during reclaim and reclaim's active memcg might not be folio's memcg. Switch to folio's memcg at the beginning and switch back afterwards.
Link https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-0-38cb3ff325c5@nvidia.com open hereLink https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-1-38cb3ff325c5@nvidia.com open hereFixes 6b24ca4a1a8d ("mm: Use multi-index entries in the page cache")Signed-off-by Zi Yan <[email protected]>Suggested-by Johannes Weiner <[email protected]>Reviewed-by Baolin Wang <[email protected]>Acked-by Johannes Weiner <[email protected]>Cc Barry Song <[email protected]>Cc David Hildenbrand <[email protected]>Cc Dev Jain <[email protected]>Cc Lance Yang <[email protected]>Cc Liam R. Howlett <[email protected]>Cc Matthew Wilcox (Oracle) <[email protected]>Cc Ryan Roberts <[email protected]>Cc William Kucharski <[email protected]>Cc <[email protected]>Signed-off-by Andrew Morton <[email protected]>Signed-off-by Zi Yan <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- mm/huge_memory.c | 10 ++++++++++ 1 file changed, 10 insertions(+)mm/huge_memory.c +1
-0@@ -3420,6 +3420,7 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,/* reset xarray order to new order after split */ XA_STATE_ORDER (xas, &folio->mapping->i_pages, folio->index, new_order);bool is_anon =folio_test_anon (folio); +struct mem_cgroup *memcg, *old_memcg;struct address_space *mapping =NULL ;struct anon_vma *anon_vma =NULL ;int order =folio_order (folio);
mm/huge_memory.c int split_huge_page_to_list_to_order(struct page *page, struct list_head *list, · line 3493
Quoted 10 lines
mm/huge_memory.c +7
-0@@ -3483,6 +3484,13 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,if (folio_test_writeback (folio))return -EBUSY ; +/* +* switch to folio's memcg as xarray node allocation can happen and +* needs to charge to it. +*/ + memcg =folio_memcg (folio); + old_memcg =set_active_memcg (memcg); +
I ran an AI-assisted review of de480d1cd9ed and I think AI report is valid:
Upstream has:
memcg = get_mem_cgroup_from_folio(folio);old_memcg = set_active_memcg(memcg);
...set_active_memcg(old_memcg);mem_cgroup_put(memcg);
6.12.y has:
memcg = folio_memcg(folio);old_memcg = set_active_memcg(memcg);
...set_active_memcg(old_memcg);
The backport instead passes the raw result of folio_memcg() and never drops a reference. That raw pointer provides neither the css reference required by set_active_memcg() nor the helper's root-memcg fallback. Both get_mem_cgroup_from_folio() and mem_cgroup_put() are already available on this branch.
The backport uses raw folio_memcg() without acquiring the css reference required by set_active_memcg(), and therefore lacks the matching mem_cgroup_put(). It also omits root-memcg fallback. Both helpers already exist on 6.12.y.
Maybe we should replace the folio_memcg() use with the upstream referenced get/put pair ? Maybe lets drop this and get it backported correctly next cycle ?
thanks,
Harshit> if (is_anon) {
Quoted 11 lines
mm/huge_memory.c +2
-0/* * The caller does not necessarily hold an mmap_lock that would @@ -3629,6 +3637,8 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,if (mapping)i_mmap_unlock_read (mapping); out: +/* restore to caller's old_memcg */ +set_active_memcg (old_memcg);xas_destroy (&xas);if (order ==HPAGE_PMD_ORDER )count_vm_event (!ret ?THP_SPLIT_PAGE :THP_SPLIT_PAGE_FAILED );
Sasha Levin
maintainerRe: [PATCH 6.12 0472/1102] mm/huge_memory: use folios memcg inside __folio_split()
Quoted 3 lines · Harshit Mogalapalli
The backport instead passes the raw result of
folio_memcg()and never drops a reference. That raw pointer provides neither the css reference required byset_active_memcg()nor the helper's root-memcg fallback.
[...]
Quoted 1 line
Maybe lets drop this and get it backported correctly next cycle ?
Dropped from the 6.12 and 6.6 queues (the same substitution is present on both, not just 6.12).
Signature · 2 lines
Thanks, Sasha
Re: [PATCH 6.12 0472/1102] mm/huge_memory: use folios memcg inside __folio_split()
In reply to Harshit MogalapalliQuoted 111 lines · Harshit Mogalapalli
Hi Greg/Sasha,
Quoted 71 lines · Greg Kroah-Hartman
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit
c299a2285d9d8bda4da024455de65e3d00de6f17upstream.Patch series "Honor
XA_FLAGS_ACCOUNTinxas_split_alloc()and charge to folio's memcg", v3.
__GFP_ACCOUNTis needed for xarray node allocation accounting whenXA_FLAGS_ACCOUNTis set. Commit7b785645e8f13("mm: fix page cache convergence regression") fixed a workingset regression with it.xas_split_alloc()does not have it and needs to be fixed.In addition, based on Sashiko's review[1] and Johannes' confirmation[2], to charge the right memcg, folio's memcg needs to be active during folio split. Add that before adding
__GFP_ACCOUNT.There is no workingset convergence regression related to missing
__GFP_ACCOUNTinxas_split_alloc()and the impact to userspace should be minor.This patch (of 2):
During a pagecache folio split, an xarray node allocation can happen and needs to charge at folio's memcg instead of folio split invoker's memcg, because for example folio split can happen during reclaim and reclaim's active memcg might not be folio's memcg. Switch to folio's memcg at the beginning and switch back afterwards.
Link https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-0-38cb3ff325c5@nvidia.com open hereLink https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-1-38cb3ff325c5@nvidia.com open hereFixes 6b24ca4a1a8d ("mm: Use multi-index entries in the page cache")Signed-off-by Zi Yan <[email protected]>Suggested-by Johannes Weiner <[email protected]>Reviewed-by Baolin Wang <[email protected]>Acked-by Johannes Weiner <[email protected]>Cc Barry Song <[email protected]>Cc David Hildenbrand <[email protected]>Cc Dev Jain <[email protected]>Cc Lance Yang <[email protected]>Cc Liam R. Howlett <[email protected]>Cc Matthew Wilcox (Oracle) <[email protected]>Cc Ryan Roberts <[email protected]>Cc William Kucharski <[email protected]>Cc <[email protected]>Signed-off-by Andrew Morton <[email protected]>Signed-off-by Zi Yan <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- mm/huge_memory.c | 10 ++++++++++ 1 file changed, 10 insertions(+)mm/huge_memory.c +1
-0@@ -3420,6 +3420,7 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,/* reset xarray order to new order after split */ XA_STATE_ORDER (xas, &folio->mapping->i_pages, folio->index, new_order);bool is_anon =folio_test_anon (folio); +struct mem_cgroup *memcg, *old_memcg;struct address_space *mapping =NULL ;struct anon_vma *anon_vma =NULL ;int order =folio_order (folio);mm/huge_memory.c int split_huge_page_to_list_to_order(struct page *page, struct list_head *list, · line 3493
Quoted 10 lines
mm/huge_memory.c +7
-0@@ -3483,6 +3484,13 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,if (folio_test_writeback (folio))return -EBUSY ; +/* +* switch to folio's memcg as xarray node allocation can happen and +* needs to charge to it. +*/ + memcg =folio_memcg (folio); + old_memcg =set_active_memcg (memcg); +I ran an AI-assisted review of
de480d1cd9edand I think AI report is valid:Upstream has:
memcg =
get_mem_cgroup_from_folio(folio);old_memcg=set_active_memcg(memcg);
...set_active_memcg(old_memcg);mem_cgroup_put(memcg);6.12.y has:
memcg =
folio_memcg(folio);old_memcg=set_active_memcg(memcg);
...set_active_memcg(old_memcg);The backport instead passes the raw result of
folio_memcg()and never drops a reference. That raw pointer provides neither the css reference required byset_active_memcg()nor the helper's root-memcg fallback. Bothget_mem_cgroup_from_folio()andmem_cgroup_put()are already available on this branch.
Quoted 8 lines
The backport uses raw
folio_memcg()without acquiring the css reference required byset_active_memcg(), and therefore lacks the matchingmem_cgroup_put(). It also omits root-memcg fallback. Both helpers already exist on 6.12.y.Maybe we should replace the
folio_memcg()use with the upstream referenced get/put pair ? Maybe lets drop this and get it backported correctly next cycle ?
No. 6.12.y backport is correct. The same reason for 6.6.y backport[1] applies here:
|> Before commit f1cf8d2f36dc3 ("mm: memcontrol:
|> eliminate the problem of dying memory cgroup for LRU folios"), like
|> v6.6, a charged folio take a ref on its memcg. During split, the folio
|> is locked, so will not be uncharged. As a result, its memcg will not go
|> away.Commit f1cf8d2f36dc3 is introduced in 7.1.
[1] https://lore.kernel.org/all/[email protected]/
Quoted 14 lines
thanks,
Harshit> if (is_anon) {Quoted 11 lines
mm/huge_memory.c +2
-0/* * The caller does not necessarily hold an mmap_lock that would @@ -3629,6 +3637,8 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,if (mapping)i_mmap_unlock_read (mapping); out: +/* restore to caller's old_memcg */ +set_active_memcg (old_memcg);xas_destroy (&xas);if (order ==HPAGE_PMD_ORDER )count_vm_event (!ret ?THP_SPLIT_PAGE :THP_SPLIT_PAGE_FAILED );
Signature · 2 lines
Best Regards, Yan, Zi
Re: [PATCH 6.12 0472/1102] mm/huge_memory: use folios memcg inside __folio_split()
Hi Zi Yan, Sasha,
Quoted 5 lines · Zi Yan
Quoted 1 line
Maybe we should replace the
folio_memcg()use with the upstream referenced get/put pair ? Maybe lets drop this and get it backported correctly next cycle ?No. 6.12.y backport is correct. The same reason for 6.6.y backport[1] applies here:
Quoted 8 lines
|> Before commit f1cf8d2f36dc3 ("mm: memcontrol: |> eliminate the problem of dying memory cgroup for LRU folios"), like |> v6.6, a charged folio take a ref on its memcg. During split, the folio |> is locked, so will not be uncharged. As a result, its memcg will not go |> away.Commit
f1cf8d2f36dc3is introduced in 7.1.
thanks a lot for checking and responding.
Looks like a very similar report was clarified by Johannes and Zi. Sorry for the noise.
Sasha: Will it be possible for you to re-queue this ?
thanks,
Harshit
Quoted 2 lines
Sasha Levin
maintainerRe: [PATCH 6.12 0472/1102] mm/huge_memory: use folios memcg inside __folio_split()
Quoted 4 lines
Looks like a very similar report was clarified by Johannes and Zi. Sorry for the noise.
Sasha: Will it be possible for you to re-queue this ?
Re-queued for 6.12 and 6.6, thanks. No noise at all, it is easier to put a patch back than to ship a broken one.
Signature · 2 lines
Thanks, Sasha
Greg Kroah-Hartman
maintainerPATCH 473/1102 drm/amd/display: clean-up dead code in dml2_mall_phantom
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brahmajit Das <[email protected]>
[ Upstream commit f117eca965c797c5efb55ee40543cb37b9cb7d23 ]
pipe_idx in funtion dml2_svp_validate_static_schedulabilit, although set is never actually used. While building with GCC 16 this gives a warning:
drivers/gpu/drm/amd/amdgpu/../display/dc/dml2/dml2_mall_phantom.c: In function ‘set_phantom_stream_timing’:drivers/gpu/drm/amd/amdgpu/../display/dc/dml2/dml2_mall_phantom.c:657:25: warning: variable ‘pipe_idx’ set but not used [-Wunused-but-set-variable=]
657 | unsigned int i, pipe_idx;
| ^~~~~~~~--- drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c +2 -4
@@ -654,14 +654,14 @@ static void set_phantom_stream_timing(struct dml2_context *ctx, struct dc_stateunsigned int svp_height, unsigned int svp_vstartup) { - unsigned int i, pipe_idx; + unsigned int i;double line_time, fp_and_sync_width_time;struct pipe_ctx *pipe;uint32_t phantom_vactive, phantom_bp, pstate_width_fw_delay_lines;static const double cvt_rb_vblank_max = ((double )460 / (1000 *1000 ));// Find DML pipe index (pipe_idx) using dc_pipe_idx -for (i =0 , pipe_idx =0 ; i < ctx->config.dcn_pipe_count; i++) { +for (i =0 ; i < ctx->config.dcn_pipe_count; i++) { pipe = &state->res_ctx.pipe_ctx[i];if (!pipe->stream)
@@ -669,8 +669,6 @@ static void set_phantom_stream_timing(struct dml2_context *ctx, struct dc_stateif (i == dc_pipe_idx)break ; - - pipe_idx++; }// Calculate lines required for pstate allow width and FW processing delays
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 474/1102 driver core: Export get_dev_from_fwnode()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ulf Hansson <[email protected]>
[ Upstream commit 9a4681a485ee1203ac968065490a8eeaa6615503 ]
It has turned out get_dev_from_fwnode() is useful at a few other places outside of the driver core, as in gpiolib.c for example. Therefore let's make it available as a common helper function.
--- drivers/base/core.c | 8 ++++++-- include/linux/device.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)
drivers/base/core.c +6 -2
@@ -1881,8 +1881,6 @@ static void fw_devlink_unblock_consumers(struct device *dev)device_links_write_unlock (); } -#define get_dev_from_fwnode (fwnode) get_device((fwnode)->dev) -static bool fwnode_init_without_drv (struct fwnode_handle *fwnode) {struct device *dev;
@@ -5209,6 +5207,12 @@ void device_set_node(struct device *dev, struct fwnode_handle *fwnode) }EXPORT_SYMBOL_GPL (device_set_node); +struct device *get_dev_from_fwnode (struct fwnode_handle *fwnode) +{ +return get_device ((fwnode)->dev); +} +EXPORT_SYMBOL_GPL (get_dev_from_fwnode); +int device_match_name (struct device *dev,const void *name) {return sysfs_streq (dev_name (dev), name);
include/linux/device.h +1 -0
@@ -1138,6 +1138,7 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode);void set_secondary_fwnode (struct device *dev,struct fwnode_handle *fwnode);void device_set_node (struct device *dev,struct fwnode_handle *fwnode);void device_set_of_node_from_dev (struct device *dev,const struct device *dev2); +struct device *get_dev_from_fwnode (struct fwnode_handle *fwnode);static inline struct device_node *dev_of_node (struct device *dev) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 475/1102 of: dynamic: Fix overlayed devices not probing because of fw_devlink
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saravana Kannan <[email protected]>
[ Upstream commit 81e7c6befa36cecdcbf7244393bd67e8f8c59bf5 ]
When an overlay is applied, if the target device has already probed successfully and bound to a device, then some of the fw_devlink logic that ran when the device was probed needs to be rerun. This allows newly created dangling consumers of the overlayed device tree nodes to be moved to become consumers of the target device.
[Herve: Add the call to driver_deferred_probe_trigger()] [Herve: Use fwnode_test_flag() to test fwnode flags value]
--- drivers/base/core.c | 83 +++++++++++++++++++++++++++++++++++++----- drivers/of/overlay.c | 15 ++++++++ include/linux/fwnode.h | 1 + 3 files changed, 90 insertions(+), 9 deletions(-)
drivers/base/core.c +74 -9
@@ -235,6 +235,79 @@ static void __fw_devlink_pickup_dangling_consumers(struct fwnode_handle *fwnode,__fw_devlink_pickup_dangling_consumers (child, new_sup); } +static void fw_devlink_pickup_dangling_consumers (struct device *dev) +{ +struct fwnode_handle *child; + +guard (mutex)(&fwnode_link_lock); + +fwnode_for_each_available_child_node (dev->fwnode, child) +__fw_devlink_pickup_dangling_consumers (child, dev->fwnode); +__fw_devlink_link_to_consumers (dev); +} + +/** +* fw_devlink_refresh_fwnode - Recheck the tree under this firmware node +* @fwnode: The fwnode under which the fwnode tree has changed +* +* This function is mainly meant to adjust the supplier/consumer dependencies +* after a fwnode tree overlay has occurred. +*/ +void fw_devlink_refresh_fwnode (struct fwnode_handle *fwnode) +{ +struct device *dev; + +/* +* Find the closest ancestor fwnode that has been converted to a device +* that can bind to a driver (bus device). +*/ +fwnode_handle_get (fwnode); +do { +if (fwnode_test_flag (fwnode,FWNODE_FLAG_NOT_DEVICE )) +continue ; + + dev =get_dev_from_fwnode (fwnode); +if (!dev) +continue ; + +if (dev->bus) +break ; + +put_device (dev); + }while ((fwnode =fwnode_get_next_parent (fwnode))); + +/* +* If none of the ancestor fwnodes have (yet) been converted to a device +* that can bind to a driver, there's nothing to fix up. +*/ +if (!fwnode) +return ; + +WARN (device_is_bound (dev) && dev->links.status !=DL_DEV_DRIVER_BOUND , +"Don't multithread overlaying and probing the same device!\n" ); + +/* +* If the device has already bound to a driver, then we need to redo +* some of the work that was done after the device was bound to a +* driver. If the device hasn't bound to a driver, running things too +* soon would incorrectly pick up consumers that it shouldn't. +*/ +if (dev->links.status ==DL_DEV_DRIVER_BOUND ) { +fw_devlink_pickup_dangling_consumers (dev); +/* +* Some of dangling consumers could have been put previously in +* the deferred probe list due to the unavailability of their +* suppliers. Those consumers have been picked up and some of +* their suppliers links have been updated. Time to re-try their +* probe sequence. +*/ +driver_deferred_probe_trigger (); + } + +put_device (dev); +fwnode_handle_put (fwnode); +} +static DEFINE_MUTEX (device_links_lock);DEFINE_STATIC_SRCU (device_links_srcu);
@@ -1313,16 +1386,8 @@ void device_links_driver_bound(struct device *dev)* child firmware node. */ if (dev->fwnode && dev->fwnode->dev == dev) { -struct fwnode_handle *child; -fwnode_links_purge_suppliers (dev->fwnode); - -guard (mutex)(&fwnode_link_lock); - -fwnode_for_each_available_child_node (dev->fwnode, child) -__fw_devlink_pickup_dangling_consumers (child, - dev->fwnode); -__fw_devlink_link_to_consumers (dev); +fw_devlink_pickup_dangling_consumers (dev); }device_remove_file (dev, &dev_attr_waiting_for_supplier);
drivers/of/overlay.c +15 -0
@@ -179,6 +179,15 @@ static int overlay_notify(struct overlay_changeset *ovcs,return 0 ; } +static void overlay_fw_devlink_refresh (struct overlay_changeset *ovcs) +{ +for (int i =0 ; i < ovcs->count; i++) { +struct device_node *np = ovcs->fragments[i].target; + +fw_devlink_refresh_fwnode (of_fwnode_handle (np)); + } +} +/* * The values of properties in the "/__symbols__" node are paths in * the ovcs->overlay_root. When duplicating the properties, the paths
@@ -946,6 +955,12 @@ static int of_overlay_apply(struct overlay_changeset *ovcs,pr_err ("overlay apply changeset entry notify error %d\n" , ret);/* notify failure is not fatal, continue */ +/* +* Needs to happen after changeset notify to give the listeners a chance +* to finish creating all the devices they need to create. +*/ +overlay_fw_devlink_refresh (ovcs); + ret_tmp =overlay_notify (ovcs,OF_OVERLAY_POST_APPLY );if (ret_tmp)if (!ret)
include/linux/fwnode.h +1 -0
@@ -245,6 +245,7 @@ int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup, u8 flags);void fwnode_links_purge (struct fwnode_handle *fwnode);void fw_devlink_purge_absent_suppliers (struct fwnode_handle *fwnode); +void fw_devlink_refresh_fwnode (struct fwnode_handle *fwnode);bool fw_devlink_is_strict (void );#endif
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 476/1102 ppp_async: drop the errored frame instead of resetting its headroom
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlatko Kosturjak <[email protected]>
[ Upstream commit 8dc5d98a16fa23c00999aecf10018c9f69fa5bf4 ]
ppp_receive_nonmp_frame() prepends a two-byte direction tag before running the pass/active BPF filters:
*(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_INBOUND_TAG);
Nothing on the receive path guarantees those two bytes of headroom. The frame-error path in ppp_async's process_input_packet() resets a reused skb's headroom to zero while claiming to restore it to a freshly allocated state - but a fresh skb from dev_alloc_skb() carries NET_SKB_PAD:
err:
if (skb) {
/* make skb appear as freshly allocated */
skb_trim(skb, 0);
skb_reserve(skb, - skb_headroom(skb));
}ap->rpkt still points at that skb, so the next frame is reassembled into it with no headroom at all. A peer that sends a bad-FCS frame followed by one beginning ff 03 then leaves a single byte of headroom by the time the filter tag is pushed, which lands one byte below skb->head:
skbuff: skb_under_panic: len:49 put:2 head:ffff888003c10000
data:ffff888003c0ffff tail:0x30 end:0x640 dev:<NULL> kernel BUG at net/core/skbuff.c:214! RIP: 0010:skb_panic+0x13e/0x230 Call Trace: skb_push+0xbd/0x100 ppp_receive_nonmp_frame+0x48a/0x1d10 ppp_input+0x4e9/0x2f80 ppp_async_process+0x2a/0xe0 tasklet_action_common+0x20f/0x8a0 handle_softirqs+0x18e/0x590 Kernel panic - not syncing: Fatal exception in interrupt
Zeroing the headroom violates the NET_SKB_PAD guarantee that dev_alloc_skb() gives the rest of the receive path. Besides the filter panic above, when CCP compression is enabled ppp_decompress_frame() hands skb->data - 2 to ->decompress()/->incomp(), which then reads out of bounds before skb->head for the same reason.
Rather than restore the headroom, drop the errored frame - as ppp_synctty already does on its error path - and clear ap->rpkt so the next frame is reassembled into a fresh skb with proper headroom. This is simpler and fixes both the filter under-panic and the CCP out-of-bounds read.
The original V1 of this patch made room in ppp_receive_nonmp_frame() with skb_cow_head(); Eric pointed out that fixing the root cause in the transport is the right approach.
Found by fuzzing the PPP receive path with a mutating peer on a pty; it is an interesting (remote) DoS: root configures PPP, the peer supplies two crashing frames. The reproducer (repro-ppp-skb.c, unchanged from v1) panics in about a second, and returns cleanly with this applied.
--- drivers/net/ppp/ppp_async.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/net/ppp/ppp_async.c +2 -5
@@ -812,11 +812,8 @@ process_input_packet(struct asyncppp *ap) err:/* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */ ap->state =SC_PREV_ERROR ; -if (skb) { -/* make skb appear as freshly allocated */ -skb_trim (skb,0 ); -skb_reserve (skb, -skb_headroom (skb)); - } +kfree_skb (skb); + ap->rpkt =NULL ; }/* Called when the tty driver has data for us. Runs parallel with the
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 477/1102 drop_monitor: perform u64_stats updates under IRQ-disabled section
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit fd098a23bf8fda7eae48db9b06e7c34fc4d228fa ]
In net_dm_packet_trace_kfree_skb_hit() and net_dm_hw_trap_packet_probe(), u64_stats_update_begin() / u64_stats_inc() / u64_stats_update_end() were called after spin_unlock_irqrestore(&...drop_queue.lock, flags), when local IRQs had already been re-enabled.
Tracepoint probes can execute in IRQ or softirq context. On 32-bit architectures, u64_stats_update_begin() disables preemption but not interrupts, relying on seqcount writes. If a nested interrupt occurs on the same CPU during the 64-bit stats update, the reentrant seqcount update can corrupt the seqcount state or stats value.
Fix this by performing the 64-bit per-CPU stats update before releasing drop_queue.lock via spin_unlock_irqrestore(), ensuring local interrupts remain disabled during the u64_stats update.
--- net/core/drop_monitor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/core/drop_monitor.c +2 -2
@@ -531,10 +531,10 @@ static void net_dm_packet_trace_kfree_skb_hit(void *ignore,return ; unlock_free: -spin_unlock_irqrestore (&data->drop_queue.lock, flags);u64_stats_update_begin (&data->stats.syncp);u64_stats_inc (&data->stats.dropped);u64_stats_update_end (&data->stats.syncp); +spin_unlock_irqrestore (&data->drop_queue.lock, flags);consume_skb (nskb); }
@@ -1002,10 +1002,10 @@ net_dm_hw_trap_packet_probe(void *ignore, const struct devlink *devlink,return ; unlock_free: -spin_unlock_irqrestore (&hw_data->drop_queue.lock, flags);u64_stats_update_begin (&hw_data->stats.syncp);u64_stats_inc (&hw_data->stats.dropped);u64_stats_update_end (&hw_data->stats.syncp); +spin_unlock_irqrestore (&hw_data->drop_queue.lock, flags);net_dm_hw_metadata_free (n_hw_metadata); free:consume_skb (nskb);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 478/1102 drop_monitor: fix size calculations for 64-bit attributes
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 7089f7ab99c89f443c92d8fcc585e63f2727f0b3 ]
net_dm_packet_report_fill() and net_dm_hw_packet_report_fill() use nla_put_u64_64bit() to append 64-bit attributes (NET_DM_ATTR_PC and NET_DM_ATTR_TIMESTAMP).
On 32-bit architectures without CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS, nla_put_u64_64bit() may append a 4-byte NET_DM_ATTR_PAD attribute for 64-bit alignment.
However, net_dm_packet_report_size() and net_dm_hw_packet_report_size() used nla_total_size(sizeof(u64)) instead of nla_total_size_64bit(sizeof(u64)), budgeting 12 bytes instead of up to 16 bytes.
This under-estimation of SKB size can lead to an skb_over_panic() when __nla_reserve() or skb_put() is subsequently called.
Fix this by using nla_total_size_64bit(sizeof(u64)) in both size calculations.
--- net/core/drop_monitor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/core/drop_monitor.c +3 -3
@@ -567,13 +567,13 @@ static size_t net_dm_packet_report_size(size_t payload_len)/* NET_DM_ATTR_ORIGIN */ nla_total_size (sizeof (u16)) +/* NET_DM_ATTR_PC */ -nla_total_size (sizeof (u64)) + +nla_total_size_64bit (sizeof (u64)) +/* NET_DM_ATTR_SYMBOL */ nla_total_size (NET_DM_MAX_SYMBOL_LEN +1 ) +/* NET_DM_ATTR_IN_PORT */ net_dm_in_port_size () +/* NET_DM_ATTR_TIMESTAMP */ -nla_total_size (sizeof (u64)) + +nla_total_size_64bit (sizeof (u64)) +/* NET_DM_ATTR_ORIG_LEN */ nla_total_size (sizeof (u32)) + /* NET_DM_ATTR_PROTO */
@@ -769,7 +769,7 @@ net_dm_hw_packet_report_size(size_t payload_len,/* NET_DM_ATTR_FLOW_ACTION_COOKIE */ net_dm_flow_action_cookie_size (hw_metadata) +/* NET_DM_ATTR_TIMESTAMP */ -nla_total_size (sizeof (u64)) + +nla_total_size_64bit (sizeof (u64)) +/* NET_DM_ATTR_ORIG_LEN */ nla_total_size (sizeof (u32)) + /* NET_DM_ATTR_PROTO */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 479/1102 net: drop_monitor: fix info leak in NET_DM_ATTR_PAYLOAD
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yehyeong Lee <[email protected]>
[ Upstream commit 5e9c8baee0329fbefe7c67aea945e2a07f15e98b ]
net_dm_packet_report_fill() and net_dm_hw_packet_report_fill() open code the NET_DM_ATTR_PAYLOAD attribute to avoid zeroing the packet payload before overwriting it with skb_copy_bits().
skb_put() reserves nla_total_size(payload_len), i.e. the header plus the NLA_ALIGN() padding, but only payload_len bytes are copied in. When payload_len is not a multiple of 4 the 1-3 padding bytes are never initialized and are leaked to user space inside the netlink message.
KMSAN confirms the leak for the software path when the packet payload length is not 4-byte aligned:
BUG: KMSAN: kernel-infoleak in _copy_to_iter _copy_to_iter __skb_datagram_iter skb_copy_datagram_iter netlink_recvmsg sock_recvmsg __sys_recvfrom Uninit was created at: kmem_cache_alloc_node_noprof __alloc_skb net_dm_packet_work Bytes 173-175 of 176 are uninitialized
Use __nla_reserve(), which sets up the attribute header and zeroes the padding, instead of open coding the attribute construction.
--- net/core/drop_monitor.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
net/core/drop_monitor.c +2 -6
@@ -672,9 +672,7 @@ static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb,if (nla_put_u16 (msg,NET_DM_ATTR_PROTO ,be16_to_cpu (skb->protocol))) goto nla_put_failure; - attr =skb_put (msg,nla_total_size (payload_len)); - attr->nla_type =NET_DM_ATTR_PAYLOAD ; - attr->nla_len =nla_attr_size (payload_len); + attr =__nla_reserve (msg,NET_DM_ATTR_PAYLOAD , payload_len);if (skb_copy_bits (skb,0 ,nla_data (attr), payload_len)) goto nla_put_failure;
@@ -832,9 +830,7 @@ static int net_dm_hw_packet_report_fill(struct sk_buff *msg,if (nla_put_u16 (msg,NET_DM_ATTR_PROTO ,be16_to_cpu (skb->protocol))) goto nla_put_failure; - attr =skb_put (msg,nla_total_size (payload_len)); - attr->nla_type =NET_DM_ATTR_PAYLOAD ; - attr->nla_len =nla_attr_size (payload_len); + attr =__nla_reserve (msg,NET_DM_ATTR_PAYLOAD , payload_len);if (skb_copy_bits (skb,0 ,nla_data (attr), payload_len)) goto nla_put_failure;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 480/1102 tipc: fix integer overflow in tipc_recvmsg() and tipc_recvstream()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang (Microsoft) <[email protected]>
[ Upstream commit 47f42ff521b4eeb46e82f9a46a4783a99f7570d7 ]
In tipc_recvmsg(), the copy length is computed as:
copy = min_t(int, dlen - offset, buflen);
buflen is size_t but min_t(int, ...) casts it to int. When buflen exceeds INT_MAX (e.g. 0xFFFFFFFF via io_uring provided buffers), it wraps negative, wins the comparison, and the negative copy length propagates to simple_copy_to_iter() where int-to-size_t promotion makes it SIZE_MAX, triggering a WARN_ON. tipc_recvstream() has the same pattern.
Kernel panic - not syncing: kernel: panic_on_warn set ... RIP: 0010:simple_copy_to_iter+0x9e/0xd0 (net/core/datagram.c:521) Call Trace: __skb_datagram_iter+0x123/0x8b0 (net/core/datagram.c:402) skb_copy_datagram_iter+0x77/0x1a0 (net/core/datagram.c:534) tipc_recvmsg+0x3d7/0xe80 (net/tipc/socket.c:1934) io_recvmsg+0x47e/0xda0
Fix by changing min_t(int, ...) to min_t(size_t, ...) in both functions. The result is always <= (dlen - offset), which is bounded by TIPC maximum message size (0x1ffff bytes), so the implicit narrowing on assignment to int copy is always safe.
--- net/tipc/socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/tipc/socket.c +2 -2
@@ -1935,7 +1935,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,if (likely (!err)) {int offset = skb_cb->bytes_read; - copy =min_t (int, dlen - offset, buflen); + copy =min_t (size_t, dlen - offset, buflen); rc =skb_copy_datagram_msg (skb, hlen + offset, m, copy);if (unlikely (rc)) goto exit;
@@ -2067,7 +2067,7 @@ static int tipc_recvstream(struct socket *sock, struct msghdr *m,/* Copy data if msg ok, otherwise return error/partial data */ if (likely (!err)) { offset = skb_cb->bytes_read; - copy =min_t (int, dlen - offset, buflen - copied); + copy =min_t (size_t, dlen - offset, buflen - copied); rc =skb_copy_datagram_msg (skb, hlen + offset, m, copy);if (unlikely (rc))break ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 481/1102 drm/vc4: hvs/v3d: Fix null dereference in unbind
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregor Herburger <[email protected]>
[ Upstream commit 7dc3680b7ffe01add3e9299fde8471d2dd53a8ae ]
The hvs and v3d drivers use dev_get_drvdata(master) in their unbind functions. Since the vc4-drm gets removed before its dependent drivers (vc4_hvs/vc4_v3d) the vc4_hvs_unbind/vc4_v3d_unbind functions try to get drvdata of its master and fails with a null dereference error.
Use the data pointer passed to the unbind functions directly instead of dev_get_drvdata(master). This avoids using potentially freed memory.
--- drivers/gpu/drm/vc4/vc4_hvs.c | 2 +- drivers/gpu/drm/vc4/vc4_v3d.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/vc4/vc4_hvs.c +1 -1
@@ -1052,7 +1052,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)static void vc4_hvs_unbind (struct device *dev,struct device *master,void *data) { -struct drm_device *drm =dev_get_drvdata (master); +struct drm_device *drm = data;struct vc4_dev *vc4 =to_vc4_dev (drm);struct vc4_hvs *hvs = vc4->hvs;struct drm_mm_node *node, *next;
drivers/gpu/drm/vc4/vc4_v3d.c +1 -1
@@ -492,7 +492,7 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)static void vc4_v3d_unbind (struct device *dev,struct device *master,void *data) { -struct drm_device *drm =dev_get_drvdata (master); +struct drm_device *drm = data;struct vc4_dev *vc4 =to_vc4_dev (drm);vc4_irq_uninstall (drm);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 482/1102 bpf: Reject redirect helpers without a bpf_net_context
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit 3f4920d165b29052255527d8ae7619e7ec132ece ]
The bpf_redirect*() helpers and skb_do_redirect() obtain the per-task bpf_redirect_info via bpf_net_ctx_get_ri(), which dereferences the current->bpf_net_context unconditionally. That context is established on the paths that run tc BPF such as sch_handle_{ingress,egress}(), *except* for the case where {cls,act}_bpf was attached to a proper qdisc. A program running from there reaches the NULL deref in two ways:
* It calls bpf_redirect() directly, which dereferences the context at the top of the helper:
tc qdisc add dev eth0 root handle 1: red limit 1MB min 10KB max 20KB \
avpkt 1000 burst 100 qevent early_drop block 10
tc filter add block 10 pref 1 bpf obj redirect.o
* It simply returns TC_ACT_REDIRECT without helper call: tcf_qevent_handle() then dispatches to skb_do_redirect(), which dereferences the context
Rather than extending bpf_net_context management into the qdisc path, make the redirect helpers refuse to operate when no context exists, and have tcf_qevent_handle() drop a TC_ACT_REDIRECT verdict instead of calling skb_do_redirect(). Previous behaviour was a crash, so nothing regresses by not supporting it.
--- net/core/filter.c | 17 +++++++++++------ net/sched/cls_api.c | 6 ++---- 2 files changed, 13 insertions(+), 10 deletions(-)
net/core/filter.c +11 -6
@@ -2559,11 +2559,13 @@ int skb_do_redirect(struct sk_buff *skb) BPF_CALL_2(bpf_redirect, u32, ifindex, u64, flags) { -struct bpf_redirect_info *ri =bpf_net_ctx_get_ri (); +struct bpf_redirect_info *ri; -if (unlikely (flags & (~(BPF_F_INGRESS ) |BPF_F_REDIRECT_INTERNAL ))) +if (unlikely (!bpf_net_ctx_get () || + (flags & (~(BPF_F_INGRESS ) |BPF_F_REDIRECT_INTERNAL ))))return TC_ACT_SHOT ; + ri =bpf_net_ctx_get_ri (); ri->flags = flags; ri->tgt_index = ifindex;
@@ -2580,11 +2582,12 @@ static const struct bpf_func_proto bpf_redirect_proto = { BPF_CALL_2(bpf_redirect_peer, u32, ifindex, u64, flags) { -struct bpf_redirect_info *ri =bpf_net_ctx_get_ri (); +struct bpf_redirect_info *ri; -if (unlikely (flags)) +if (unlikely (!bpf_net_ctx_get () || flags))return TC_ACT_SHOT ; + ri =bpf_net_ctx_get_ri (); ri->flags =BPF_F_PEER ; ri->tgt_index = ifindex;
@@ -2602,11 +2605,13 @@ static const struct bpf_func_proto bpf_redirect_peer_proto = { BPF_CALL_4(bpf_redirect_neigh, u32, ifindex, struct bpf_redir_neigh *, params, int, plen, u64, flags) { -struct bpf_redirect_info *ri =bpf_net_ctx_get_ri (); +struct bpf_redirect_info *ri; -if (unlikely ((plen && plen <sizeof (*params)) || flags)) +if (unlikely ((plen && plen <sizeof (*params)) || + !bpf_net_ctx_get () || flags))return TC_ACT_SHOT ; + ri =bpf_net_ctx_get_ri (); ri->flags =BPF_F_NEIGH | (plen ?BPF_F_NEXTHOP :0 ); ri->tgt_index = ifindex;
net/sched/cls_api.c +2 -4
@@ -4059,6 +4059,8 @@ struct sk_buff *tcf_qevent_handle(struct tcf_qevent *qe, struct Qdisc *sch, stru fl =rcu_dereference_bh (qe->filter_chain);switch (tcf_classify (skb,NULL , fl, &cl_res, false)) { +case TC_ACT_REDIRECT : + fallthrough;case TC_ACT_SHOT :qdisc_qstats_drop (sch);__qdisc_drop (skb, to_free);
@@ -4070,10 +4072,6 @@ struct sk_buff *tcf_qevent_handle(struct tcf_qevent *qe, struct Qdisc *sch, stru__qdisc_drop (skb, to_free); *ret = __NET_XMIT_STOLEN;return NULL ; -case TC_ACT_REDIRECT : -skb_do_redirect (skb); - *ret = __NET_XMIT_STOLEN; -return NULL ;case TC_ACT_CONSUMED : *ret = __NET_XMIT_STOLEN;return NULL ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 483/1102 Bluetooth: ISO: fix malformed ISO_END/CONT handling
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
[ Upstream commit e054c1a6ae7310d2815778fddb87da616e11c255 ]
Core specification (Part C vol 4 sec 5.4.5) does not exclude empty ISO_CONT, ISO_END packets. We currently reject them if they are last.
If controller sends malformed sequence
ISO_START -> rx_len = 4, ISO_CONT skb->len 4, ISO_START
that ends payload in ISO_CONT, we leak conn->rx_skb. If controller sends too long ISO_END, we panic on skb_put. If controller sends too short ISO_END we accept it.
Fix by marking unfinished ISO_START via conn->rx_skb != NULL. Check skb->len properly before skb_put. Combine the ISO_CONT/END code paths as they require the same initial checks. Reject too short ISO_END packets.
--- net/bluetooth/iso.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-)
net/bluetooth/iso.c +16 -15
@@ -2329,7 +2329,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)switch (pb) {case ISO_START :case ISO_SINGLE : -if (conn->rx_len) { +if (conn->rx_skb || conn->rx_len) {BT_ERR ("Unexpected start frame (len %d)" , skb->len);kfree_skb (conn->rx_skb); conn->rx_skb =NULL ;
@@ -2396,12 +2396,14 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)break ;case ISO_CONT : -BT_DBG ("Cont: frag len %d (expecting %d)" , skb->len, +case ISO_END : +BT_DBG ("%s: frag len %d (expecting %d)" , + (pb ==ISO_END ) ?"End" :"Cont" , skb->len, conn->rx_len); -if (!conn->rx_len) { -BT_ERR ("Unexpected continuation frame (len %d)" , - skb->len); +if (!conn->rx_skb) { +BT_ERR ("Unexpected ISO %s frame (len %d)" , + (pb ==ISO_END ) ?"End" :"Cont" , skb->len); goto drop; }
@@ -2417,17 +2419,9 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)skb_copy_from_linear_data (skb,skb_put (conn->rx_skb, skb->len), skb->len); conn->rx_len -= skb->len; -break ; -case ISO_END : -if (!conn->rx_len) { -BT_ERR ("Unexpected end frame (len %d)" , skb->len); - goto drop; - } - -skb_copy_from_linear_data (skb,skb_put (conn->rx_skb, skb->len), - skb->len); - conn->rx_len -= skb->len; +if (pb ==ISO_CONT ) +break ;if (!conn->rx_len) {struct sk_buff *rx_skb = conn->rx_skb;
@@ -2438,6 +2432,13 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)*/ conn->rx_skb =NULL ;iso_recv_frame (conn, rx_skb); + }else { +BT_ERR ("ISO fragment incomplete (len %d, expected %d)" , + skb->len, conn->rx_len); +kfree_skb (conn->rx_skb); + conn->rx_skb =NULL ; + conn->rx_len =0 ; + goto drop; }break ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 484/1102 bpf: Mask pseudo pointer values in verifier logs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuoqi Gui <[email protected]>
[ Upstream commit 72a85e9464a5332fb2cd7efd26d9295275ceda2d ]
print_bpf_insn() masks ldimm64 immediates for pointer-bearing pseudo sources when pointer leaks are not allowed, but the mask only covers BPF_PSEUDO_MAP_FD and BPF_PSEUDO_MAP_VALUE.
BPF_PSEUDO_MAP_IDX, BPF_PSEUDO_MAP_IDX_VALUE, and BPF_PSEUDO_BTF_ID can also be resolved to kernel pointer values before the verifier log prints the instruction. Include them in the existing pointer classification so the log prints 0x0 instead of the rewritten address.
--- kernel/bpf/disasm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/bpf/disasm.c +4 -1
@@ -311,7 +311,10 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,*/ u64 imm = ((u64)(insn +1 )->imm <<32 ) | (u32 )insn->imm;bool is_ptr = insn->src_reg ==BPF_PSEUDO_MAP_FD || - insn->src_reg ==BPF_PSEUDO_MAP_VALUE ; + insn->src_reg ==BPF_PSEUDO_MAP_VALUE || + insn->src_reg ==BPF_PSEUDO_MAP_IDX || + insn->src_reg ==BPF_PSEUDO_MAP_IDX_VALUE || + insn->src_reg ==BPF_PSEUDO_BTF_ID ;char tmp[64 ];if (is_ptr && !allow_ptr_leaks)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 485/1102 sctp: fix err_chunk memory leaks in INIT handling
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
[ Upstream commit 9f58a0a4d6c2ed5d341bba64f058f15d1b0c36f2 ]
When sctp_verify_init() encounters unrecognized parameters, it allocates an err_chunk to report them. However, this chunk is leaked in several code paths:
1. In sctp_sf_do_5_1B_init(), if security_sctp_assoc_request() fails after sctp_verify_init() has populated err_chunk, the function returns immediately without freeing it.
2. In sctp_sf_do_unexpected_init(), the same leak occurs on the security_sctp_assoc_request() failure path.
3. In sctp_sf_do_unexpected_init(), on the success path after copying unrecognized parameters to the INIT-ACK, the function returns without freeing err_chunk, unlike sctp_sf_do_5_1B_init() which properly frees it.
Fix all three leaks by adding sctp_chunk_free(err_chunk) calls before returning in the error paths and on the success path in sctp_sf_do_unexpected_init().
--- net/sctp/sm_statefuns.c | 5 +++++ 1 file changed, 5 insertions(+)
net/sctp/sm_statefuns.c +5 -0
@@ -416,6 +416,8 @@ enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,/* Update socket peer label if first association. */ if (security_sctp_assoc_request (new_asoc, chunk->skb)) {sctp_association_free (new_asoc); +if (err_chunk) +sctp_chunk_free (err_chunk);return sctp_sf_pdiscard (net, ep, asoc, type, arg, commands); }
@@ -1607,6 +1609,8 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(/* Update socket peer label if first association. */ if (security_sctp_assoc_request (new_asoc, chunk->skb)) {sctp_association_free (new_asoc); +if (err_chunk) +sctp_chunk_free (err_chunk);return sctp_sf_pdiscard (net, ep, asoc, type, arg, commands); }
@@ -1672,6 +1676,7 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(* parameter type. */ sctp_addto_chunk (repl, len, unk_param); +sctp_chunk_free (err_chunk); }sctp_add_cmd_sf (commands,SCTP_CMD_NEW_ASOC ,SCTP_ASOC (new_asoc));
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 486/1102 md/raid10: fix writes_pending and barrier reference leaks on discard failures
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abd-Alrhman Masalkhi <[email protected]>
[ Upstream commit 393d687131d8aa8c7e4de2cb494438e145d20fc2 ]
raid10_make_request() acquires a writes_pending reference with md_write_start() before calling raid10_handle_discard(). Several failure paths in raid10_handle_discard() complete the bio and return without releasing the corresponding reference, causing md_write_end() to be skipped.
Call md_write_end() before returning from these failure paths to keep writes_pending accounting balanced.
Additionally, discard split allocation failures can occur after wait_barrier() succeeds. Those paths return without calling allow_barrier(), leaking the associated barrier reference.
Release the barrier before returning from those paths.
--- drivers/md/raid10.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/md/raid10.c +5 -0
@@ -1628,6 +1628,7 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)if (!wait_barrier (conf, bio->bi_opf &REQ_NOWAIT )) {bio_wouldblock_error (bio); +md_write_end (mddev);return 0 ; }
@@ -1670,6 +1671,8 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)if (IS_ERR (split)) { bio->bi_status =errno_to_blk_status (PTR_ERR (split));bio_endio (bio); +md_write_end (mddev); +allow_barrier (conf);return 0 ; }
@@ -1687,6 +1690,8 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)if (IS_ERR (split)) { bio->bi_status =errno_to_blk_status (PTR_ERR (split));bio_endio (bio); +md_write_end (mddev); +allow_barrier (conf);return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 487/1102 coresight: platform: defer connection counter increment until alloc succeeds
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jie Gan <[email protected]>
[ Upstream commit 1563ae33dc4f5ebac96b93af2ef72e72aaaa31ae ]
coresight_add_out_conn() increments nr_outconns before calling devm_krealloc_array() and again before devm_kmalloc(). If either allocation fails, the counter is already bumped while the corresponding array entry is NULL or uninitialized garbage.
coresight_add_in_conn() has the same problem with nr_inconns and devm_krealloc_array().
In both cases the probe returns -ENOMEM, which causes coresight_get_platform_data() to call coresight_release_platform_data() for cleanup. That function iterates up to nr_outconns (or nr_inconns) entries and dereferences each pointer unconditionally, hitting the NULL or garbage entry and panicking instead of failing gracefully.
Fix by moving the counter increments to after all allocations succeed, so the struct is always consistent on any error path.
--- drivers/hwtracing/coresight/coresight-platform.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/hwtracing/coresight/coresight-platform.c +6 -6
@@ -45,9 +45,8 @@ coresight_add_out_conn(struct device *dev, } } - pdata->nr_outconns++; pdata->out_conns = -devm_krealloc_array (dev, pdata->out_conns, pdata->nr_outconns, +devm_krealloc_array (dev, pdata->out_conns, pdata->nr_outconns +1 ,sizeof (*pdata->out_conns),GFP_KERNEL );if (!pdata->out_conns)return ERR_PTR (-ENOMEM );
@@ -63,7 +62,8 @@ coresight_add_out_conn(struct device *dev,* used right away. */ *conn = *new_conn; - pdata->out_conns[pdata->nr_outconns -1 ] = conn; + pdata->out_conns[pdata->nr_outconns] = conn; + pdata->nr_outconns++;return conn; }EXPORT_SYMBOL_GPL (coresight_add_out_conn);
@@ -86,13 +86,13 @@ int coresight_add_in_conn(struct coresight_connection *out_conn)return 0 ; } - pdata->nr_inconns++; pdata->in_conns = -devm_krealloc_array (dev, pdata->in_conns, pdata->nr_inconns, +devm_krealloc_array (dev, pdata->in_conns, pdata->nr_inconns +1 ,sizeof (*pdata->in_conns),GFP_KERNEL );if (!pdata->in_conns)return -ENOMEM ; - pdata->in_conns[pdata->nr_inconns -1 ] = out_conn; + pdata->in_conns[pdata->nr_inconns] = out_conn; + pdata->nr_inconns++;return 0 ; }EXPORT_SYMBOL_GPL (coresight_add_in_conn);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 488/1102 RDMA/bnxt_re: Proper rollback if the ioremap fails
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvin Xavier <[email protected]>
[ Upstream commit 87267803a8c824616eb147c5dad7030a5db6f878 ]
bnxt_qplib_alloc_dpi returns success even if ioremap fails. Add the proper rollback when the ioremap fails and return -ENOMEM status.
--- drivers/infiniband/hw/bnxt_re/qplib_res.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/infiniband/hw/bnxt_re/qplib_res.c +11 -0
@@ -737,9 +737,13 @@ int bnxt_qplib_alloc_dpi(struct bnxt_qplib_res *res,break ;case BNXT_QPLIB_DPI_TYPE_WC : dpi->dbr =ioremap_wc (umaddr,PAGE_SIZE ); +if (!dpi->dbr) + goto fail_ioremap;break ;default : dpi->dbr =ioremap (umaddr,PAGE_SIZE ); +if (!dpi->dbr) + goto fail_ioremap;break ; }
@@ -747,6 +751,13 @@ int bnxt_qplib_alloc_dpi(struct bnxt_qplib_res *res,mutex_unlock (&res->dpi_tbl_lock);return 0 ; +fail_ioremap: +/* Roll back the bit we just claimed. */ +set_bit (bit_num, dpit->tbl); + dpit->app_tbl[bit_num] =NULL ; +mutex_unlock (&res->dpi_tbl_lock); +return -ENOMEM ; + } int bnxt_qplib_dealloc_dpi(struct bnxt_qplib_res *res,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 489/1102 bpf: Guard __get_user acesss with access_ok for uprobe_multi data
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
[ Upstream commit 4d87a251d45b4a95eb4c0abcfab809c9f231258a ]
As reported by sashiko [1] we need to use access_ok to check the user space data bounds before we use __get-user to get it.
[1] https://lore.kernel.org/bpf/[email protected]/
--- kernel/trace/bpf_trace.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
kernel/trace/bpf_trace.c +11 -0
@@ -3308,6 +3308,7 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prunsigned long __user *uoffsets;u64 __user *ucookies;void __user *upath; +unsigned long size;u32 flags, cnt, i;struct path path;char *name;
@@ -3342,6 +3343,16 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr uref_ctr_offsets =u64_to_user_ptr (attr->link_create.uprobe_multi.ref_ctr_offsets); ucookies =u64_to_user_ptr (attr->link_create.uprobe_multi.cookies); +/* +* All uoffsets/uref_ctr_offsets/ucookies arrays have the same value +* size, we need to check their address range is safe for __get_user +* calls. +*/ + size =sizeof (*uoffsets) * cnt; +if (!access_ok (uoffsets, size) || !access_ok (uref_ctr_offsets, size) || + !access_ok (ucookies, size)) +return -EFAULT ; + name =strndup_user (upath,PATH_MAX );if (IS_ERR (name)) { err =PTR_ERR (name);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 490/1102 ipv4: fib: Dont dump dying fib_info in fib_leaf_notify().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 06b693d2eb6651a63ad85bad8673de3b7d4edd6d ]
syzbot reported use-after-free in nsim_fib4_prepare_event(). [0]
The problem is that the following functions call fib_info_hold() / refcount_inc() while dumping fib_info under RCU, which is unsafe.
* mlxsw_sp_router_fib4_event()
* rocker_router_fib_event()
* nsim_fib4_prepare_event()
refcount_inc_not_zero() must be used, but it would be too late there.
Let's guarantee the lifetime of fib_info in fib_leaf_notify().
Note that IPv6 does not need the corresponding change since fib6_table_dump() holds fib6_table.tb6_lock.
[0]:refcount_t: addition on 0; use-after-free.
WARNING: lib/refcount.c:25 at refcount_warn_saturate+0x9f/0x110 lib/refcount.c:25, CPU#0: kworker/u8:15/3420
Modules linked in:
CPU: 0 UID: 0 PID: 3420 Comm: kworker/u8:15 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026
Workqueue: netns cleanup_net
RIP: 0010:refcount_warn_saturate+0x9f/0x110 lib/refcount.c:25
Code: eb 66 85 db 74 3e 83 fb 01 75 4c e8 1b f1 22 fd 48 8d 3d 84 cb f1 0a 67 48 0f b9 3a eb 4a e8 08 f1 22 fd 48 8d 3d 81 cb f1 0a <67> 48 0f b9 3a eb 37 e8 f5 f0 22 fd 48 8d 3d 7e cb f1 0a 67 48 0f
RSP: 0018:ffffc9000f2c7270 EFLAGS: 00010293
RAX: ffffffff84a18858 RBX: 0000000000000002 RCX: ffff888032ff9ec0
RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff8f9353e0
RBP: 0000000000000000 R08: ffff888032ff9ec0 R09: 0000000000000005
R10: 0000000000000100 R11: 0000000000000004 R12: ffff8880570cc000
R13: dffffc0000000000 R14: ffff88802b40563c R15: ffff8880570cc000
FS: 0000000000000000(0000) GS:ffff888126173000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fb1f4d5d000 CR3: 000000006072a000 CR4: 00000000003526f0
Call Trace:
<TASK>
__refcount_add include/linux/refcount.h:-1 [inline]
__refcount_inc include/linux/refcount.h:366 [inline]
refcount_inc include/linux/refcount.h:383 [inline]
fib_info_hold include/net/ip_fib.h:629 [inline]
nsim_fib4_prepare_event drivers/net/netdevsim/fib.c:930 [inline]
nsim_fib_event_schedule_work drivers/net/netdevsim/fib.c:1000 [inline]
nsim_fib_event_nb+0x1055/0x1240 drivers/net/netdevsim/fib.c:1043
call_fib_notifier+0x45/0x80 net/core/fib_notifier.c:25
call_fib_entry_notifier net/ipv4/fib_trie.c:90 [inline]
fib_leaf_notify net/ipv4/fib_trie.c:2176 [inline]
fib_table_notify net/ipv4/fib_trie.c:2194 [inline]
fib_notify+0x36b/0x5e0 net/ipv4/fib_trie.c:2217
fib_net_dump net/core/fib_notifier.c:70 [inline]
register_fib_notifier+0x184/0x360 net/core/fib_notifier.c:108
nsim_fib_create+0x85d/0x9f0 drivers/net/netdevsim/fib.c:1596
nsim_dev_reload_create drivers/net/netdevsim/dev.c:1604 [inline]
nsim_dev_reload_up+0x374/0x7c0 drivers/net/netdevsim/dev.c:1058
devlink_reload+0x501/0x8d0 net/devlink/dev.c:475
devlink_pernet_pre_exit+0x1ff/0x420 net/devlink/core.c:558
ops_pre_exit_list net/core/net_namespace.c:161 [inline]
ops_undo_list+0x187/0x940 net/core/net_namespace.c:234
cleanup_net+0x56e/0x800 net/core/net_namespace.c:702
process_one_work kernel/workqueue.c:3314 [inline]
process_scheduled_works+0xb5d/0x1860 kernel/workqueue.c:3397
worker_thread+0xa53/0xfc0 kernel/workqueue.c:3478
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>--- include/net/ip_fib.h | 5 +++++ net/ipv4/fib_trie.c | 4 ++++ 2 files changed, 9 insertions(+)
include/net/ip_fib.h +5 -0
@@ -612,6 +612,11 @@ static inline void fib_info_hold(struct fib_info *fi)refcount_inc (&fi->fib_clntref); } +static inline bool fib_info_hold_safe (struct fib_info *fi) +{ +return refcount_inc_not_zero (&fi->fib_clntref); +} +static inline void fib_info_put (struct fib_info *fi) {if (refcount_dec_and_test (&fi->fib_clntref))
net/ipv4/fib_trie.c +4 -0
@@ -2178,10 +2178,14 @@ static int fib_leaf_notify(struct key_vector *l, struct fib_table *tb,if (fa->fa_slen == last_slen)continue ; +if (!fib_info_hold_safe (fa->fa_info)) +continue ; + last_slen = fa->fa_slen; err =call_fib_entry_notifier (nb,FIB_EVENT_ENTRY_REPLACE , l->key,KEYLENGTH - fa->fa_slen, fa, extack); +fib_info_put (fa->fa_info);if (err)return err; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 491/1102 ASoC: topology: Check PCM and DAI name strings before use
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cássio Gabriel <[email protected]>
[ Upstream commit b7e44d1986d6671342c19b82192189ca5db5dab7 ]
Topology objects store several PCM and DAI names in fixed-size UAPI arrays. Other topology parser paths validate these fields with bounded strnlen() checks before using them as C strings, but the PCM and DAI paths still pass some fixed-size arrays directly to strlen(), devm_kstrdup(), DAI lookup, and diagnostic prints.
A malformed topology blob with a non-NUL-terminated PCM, DAI, or stream capability name can therefore make the parser read past the end of the fixed-size field.
Reject unterminated PCM and DAI name fields before consuming them as C strings.
--- sound/soc/soc-topology.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-)
sound/soc/soc-topology.c +34 -3
@@ -1348,9 +1348,24 @@ static int soc_tplg_dapm_complete(struct soc_tplg *tplg)return ret; } +static int soc_tplg_check_name (const char *name) +{ +if (strnlen (name,SNDRV_CTL_ELEM_ID_NAME_MAXLEN ) == +SNDRV_CTL_ELEM_ID_NAME_MAXLEN ) +return -EINVAL ; + +return 0 ; +} +static int set_stream_info (struct soc_tplg *tplg,struct snd_soc_pcm_stream *stream,struct snd_soc_tplg_stream_caps *caps) { +int ret; + + ret =soc_tplg_check_name (caps->name); +if (ret) +return ret; + stream->stream_name =devm_kstrdup (tplg->dev, caps->name,GFP_KERNEL );if (!stream->stream_name)return -ENOMEM ;
@@ -1403,7 +1418,11 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,if (dai_drv ==NULL )return -ENOMEM ; -if (strlen (pcm->dai_name)) { + ret =soc_tplg_check_name (pcm->dai_name); +if (ret) + goto err; + +if (pcm->dai_name[0 ]) { dai_drv->name =devm_kstrdup (tplg->dev, pcm->dai_name,GFP_KERNEL );if (!dai_drv->name) { ret = -ENOMEM ;
@@ -1509,7 +1528,11 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,if (tplg->ops) link->dobj.unload = tplg->ops->link_unload; -if (strlen (pcm->pcm_name)) { + ret =soc_tplg_check_name (pcm->pcm_name); +if (ret) + goto err; + +if (pcm->pcm_name[0 ]) { link->name =devm_kstrdup (tplg->dev, pcm->pcm_name,GFP_KERNEL ); link->stream_name =devm_kstrdup (tplg->dev, pcm->pcm_name,GFP_KERNEL );if (!link->name || !link->stream_name) {
@@ -1519,7 +1542,11 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg, } link->id =le32_to_cpu (pcm->pcm_id); -if (strlen (pcm->dai_name)) { + ret =soc_tplg_check_name (pcm->dai_name); +if (ret) + goto err; + +if (pcm->dai_name[0 ]) { link->cpus->dai_name =devm_kstrdup (tplg->dev, pcm->dai_name,GFP_KERNEL );if (!link->cpus->dai_name) { ret = -ENOMEM ;
@@ -1871,6 +1898,10 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,memset (&dai_component,0 ,sizeof (dai_component)); + ret =soc_tplg_check_name (d->dai_name); +if (ret) +return ret; + dai_component.dai_name = d->dai_name; dai =snd_soc_find_dai (&dai_component);if (!dai) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 492/1102 ASoC: meson: aiu: Validate written enum values
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: HyeongJun An <[email protected]>
[ Upstream commit d65adf85477247be04ac86886f8edfaa047b5d4a ]
The AIU HDMI and internal codec mux put callbacks use the written enum value with snd_soc_enum_item_to_val() before checking whether the value is valid for the enumeration.
Reject out-of-range values before converting the enum item, matching the validation already done by the G12A HDMI and internal codec mux controls.
--- sound/soc/meson/aiu-acodec-ctrl.c | 3 +++ sound/soc/meson/aiu-codec-ctrl.c | 3 +++ 2 files changed, 6 insertions(+)
sound/soc/meson/aiu-acodec-ctrl.c +3 -0
@@ -38,6 +38,9 @@ static int aiu_acodec_ctrl_mux_put_enum(struct snd_kcontrol *kcontrol,struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;unsigned int mux, changed; +if (ucontrol->value.enumerated.item[0 ] >= e->items) +return -EINVAL ; + mux =snd_soc_enum_item_to_val (e, ucontrol->value.enumerated.item[0 ]); changed = snd_soc_component_test_bits(component, e->reg, CTRL_DIN_LRCLK_SRC,
sound/soc/meson/aiu-codec-ctrl.c +3 -0
@@ -30,6 +30,9 @@ static int aiu_codec_ctrl_mux_put_enum(struct snd_kcontrol *kcontrol,struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;unsigned int mux, changed; +if (ucontrol->value.enumerated.item[0 ] >= e->items) +return -EINVAL ; + mux =snd_soc_enum_item_to_val (e, ucontrol->value.enumerated.item[0 ]); changed = snd_soc_component_test_bits(component, e->reg, CTRL_DATA_SEL,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 493/1102 ksmbd: use memcmp() to compare ClientGUIDs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit e8bb506e6ef749ac0336f3e579d8d02396b7d832 ]
ClientGUID is a fixed-size binary value and can contain embedded NUL bytes. strncmp() stops comparing at the first NUL byte, so different ClientGUID values can incorrectly be treated as equal.
Use memcmp() in SMB3 multichannel session binding and FSCTL_VALIDATE_NEGOTIATE_INFO to compare all SMB2_CLIENT_GUID_SIZE bytes.
--- fs/smb/server/smb2pdu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/smb/server/smb2pdu.c +2 -2
@@ -1761,7 +1761,7 @@ int smb2_sess_setup(struct ksmbd_work *work) goto out_err; } -if (strncmp (conn->ClientGUID, sess->ClientGUID, +if (memcmp (conn->ClientGUID, sess->ClientGUID,SMB2_CLIENT_GUID_SIZE )) { rc = -ENOENT ; goto out_err;
@@ -8132,7 +8132,7 @@ static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn, goto err_out; } -if (strncmp (neg_req->Guid, conn->ClientGUID,SMB2_CLIENT_GUID_SIZE )) { +if (memcmp (neg_req->Guid, conn->ClientGUID,SMB2_CLIENT_GUID_SIZE )) { ret = -EINVAL ; goto err_out; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 494/1102 l2tp: fix tunnel and session refcount leak on seq_file release
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 9006c116dd111d457bf5d074990210f70a4ad2c8 ]
In pppol2tp_proc_open() and l2tp_dfs_seq_open(), iteration state (pd->tunnel and pd->session) is kept in seq_file private data to allow iteration across multiple read() system calls.
However, if userspace closes /proc/net/pppol2tp or /sys/kernel/debug/l2tp/tunnels before reading to end-of-file (EOF), any tunnel or session reference stored in pd->tunnel / pd->session is left un-dropped when seq_file private data is freed.
Fix this by dropping any remaining pd->tunnel and pd->session references in pppol2tp_proc_release() and l2tp_dfs_seq_release() when closing the file.
--- net/l2tp/l2tp_debugfs.c | 4 +++ net/l2tp/l2tp_ppp.c | 56 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-)
net/l2tp/l2tp_debugfs.c +4 -0
@@ -306,6 +306,10 @@ static int l2tp_dfs_seq_release(struct inode *inode, struct file *file) seq = file->private_data; pd = seq->private; +if (pd->session) +l2tp_session_put (pd->session); +if (pd->tunnel) +l2tp_tunnel_put (pd->tunnel);if (pd->net)put_net_track (pd->net, &pd->ns_tracker);kfree (pd);
net/l2tp/l2tp_ppp.c +53 -3
77 lines not on this page · raw message
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 495/1102 af_unix: Unlink scc_entry in unix_del_edge().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 594d905195024b228c962627ae5ae7c17bd582a4 ]
Kyle Zeng reported that GC could free a dead SCC partially.
The scenario is as follows:
1) Create two SCCs:
X -. A <-> B
^--'2) Run the following concurrently:
2-1) send() sk-B to sk-B from sk-X
2-2) close() both A and B
At 2-1), there is a small window where unix_add_edges() publishes a new edge (B <-> B) to GC but its skb is not queued by skb_queue_tail().
If 2-2) completes before skb_queue_tail() and GC is triggered, it judges A <-> B as dead, but B is not freed because GC cannot collect the not-yet-queued skb holding the B <-> B edge.
X -. A <-> B -. This edge is visible
^--' ^..' but skb is not
This itself is not a problem since the next GC run will judge B as dead as well and free it finally.
X -. A <.> B -.
^--' ^--'However, X's SCC forces the next GC to call unix_walk_scc_fast(), and it iterates over A through B's scc_entry.
Let's unlink scc_entry before freeing the vertex in unix_del_edge().
--- net/unix/garbage.c | 1 + 1 file changed, 1 insertion(+)
net/unix/garbage.c +1 -0
@@ -173,6 +173,7 @@ static void unix_del_edge(struct scm_fp_list *fpl, struct unix_edge *edge)if (!vertex->out_degree) { edge->predecessor->vertex =NULL ;list_move_tail (&vertex->entry, &fpl->vertices); +list_del (&vertex->scc_entry); } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 496/1102 Bluetooth: btrtl: Add the support for RTL8761CUV
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Chou <[email protected]>
[ Upstream commit 4a23ce935f74d19df48d1906497fad1cef391392 ]
Add support for RTL8761CUV BT controller on the USB interface. Do not apply IC_MATCH_FL_HCIVER when hci_ver is 0 in the ic_id_table.
The device info from /sys/kernel/debug/usb/devices as below.
T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 13 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=c761 Rev= 2.00 S: Manufacturer=Realtek S: Product=Bluetooth Controller S: SerialNumber=10000 C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
--- drivers/bluetooth/btrtl.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
drivers/bluetooth/btrtl.c +15 -1
@@ -72,6 +72,7 @@ enum btrtl_chip_id {CHIP_ID_8851B =36 ,CHIP_ID_8922A =44 ,CHIP_ID_8852BT =47 , + CHIP_ID_8761C = 51, }; struct id_table {
@@ -230,6 +231,14 @@ static const struct id_table ic_id_table[] = { .cfg_name = "rtl_bt/rtl8761bu_config", .hw_info = "rtl8761bu" }, +/* 8761CU */ + { IC_INFO(RTL_ROM_LMP_8761A, 0x0e, 0, HCI_USB), + .config_needed = false, + .has_rom_version = true, + .fw_name = "rtl_bt/rtl8761cu_fw", + .cfg_name = "rtl_bt/rtl8761cu_config", + .hw_info = "rtl8761cu" }, + /* 8822C with UART interface */ { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0x8, HCI_UART), .config_needed = true,
@@ -344,7 +353,8 @@ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev, (ic_id_table[i].hci_rev != hci_rev))continue ;if ((ic_id_table[i].match_flags &IC_MATCH_FL_HCIVER ) && - (ic_id_table[i].hci_ver != hci_ver)) + (ic_id_table[i].hci_ver != hci_ver) && + (ic_id_table[i].hci_ver !=0 ))continue ;if ((ic_id_table[i].match_flags &IC_MATCH_FL_HCIBUS ) && (ic_id_table[i].hci_bus != hci_bus))
@@ -662,6 +672,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, { RTL_ROM_LMP_8851B, 36 }, /* 8851B */ { RTL_ROM_LMP_8922A, 44 }, /* 8922A */ { RTL_ROM_LMP_8852A, 47 }, /* 8852BT */ + { RTL_ROM_LMP_8761A, 51 }, /* 8761C */ };if (btrtl_dev->fw_len <=8 )
@@ -1306,6 +1317,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)case CHIP_ID_8851B :case CHIP_ID_8922A :case CHIP_ID_8852BT : +case CHIP_ID_8761C :set_bit (HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED , &hdev->quirks);/* RTL8852C needs to transmit mSBC data continuously without
@@ -1525,6 +1537,8 @@ MODULE_FIRMWARE("rtl_bt/rtl8761b_fw.bin");MODULE_FIRMWARE ("rtl_bt/rtl8761b_config.bin" );MODULE_FIRMWARE ("rtl_bt/rtl8761bu_fw.bin" );MODULE_FIRMWARE ("rtl_bt/rtl8761bu_config.bin" ); +MODULE_FIRMWARE ("rtl_bt/rtl8761cu_fw.bin" ); +MODULE_FIRMWARE ("rtl_bt/rtl8761cu_config.bin" );MODULE_FIRMWARE ("rtl_bt/rtl8821a_fw.bin" );MODULE_FIRMWARE ("rtl_bt/rtl8821a_config.bin" );MODULE_FIRMWARE ("rtl_bt/rtl8821c_fw.bin" );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 497/1102 mm/damon/core: avoid infinite kdamond_merge_regions() internal loop
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <[email protected]>
commit 123e4619ab6c8ab1c4cb1d7a58311a2af13929cd upstream.
Patch series "mm/damon: unurgent fixes for infinite loop, NULL de-ref and races", v1.1.
Sashiko found a few issues in DAMON that could cause infinite loop, NULL dereference and monitoring results degradation. The first two sounds scary but the infinite loop happens only under unreasonable user setup. The NULL dereference is only in a unit test. Monitoring results degradation is trivial since it is only best-effort, and those happens from only unlikely races. Still those are bugs that better to fix if possible. Fix those.
This patch (of 6):
Due to online parameter update like events, the number of DAMON regions could be higher than the user-set upper limit. kdamond_merge_regions() repeats merge regions until the number meets the limit, while doubling the merge threshold up to the theoretical maximum threshold. It is tried only up to the theoretical maximum threshold because even the aggressive merging can fail from reducing the number of regions under the user-defined upper limit. For example, there could be many user-defined non-contiguous regions that cannot be merged.
The threshold based loop break condition is evaluated by comparing the threshold for the next merging try against the theoretical maximum threshold. If max_thres is larger than UINT_MAX / 2, doubling the threshold could make it overflow, and bypass the loop break condition. In the case, if the number of regions cannot be reduced under the upper limit like explained above, the loop will run infinitely.
Prevent the case by doing the break condition check before doubling the threshold. Also, prevent the threshold exceeding the maximum threshold, as it could overflow and apply the wrong merge threshold.
This issue is unlikely to occur in real world, since having the max_thres higher than UINT_MAX / 2 require unrealistically large aggregation intervals compared to the sampling interval. Also, it requires an unrealistically large number of uncontiguous regions setup. Nonetheless, the consequence is bad and the fix is simple.
The issue was discovered [1] by Sashiko.
--- mm/damon/core.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
mm/damon/core.c +9 -4
@@ -1834,7 +1834,7 @@ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold, max_thres = c->attrs.aggr_interval / (c->attrs.sample_interval ? c->attrs.sample_interval :1 ); - do { +while (true) { nr_regions =0 ;damon_for_each_target (t, c) { damon_merge_regions_of(t, threshold, sz_limit,
@@ -1842,9 +1842,14 @@ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold, nr_regions +=damon_nr_regions (t); } count_age = false; - threshold =max (1 , threshold *2 ); - }while (nr_regions > c->attrs.max_nr_regions && - threshold /2 < max_thres); +if (nr_regions <= c->attrs.max_nr_regions || + max_thres <= threshold) +break ; +if (threshold < max_thres /2 ) + threshold =max (1 , threshold *2 ); +else + threshold = max_thres; + } }/*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 498/1102 ARM: 9484/1: enable interrupts when unhandled user faults are triggered
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xie Yuanbin <[email protected]>
[ Upstream commit e79ca91165d4fd18549c536abdb86101e889052f ]
PREEMPT_RT requires interrupts to be enabled when sending signals.
When do_DataAbort()/do_PrefetchAbort() triggers unhandled user faults, that is inf->fn() return a non-zero value, and the interrupts are not enabled within the hook function, force_sig_fault() will be called with interrupts disabled.
This can be triggered by user programs executing the bkpt instruction, with kernel config CONFIG_PERF_EVENTS=n.
Enable interrupts in do_DataAbort()/do_PrefetchAbort() when unhandled user faults are triggered to fix the issue.
--- arch/arm/mm/fault.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm/mm/fault.c +6 -0
@@ -650,6 +650,9 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)if (!inf->fn (addr, fsr & ~FSR_LNX_PF , regs))return ; +if (likely (user_mode (regs))) +local_irq_enable (); +pr_alert ("8<--- cut here ---\n" );pr_alert ("Unhandled fault: %s (0x%03x) at 0x%08lx\n" , inf->name, fsr, addr);
@@ -688,6 +691,9 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)if (!inf->fn (addr, ifsr |FSR_LNX_PF , regs))return ; +if (likely (user_mode (regs))) +local_irq_enable (); +pr_alert ("8<--- cut here ---\n" );pr_alert ("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n" , inf->name, ifsr, addr);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 499/1102 ARM: ensure interrupts are enabled in __do_user_fault()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) <[email protected]>
[ Upstream commit 59e4f3b45b96a24fc9b7a89e5f8a2168b30f95af ]
__do_user_fault() may be called from fault handling paths where the interrupts are enabled or disabled. E.g. do_page_fault() calls this with interrupts enabled, whereas do_sect_fault()->do_bad_area() will call this with interrupts disabled. Since this is a userspace fault, we know that interrupts were enabled in the parent context, so call local_irq_enable() here to give a consistent interrupt state.
This is necessary for force_sig_info() when PREEMPT_RT is enabled.
--- arch/arm/mm/fault.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/mm/fault.c +5 -1
@@ -191,7 +191,8 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,/* * Something tried to access memory that isn't in our memory map.. -* User mode accesses just cause a SIGSEGV +* User mode accesses just cause a SIGSEGV. Ensure interrupts are enabled +* for preempt RT. */ static void __do_user_fault(unsigned long addr, unsigned int fsr, unsigned int sig,
@@ -199,6 +200,8 @@ __do_user_fault(unsigned long addr, unsigned int fsr, unsigned int sig, {struct task_struct *tsk = current; +local_irq_enable (); +#ifdef CONFIG_DEBUG_USER if (((user_debug &UDBG_SEGV ) && (sig ==SIGSEGV )) || ((user_debug &UDBG_BUS ) && (sig ==SIGBUS ))) {
@@ -273,6 +276,7 @@ do_kernel_address_page_fault(struct mm_struct *mm, unsigned long addr,* should not be faulting in kernel space, which includes the * vector/khelper page. Handle the branch predictor hardening * while interrupts are still disabled, then send a SIGSEGV. +* Note that __do_user_fault() will enable interrupts. */ harden_branch_predictor ();__do_user_fault (addr, fsr,SIGSEGV ,SEGV_MAPERR , regs);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 500/1102 RAS/AMD/ATL, EDAC/amd64: Only load ATL when needed
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <[email protected]>
[ Upstream commit 4c3da04827dc01dc1cfc3d03654b7de656c42d80 ]
The AMD Address Translation Library (ATL) will attempt to load on all AMD Zen/SMCA systems.
However, only systems with DRAM ECC enabled will use the library. Other systems will fail to load the library and produce an unnecessary message to the user. More importantly, that thing is dead code loaded and unused.
Remove the ATL module dependency table to prevent autoloading. Request ATL to load from EDAC once all system checks are complete.
[ bp: Massage commit message. ]
--- drivers/edac/amd64_edac.c | 2 ++ drivers/ras/amd/atl/core.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/edac/amd64_edac.c +2 -0
@@ -4184,6 +4184,8 @@ static int __init amd64_edac_init(void) goto err_pci; } +request_module_nowait ("amd_atl" ); +/* register stuff with EDAC MCE */ if (boot_cpu_data.x86 >=0x17 ) {amd_register_ecc_decoder (decode_umc_error);
drivers/ras/amd/atl/core.c +0 -1
@@ -190,7 +190,6 @@ static const struct x86_cpu_id amd_atl_cpuids[] = { X86_MATCH_FEATURE(X86_FEATURE_ZEN, NULL), { } }; -MODULE_DEVICE_TABLE (x86cpu, amd_atl_cpuids);static int __init amd_atl_init (void ) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 501/1102 EDAC/igen6: Fix interleave boundary condition
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <[email protected]>
[ Upstream commit f4008169bd320eedb9ddf2b39eeb21370ddac278 ]
The address translation logic splits the memory space into interleaved and non-interleaved regions using a boundary at 2 * s_size.
The current check uses '>' and incorrectly classifies the boundary address (2 * s_size) as part of the interleaved region. This leads to incorrect channel/sub-channel selection at the region boundary.
Fix the classification by using '>=' so that the boundary address is handled in the non-interleaved region, matching the hardware layout.
--- drivers/edac/igen6_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/edac/igen6_edac.c +1 -1
@@ -674,7 +674,7 @@ static void decode_addr(u64 addr, u32 hash, u64 s_size, int l_map, {int intlv_bit =CHANNEL_HASH_LSB_MASK_BIT (hash) +6 ; -if (addr >2 * s_size) { +if (addr >=2 * s_size) { *sub_addr = addr - s_size; *idx = l_map;return ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 502/1102 EDAC/igen6: Fix channel selection hash
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <[email protected]>
[ Upstream commit 540b79536f3a89a66c5b6c490110298d43025618 ]
In channel selection hash mode, the hardware decoding logic always includes the channel interleave bit in XOR operations. However, the hash mask may or may not include this channel interleave bit. When the mask does include this bit, the current igen6_edac code performs XOR on the interleave bit twice, effectively ignoring it - which is incorrect.
Fix this issue by ensuring the hash mask always includes the interleave bit, so XOR is performed on the interleave bit exactly once.
--- drivers/edac/igen6_edac.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/edac/igen6_edac.c +11 -3
@@ -648,14 +648,22 @@ static enum mem_type get_memory_type(u32 mad_inter)static int decode_chan_idx (u64 addr,u64 mask,int intlv_bit) { -u64 hash_addr = addr & mask, hash =0 ; -u64 intlv = (addr >> intlv_bit) &1 ; +u64 hash_addr, hash =0 ;int i; +/* +* In hash mode, the @intlv_bit is the lowest selected bit of @addr +* to be XORed. While @mask may or may not include this @intlv_bit, +* we enforce that @mask includes @intlv_bit to ensure @intlv_bit is +* XORed exactly once. +*/ + mask |=1 << intlv_bit; + hash_addr = addr & mask; +for (i =6 ; i <20 ; i++) hash ^= (hash_addr >> i) &1 ; -return (int )hash ^ intlv; +return (int )hash; }static u64 decode_channel_addr (u64 addr,int intlv_bit)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 503/1102 EDAC/igen6: Fix channel address decode for non-hash mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <[email protected]>
[ Upstream commit 7b348d0d401d478f1923ba20a34a61681d1f7971 ]
In non-hash mode, decode_channel_addr() and channel index extraction used a hardcoded interleave bit position 6 instead of the actual intlv_bit parameter, causing incorrect channel address decoding.
Fix this by using intlv_bit consistently in both hash and non-hash modes.
--- drivers/edac/igen6_edac.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/edac/igen6_edac.c +5 -6
@@ -688,13 +688,12 @@ static void decode_addr(u64 addr, u32 hash, u64 s_size, int l_map,return ; } -if (CHANNEL_HASH_MODE (hash)) { - *sub_addr =decode_channel_addr (addr, intlv_bit); + *sub_addr =decode_channel_addr (addr, intlv_bit); + +if (CHANNEL_HASH_MODE (hash)) *idx =decode_chan_idx (addr,CHANNEL_HASH_MASK (hash), intlv_bit); - }else { - *sub_addr =decode_channel_addr (addr,6 ); - *idx =GET_BITFIELD (addr,6 ,6 ); - } +else + *idx =GET_BITFIELD (addr, intlv_bit, intlv_bit); }static int igen6_decode (struct decoded_addr *res)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 504/1102 EDAC/device_sysfs: Use kstrtouint() for poll_msec to prevent truncation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jad Keskes <[email protected]>
[ Upstream commit 66cc9dec919dd63d8e4b3d386f7aed3ae684e645 ]
The poll_msec sysfs store file uses simple_strtoul() which accepts an unsigned long, but the target field (poll_msec) is unsigned int. On 64-bit systems, a value > UINT_MAX is silently truncated when stored.
Fix the mismatch by using kstrtouint() instead. This rejects values larger than UINT_MAX at parse time, making truncation impossible. Also add a check for value < 1 to reject the 0-delay case, which would cause the poll work to spin without delay and consume 100% CPU.
--- drivers/edac/edac_device_sysfs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/edac/edac_device_sysfs.c +9 -2
@@ -90,14 +90,21 @@ static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info *ctl_info, const char *data, size_t count) { -unsigned long value; +unsigned int value; +int ret;/* get the value and enforce that it is non-zero, must be at least * one millisecond for the delay period, between scans * Then cancel last outstanding delay for the work request * and set a new one. */ - value =simple_strtoul (data,NULL ,0 ); + ret =kstrtouint (data,0 , &value); +if (ret <0 ) +return ret; + +if (value <1 ) +return -EINVAL ; +edac_device_reset_delay_period (ctl_info, value);return count;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 505/1102 drm/virtio: Fix a NULL vs ERR_PTR() bug in virtio_gpu_user_framebuffer_create()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 94579f24e2b526a04eb41050af0ba018c6f528e7 ]
Smatch complains that returning a NULL here will lead to a NULL pointer dereference in drm_mode_addfb2(). Return an error pointer instead.
--- drivers/gpu/drm/virtio/virtgpu_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/virtio/virtgpu_display.c +1 -1
@@ -318,7 +318,7 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev,if (ret) {kfree (virtio_gpu_fb);drm_gem_object_put (obj); -return NULL ; +return ERR_PTR (ret); }return &virtio_gpu_fb->base;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 506/1102 accel/qaic: Address potential out-of-bounds read in resp_worker()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youssef Samir <[email protected]>
[ Upstream commit ab243f74ab4084ca5c8dec608cb5b0deb27db067 ]
Although 'commit 2feec5ae5df7 ("accel/qaic: Handle DBC deactivation if the owner went away")' fixes the scenario it was intended for by walking the message and only decoding QAIC_TRANS_DEACTIVATE_FROM_DEV, if present, it skipped over the bounds checking code that is included in decode_message(). This could lead to issues such as reading past the slab allocation's end, infinite loops or kernel panics. For those issues to happen, a malformed wire message is needed to be sent from the device.
Instead of duplicating the bounds checking code already present in decode_message(), use the function inside resp_worker().
--- drivers/accel/qaic/qaic_control.c | 46 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 22 deletions(-)
drivers/accel/qaic/qaic_control.c +24 -22
@@ -958,11 +958,13 @@ static int decode_status(struct qaic_device *qdev, void *trans, struct manage_msstatic int decode_message (struct qaic_device *qdev,struct manage_msg *user_msg,struct wire_msg *msg,struct ioctl_resources *resources, -struct qaic_user *usr) +struct qaic_user *usr,bool orphaned_deactivate) { +u32 msg_hdr_count =le32_to_cpu (msg->hdr.count);u32 msg_hdr_len =le32_to_cpu (msg->hdr.len);struct wire_trans_hdr *trans_hdr;u32 msg_len =0 ; +int trans_type;int ret;int i;
@@ -970,10 +972,12 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg, msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)return -EINVAL ; - user_msg->len =0 ; - user_msg->count =le32_to_cpu (msg->hdr.count); +if (user_msg) { + user_msg->len =0 ; + user_msg->count = msg_hdr_count; + } -for (i =0 ; i < user_msg->count; ++i) { +for (i =0 ; i < msg_hdr_count; ++i) {u32 hdr_len;if (msg_len > msg_hdr_len -sizeof (*trans_hdr))
@@ -985,7 +989,20 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg, size_add(msg_len, hdr_len) > msg_hdr_len)return -EINVAL ; -switch (le32_to_cpu (trans_hdr->type)) { + trans_type =le32_to_cpu (trans_hdr->type); +/* +* orphaned_deactivate is the case where a deactivate response +* is received from the device after the user owning the DBC, +* and the message requesting deactivation, has gone away. +* In this case, only process QAIC_TRANS_DEACTIVATE_FROM_DEV +* transaction and skip the others. +*/ +if (orphaned_deactivate && trans_type !=QAIC_TRANS_DEACTIVATE_FROM_DEV ) { + msg_len += hdr_len; +continue ; + } + +switch (trans_type) {case QAIC_TRANS_PASSTHROUGH_FROM_DEV : ret =decode_passthrough (qdev, trans_hdr, user_msg, &msg_len);break ;
@@ -1277,7 +1294,7 @@ static int qaic_manage(struct qaic_device *qdev, struct qaic_user *usr, struct m goto dma_cont_failed; } - ret =decode_message (qdev, user_msg, rsp, &resources, usr); + ret =decode_message (qdev, user_msg, rsp, &resources, usr, false); dma_cont_failed:free_dbc_buf (qdev, &resources);
@@ -1442,22 +1459,7 @@ static void resp_worker(struct work_struct *work)* response to the QAIC_TRANS_TERMINATE_TO_DEV transaction, * otherwise, the user can issue an soc_reset to the device. */ -u32 msg_count =le32_to_cpu (msg->hdr.count); -u32 msg_len =le32_to_cpu (msg->hdr.len); -u32 len =0 ; -int j; - -for (j =0 ; j < msg_count && len < msg_len; ++j) { -struct wire_trans_hdr *trans_hdr; - - trans_hdr = (struct wire_trans_hdr *)(msg->data + len); -if (le32_to_cpu (trans_hdr->type) ==QAIC_TRANS_DEACTIVATE_FROM_DEV ) { -if (decode_deactivate (qdev, trans_hdr, &len,NULL )) - len +=le32_to_cpu (trans_hdr->len); - }else { - len +=le32_to_cpu (trans_hdr->len); - } - } +decode_message (qdev,NULL , msg,NULL ,NULL , true);/* request must have timed out, drop packet */ kfree (msg); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 507/1102 nvme-rdma: fix -EIO cleanup order in queue_rq
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <[email protected]>
[ Upstream commit d61828199c6cb4b76d48403c77023cd4bb9d09fc ]
On -EIO, the RDMA queue_rq path reports a host path error and then still cleans up the command and unmaps the SQE DMA. The path error helper completes the request, so that is double cleanup and DMA unmap after the request is already complete.
Unmap the SQE first, then report the host path error. Skip the outer command cleanup on that path.
--- drivers/nvme/host/rdma.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/nvme/host/rdma.c +10 -8
@@ -2002,7 +2002,7 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,struct ib_device *dev;bool queue_ready =test_bit (NVME_RDMA_Q_LIVE , &queue->flags);blk_status_t ret; -int err; +int err =0 ;WARN_ON_ONCE (rq->tag <0 );
@@ -2058,16 +2058,18 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, err_unmap:nvme_rdma_unmap_data (queue, rq); err: -if (err == -EIO ) - ret =nvme_host_path_error (rq); -else if (err == -ENOMEM || err == -EAGAIN ) - ret =BLK_STS_RESOURCE ; -else - ret =BLK_STS_IOERR ; -nvme_cleanup_cmd (rq); +if (err != -EIO ) { +nvme_cleanup_cmd (rq); +if (err == -ENOMEM || err == -EAGAIN ) + ret =BLK_STS_RESOURCE ; +else + ret =BLK_STS_IOERR ; + } unmap_qe:ib_dma_unmap_single (dev, req->sqe.dma,sizeof (struct nvme_command ),DMA_TO_DEVICE ); +if (err == -EIO ) +return nvme_host_path_error (rq);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 508/1102 nvmet-rdma: fix queue leak when connect backlog is exceeded
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <[email protected]>
[ Upstream commit fb1ed67788e21832b614c23767a088c08cfdd2f2 ]
When pending disconnecting queues exceed the backlog limit, the connect path only drops the device reference and leaks the newly allocated queue and its IB resources.
--- drivers/nvme/target/rdma.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/nvme/target/rdma.c +7 -8
@@ -1626,19 +1626,13 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,mutex_unlock (&nvmet_rdma_queue_mutex);if (pending >NVMET_RDMA_BACKLOG ) { ret =NVME_SC_CONNECT_CTRL_BUSY ; - goto put_device; + goto free_queue; } } ret =nvmet_rdma_cm_accept (cm_id, queue, &event->param.conn); -if (ret) { -/* -* Don't destroy the cm_id in free path, as we implicitly -* destroy the cm_id here with non-zero ret code. -*/ - queue->cm_id =NULL ; +if (ret) goto free_queue; - }mutex_lock (&nvmet_rdma_queue_mutex);list_add_tail (&queue->queue_list, &nvmet_rdma_queue_list);
@@ -1647,6 +1641,11 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,return 0 ; free_queue: +/* +* Don't destroy the cm_id in free path, as we implicitly +* destroy the cm_id here with non-zero ret code. +*/ + queue->cm_id =NULL ;nvmet_rdma_free_queue (queue); put_device:kref_put (&ndev->ref, nvmet_rdma_free_dev);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 509/1102 sched_ext: Fix nonexistent field in sched-ext.rst example
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liang Luo <[email protected]>
[ Upstream commit 4fb8d6379d2c7ceecb2b3e111954d29089d59492 ]
The ops.exit() example in sched-ext.rst reads ei->type, but struct scx_exit_info has never had a type field - the exit reason is exposed as ei->kind since the struct was introduced. A scheduler written following the example fails to compile with
error: no member named 'type' in 'struct scx_exit_info'
Use ei->kind.
--- Documentation/scheduler/sched-ext.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/scheduler/sched-ext.rst +1 -1
@@ -180,7 +180,7 @@ optional. The following modified excerpt is from void BPF_STRUCT_OPS(simple_exit, struct scx_exit_info *ei) { - exit_type = ei->type; + exit_type = ei->kind; } SEC(".struct_ops")
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 510/1102 selftests/cgroup: Fix cg_run_in_subcgroups ignoring arg parameter
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hongfu Li <[email protected]>
[ Upstream commit a8c6daab4b0e276508b7ffdd66c60fd3020a9178 ]
cg_run_in_subcgroups() discards its arg and always passes NULL to cg_run(), turning the (void *)100 from test_kmem_dead_cgroups() into NULL so no allocation occurs.
This makes test_kmem_dead_cgroups() falsely pass without exercising the "dying cgroup with charged slab" scenario it intends to test.
Pass the arg through to cg_run() to fix this.
--- tools/testing/selftests/cgroup/test_kmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/cgroup/test_kmem.c +1 -1
@@ -144,7 +144,7 @@ static int cg_run_in_subcgroups(const char *parent,return -1 ; } -if (cg_run (child, fn,NULL )) { +if (cg_run (child, fn, arg)) {cg_destroy (child);free (child);return -1 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 511/1102 bpf: Fix REG INVARIANTS VIOLATION on speculative pointer arithmetic
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 150aeba624e8b7cac51c39440d7e8e1fd11de9a0 ]
Take the following unprivileged program as an example:
r0 = bpf_map_lookup_elem(...) /* PTR_TO_MAP_VALUE, offset 0 */ ... 14: r0 += r1 /* r1 is a bounded scalar */ 15: r9 = r0
Loading it triggers a verifier warning from reg_bounds_sanity_check():
verifier bug: REG INVARIANTS VIOLATION (alu): const subreg tnum out
of sync with range bounds r64={.base=0x0, .size=0x0}
r32={.base=0x0, .size=0xffffffff} var_off=(0x0, 0x0)What happens:
1. Processing insn 14 (r0 += r1) in adjust_ptr_min_max_vals(), the new offset is computed into dst_reg's var_off and 32/64-bit ranges.
2. Because pointer registers do not track 32-bit subregister bounds, __mark_reg32_unbounded() first sets r32 to the full range; r32 is re-derived from the offset at the end of the function by reg_bounds_sync().
3. On the unprivileged path, sanitize_ptr_alu() is called and, via sanitize_speculative_path() -> push_stack(), snapshots the current register state and schedules the next instruction (insn 15) to be verified directly as a speculative path.
4. That snapshot is taken between step 2 and the final reg_bounds_sync():
at this point dst_reg's var_off still holds the (const) original offset while r32 has just been blanked to the full range, i.e. the two are out of sync. When the speculative path later verifies insn 15 (r9 = r0), the inconsistent state reaches reg_bounds_sanity_check() and trips the warning.
var_off and the 32-bit range must always be consistent. There are two ways to keep the snapshot consistent:
1. sync var_off and r32 before the snapshot so they match, or
2. leave r32 at its original (already consistent) value and blank it only after the snapshot.
The whole point of sanitize_ptr_alu() is to insert a harmless masking sequence that keeps the access in bounds under speculation, so the state it snapshots should faithfully represent that. Take approach 2: move __mark_reg32_unbounded() to after sanitize_ptr_alu(), so the speculative snapshot keeps the pointer's original, consistent r32. The non-speculative path is unchanged: r32 is still blanked before the offset is applied and re-derived by reg_bounds_sync().
--- kernel/bpf/verifier.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
kernel/bpf/verifier.c +8 -3
@@ -13579,9 +13579,6 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, !check_reg_sane_offset(env, ptr_reg, ptr_reg->type))return -EINVAL ; -/* pointer types do not carry 32-bit bounds at the moment. */ -__mark_reg32_unbounded (dst_reg); -if (sanitize_needed (opcode)) { ret =sanitize_ptr_alu (env, insn, ptr_reg, off_reg, dst_reg, &info, false);
@@ -13589,6 +13586,14 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,return sanitize_err (env, insn, ret, off_reg, dst_reg); } +/* +* Pointer types do not carry 32-bit bounds at the moment. Blank r32 +* only after sanitize_ptr_alu() may have snapshotted dst_reg into a +* speculative path: otherwise reg_bounds_sanity_check() might hit some +* constraints violations. +*/ +__mark_reg32_unbounded (dst_reg); +switch (opcode) {case BPF_ADD :/* We can take a fixed offset as long as it doesn't overflow
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 512/1102 ufs: do not treat unreadable directory blocks as empty
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memis <[email protected]>
[ Upstream commit 08edfb34ee9ca54383970c65ed3a6013e84f5e16 ]
ufs_empty_dir() scans every directory block to decide whether a directory is empty before rmdir() removes it. When ufs_get_folio() cannot read or validate a block it returns an error pointer, and the loop currently skips that block with continue and keeps scanning the remaining blocks.
If none of the readable blocks hold an entry, the function returns 1 and the caller unlinks the directory. A directory whose contents live in a block that cannot be read, for example because of an I/O error or corrupted directory metadata, is therefore seen as empty and removed, losing the entries it still holds.
Follow the ext2 behaviour and treat an unreadable block as a reason to consider the directory not empty, so rmdir() fails instead of discarding data that could not be verified.
--- fs/ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ufs/dir.c +1 -1
@@ -590,7 +590,7 @@ int ufs_empty_dir(struct inode * inode) kaddr =ufs_get_folio (inode, i, &folio);if (IS_ERR (kaddr)) -continue ; +return 0 ; de = (struct ufs_dir_entry *)kaddr; kaddr +=ufs_last_byte (inode, i) -UFS_DIR_REC_LEN (1 );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 513/1102 drm/cirrus: Use video aperture helpers
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
[ Upstream commit c77ec6b18b0397cf1f0c270ea77310f70fe48081 ]
DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly.
Stable-dep-of: 92312d333bf7 ("drm/cirrus-qemu: Validate BAR0 size during probe")
--- drivers/gpu/drm/tiny/cirrus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/tiny/cirrus.c +2 -2
@@ -16,6 +16,7 @@* Copyright 1999-2001 Jeff Garzik <[email protected]> */ +#include <linux/aperture.h> #include <linux/iosys-map.h> #include <linux/module.h> #include <linux/pci.h>
@@ -23,7 +24,6 @@#include <video/cirrus.h> #include <video/vga.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_state_helper.h>
@@ -670,7 +670,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev,struct cirrus_device *cirrus;int ret; - ret =drm_aperture_remove_conflicting_pci_framebuffers (pdev, &cirrus_driver); + ret =aperture_remove_conflicting_pci_devices (pdev, cirrus_driver.name);if (ret)return ret;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 514/1102 drm/cirrus-qemu: Validate BAR0 size during probe
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Slawomir Stepien <[email protected]>
[ Upstream commit 92312d333bf700798f92f30406c721bce87506f3 ]
The cirrus-qemu driver relies on CIRRUS_VRAM_SIZE (4 MB) to validate framebuffer sizes. However, during PCI probe, the driver mapped BAR0 without verifying that its size matches CIRRUS_VRAM_SIZE.
If a PCI device with a BAR0 smaller than 4 MB is bound to the driver, the mapped VRAM will be smaller than expected. Because validation checks assume 4 MB VRAM, framebuffers larger than the mapped memory can be created.
When the display plane is updated (e.g. during release), cirrus_primary_plane_helper_atomic_update() copies the framebuffer to VRAM using drm_fb_memcpy(). Writing past the end of the mapped I/O memory causes a supervisor write page fault:
BUG: unable to handle page fault for address: ffffc9000389c000 ... RIP: 0010:memcpy_toio+0x7c/0xe0 arch/x86/lib/iomem.c:110 ... Call Trace: <TASK> iosys_map_memcpy_to include/linux/iosys-map.h:285 [inline] drm_fb_memcpy+0x325/0x5d0 drivers/gpu/drm/drm_format_helper.c:442 cirrus_primary_plane_helper_atomic_update+0x98a/0xb00 drivers/gpu/drm/tiny/cirrus-qemu.c:358 drm_atomic_helper_commit_planes+0x626/0xea0 drivers/gpu/drm/drm_atomic_helper.c:3038 drm_atomic_helper_commit_tail+0x60/0x510 drivers/gpu/drm/drm_atomic_helper.c:1989 commit_tail+0x2b1/0x3c0 drivers/gpu/drm/drm_atomic_helper.c:2074 drm_atomic_helper_commit+0xa77/0xb10 drivers/gpu/drm/drm_atomic_helper.c:2312
Fix this by validating in cirrus_pci_probe() that the PCI BAR0 resource is not less than CIRRUS_VRAM_SIZE, returning -ENODEV if it is less.
--- drivers/gpu/drm/tiny/cirrus.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/tiny/cirrus.c +3 -0
@@ -670,6 +670,9 @@ static int cirrus_pci_probe(struct pci_dev *pdev,struct cirrus_device *cirrus;int ret; +if (pci_resource_len (pdev,0 ) <CIRRUS_VRAM_SIZE ) +return -ENODEV ; + ret =aperture_remove_conflicting_pci_devices (pdev, cirrus_driver.name);if (ret)return ret;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 515/1102 net: icmp: avoid invalid transport header access in icmp_send tracepoint
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 7fcc2fe39fed1cb98a7374a113ff3800e8f9af80 ]
syzbot reported a WARNING triggered by DEBUG_NET_WARN_ON_ONCE():
WARNING: at skb_transport_header include/linux/skbuff.h:3087 [inline] WARNING: at udp_hdr include/linux/udp.h:23 [inline] WARNING: at do_trace_event_raw_event_icmp_send include/trace/events/icmp.h:30 [inline] WARNING: at trace_event_raw_event_icmp_send+0x48c/0x6ec include/trace/events/icmp.h:11 Call trace: skb_transport_header include/linux/skbuff.h:3087 [inline] udp_hdr include/linux/udp.h:23 [inline] do_trace_event_raw_event_icmp_send include/trace/events/icmp.h:30 [inline] trace_event_raw_event_icmp_send+0x48c/0x6ec include/trace/events/icmp.h:11 __traceiter_icmp_send include/trace/events/icmp.h:11 [inline] __do_trace_icmp_send include/trace/events/icmp.h:11 [inline] trace_icmp_send+0x320/0x49c include/trace/events/icmp.h:11 __icmp_send+0xcfc/0x11d8 net/ipv4/icmp.c:1013 ipv4_send_dest_unreach net/ipv4/route.c:1280 [inline] ipv4_link_failure+0x57c/0x8dc net/ipv4/route.c:1287 dst_link_failure include/net/dst.h:438 [inline] vti_tunnel_xmit+0xe40/0x17a4 net/ipv4/ip_vti.c:307
TP_fast_assign() unconditionally calls udp_hdr(skb) before checking whether the packet is UDP. Furthermore, __icmp_send() can be invoked from paths (e.g., link failures, ARP errors, forwarding, AF_PACKET) where skb->transport_header was never initialized (~0U).
Under CONFIG_DEBUG_NET=y, calling skb_transport_header(skb) triggers DEBUG_NET_WARN_ON_ONCE(!skb_transport_header_was_set(skb)).
Fix this by:
1. Only parsing transport info when iph->protocol == IPPROTO_UDP.
2. Using skb_header_pointer() at skb_network_offset(skb) + (iph->ihl << 2) to safely fetch the UDP header without assuming transport_header is set.
--- include/trace/events/icmp.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
include/trace/events/icmp.h +8 -5
@@ -27,17 +27,20 @@ TRACE_EVENT(icmp_send,TP_fast_assign ( struct iphdr *iph = ip_hdr(skb); -struct udphdr *uh =udp_hdr (skb); -int proto_4 = iph->protocol; +struct udphdr _uh, *uh =NULL ;__be32 *p32; __entry->skbaddr = skb; __entry->type = type; __entry->code = code; -if (proto_4 !=IPPROTO_UDP || (u8 *)uh < skb->head || - (u8 *)uh +sizeof (struct udphdr ) - >skb_tail_pointer (skb)) { +if (iph->protocol ==IPPROTO_UDP ) + uh =skb_header_pointer (skb, +skb_network_offset (skb) + + (iph->ihl <<2 ), +sizeof (_uh), &_uh); + +if (!uh) { __entry->sport =0 ; __entry->dport =0 ; __entry->ulen =0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 516/1102 tcp: use GFP_ATOMIC in tcp_send_active_reset()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 18666c73afe95eeca8707c699b63f96ce3acda42 ]
tcp_send_active_reset() can be called from contexts where gfp_any() (in tcp_disconnect()) or sk->sk_allocation (in __tcp_close() and mptcp_do_fastclose()) evaluates to GFP_KERNEL, which includes __GFP_FS and __GFP_DIRECT_RECLAIM.
Allocating with GFP_KERNEL while holding the socket lock (sk_lock) creates a lockdep dependency:
sk_lock -> fs_reclaim
This causes false-positive lockdep circular locking warnings with storage subsystems (such as nvme-tcp) that acquire socket locks in block I/O paths and invoke tcp_disconnect() or close sockets upon teardown:
set->srcu -> sk_lock -> fs_reclaim -> elevator_lock -> set->srcu
Active resets are small RST packet headers that should never enter direct reclaim or block while holding socket locks.
Use sk_gfp_mask(sk, GFP_ATOMIC | __GFP_NOWARN) inside tcp_send_active_reset() and remove its priority argument. This preserves __GFP_MEMALLOC access for SOCK_MEMALLOC sockets, suppresses allocation failure warnings, and aligns with other control packet allocations (e.g. tcp_send_fin(), __tcp_send_ack(), tcp_xmit_probe_skb()).
--- include/net/tcp.h | 3 +-- net/ipv4/tcp.c | 14 ++++++-------- net/ipv4/tcp_output.c | 4 ++-- net/ipv4/tcp_timer.c | 6 +++--- net/mptcp/protocol.c | 3 +-- net/mptcp/protocol.h | 2 +- 6 files changed, 14 insertions(+), 18 deletions(-)
include/net/tcp.h +1 -2
@@ -666,8 +666,7 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,void tcp_send_probe0 (struct sock *);int tcp_write_wakeup (struct sock *,int mib);void tcp_send_fin (struct sock *sk); -void tcp_send_active_reset (struct sock *sk,gfp_t priority, -enum sk_rst_reason reason); +void tcp_send_active_reset (struct sock *sk,enum sk_rst_reason reason);int tcp_send_synack (struct sock *);void tcp_push_one (struct sock *,unsigned int mss_now);void __tcp_send_ack (struct sock *sk,u32 rcv_nxt,u16 flags);
net/ipv4/tcp.c +6 -8
@@ -3111,8 +3111,7 @@ void __tcp_close(struct sock *sk, long timeout)/* Unread data was tossed, zap the connection. */ NET_INC_STATS (sock_net (sk),LINUX_MIB_TCPABORTONCLOSE );tcp_set_state (sk,TCP_CLOSE ); -tcp_send_active_reset (sk, sk->sk_allocation, -SK_RST_REASON_TCP_ABORT_ON_CLOSE ); +tcp_send_active_reset (sk,SK_RST_REASON_TCP_ABORT_ON_CLOSE ); }else if (sock_flag (sk,SOCK_LINGER ) && !sk->sk_lingertime) {/* Check zero linger _after_ checking for unread data. */ sk->sk_prot->disconnect (sk,0 );
@@ -3186,7 +3185,7 @@ void __tcp_close(struct sock *sk, long timeout)struct tcp_sock *tp =tcp_sk (sk);if (READ_ONCE (tp->linger2) <0 ) {tcp_set_state (sk,TCP_CLOSE ); -tcp_send_active_reset (sk,GFP_ATOMIC , +tcp_send_active_reset (sk,SK_RST_REASON_TCP_ABORT_ON_LINGER );__NET_INC_STATS (sock_net (sk),LINUX_MIB_TCPABORTONLINGER );
@@ -3205,7 +3204,7 @@ void __tcp_close(struct sock *sk, long timeout)if (sk->sk_state !=TCP_CLOSE ) {if (tcp_check_oom (sk,0 )) {tcp_set_state (sk,TCP_CLOSE ); -tcp_send_active_reset (sk,GFP_ATOMIC , +tcp_send_active_reset (sk,SK_RST_REASON_TCP_ABORT_ON_MEMORY );__NET_INC_STATS (sock_net (sk),LINUX_MIB_TCPABORTONMEMORY );
@@ -3306,14 +3305,14 @@ int tcp_disconnect(struct sock *sk, int flags) }else if (unlikely (tp->repair)) {WRITE_ONCE (sk->sk_err,ECONNABORTED ); }else if (tcp_need_reset (old_state)) { -tcp_send_active_reset (sk,gfp_any (),SK_RST_REASON_TCP_STATE ); +tcp_send_active_reset (sk,SK_RST_REASON_TCP_STATE );WRITE_ONCE (sk->sk_err,ECONNRESET ); }else if (tp->snd_nxt != tp->write_seq && (1 << old_state) & (TCPF_CLOSING |TCPF_LAST_ACK )) {/* The last check adjusts for discrepancy of Linux wrt. RFC * states */ -tcp_send_active_reset (sk,gfp_any (), +tcp_send_active_reset (sk,SK_RST_REASON_TCP_DISCONNECT_WITH_DATA );WRITE_ONCE (sk->sk_err,ECONNRESET ); }else if (old_state ==TCP_SYN_SENT )
@@ -4945,8 +4944,7 @@ int tcp_abort(struct sock *sk, int err)bh_lock_sock (sk);if (tcp_need_reset (sk->sk_state)) -tcp_send_active_reset (sk,GFP_ATOMIC , -SK_RST_REASON_TCP_STATE ); +tcp_send_active_reset (sk,SK_RST_REASON_TCP_STATE );tcp_done_with_error (sk, err);bh_unlock_sock (sk);
net/ipv4/tcp_output.c +2 -2
@@ -3642,9 +3642,9 @@ void tcp_send_fin(struct sock *sk)* was unread data in the receive queue. This behavior is recommended * by RFC 2525, section 2.17. -DaveM */ -void tcp_send_active_reset (struct sock *sk,gfp_t priority, -enum sk_rst_reason reason) +void tcp_send_active_reset (struct sock *sk,enum sk_rst_reason reason) { +gfp_t priority =sk_gfp_mask (sk,GFP_ATOMIC | __GFP_NOWARN);struct sk_buff *skb;TCP_INC_STATS (sock_net (sk),TCP_MIB_OUTRSTS );
net/ipv4/tcp_timer.c +3 -3
@@ -125,7 +125,7 @@ static int tcp_out_of_resources(struct sock *sk, bool do_reset) (!tp->snd_wnd && !tp->packets_out)) do_reset = true;if (do_reset) -tcp_send_active_reset (sk,GFP_ATOMIC , +tcp_send_active_reset (sk,SK_RST_REASON_TCP_ABORT_ON_MEMORY );tcp_done (sk);__NET_INC_STATS (sock_net (sk),LINUX_MIB_TCPABORTONMEMORY );
@@ -783,7 +783,7 @@ static void tcp_keepalive_timer (struct timer_list *t) goto out; } } -tcp_send_active_reset (sk,GFP_ATOMIC ,SK_RST_REASON_TCP_STATE ); +tcp_send_active_reset (sk,SK_RST_REASON_TCP_STATE ); goto death; }
@@ -810,7 +810,7 @@ static void tcp_keepalive_timer (struct timer_list *t) icsk->icsk_probes_out > 0) || (user_timeout == 0 && icsk->icsk_probes_out >= keepalive_probes(tp))) { -tcp_send_active_reset (sk,GFP_ATOMIC , +tcp_send_active_reset (sk,SK_RST_REASON_TCP_KEEPALIVE_TIMEOUT );tcp_write_err (sk); goto out;
net/mptcp/protocol.c +1 -2
@@ -2900,8 +2900,7 @@ static void mptcp_do_fastclose(struct sock *sk)*/ inet_csk (ssk)->icsk_ack.rcv_mss =TCP_MIN_MSS ; -tcp_send_active_reset (ssk, ssk->sk_allocation, -SK_RST_REASON_TCP_ABORT_ON_CLOSE ); +tcp_send_active_reset (ssk,SK_RST_REASON_TCP_ABORT_ON_CLOSE ); unlock:release_sock (ssk); }
net/mptcp/protocol.h +1 -1
@@ -646,7 +646,7 @@ mptcp_send_active_reset_reason(struct sock *sk)enum sk_rst_reason reason; reason =sk_rst_convert_mptcp_reason (subflow->reset_reason); -tcp_send_active_reset (sk,GFP_ATOMIC , reason); +tcp_send_active_reset (sk, reason); } static inline u64
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 517/1102 net: iptunnel: fix stale transport header during tunnel decapsulation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dong Chenchen <[email protected]>
[ Upstream commit 28a57fb2c5df4deb42a06e52fd36c14b37aa0034 ]
Syzbot reported a crash in qdisc_pkt_len_segs_init() caused by a stale transport_header offset after tunnel decapsulation.
BUG: unable to handle page fault for address: ffffed102091a42e Oops: Oops: 0000 [#1] SMP KASAN NOPTI CPU: 0 UID: 0 PID: 340 Comm: qdisc_uaf_repro Not tainted 7.2.0-rc4-00061-g248951ddc14d #256 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:__asan_load2 <IRQ>
qdisc_pkt_len_segs_init (net/core/dev.c:4145) __dev_queue_xmit (net/core/dev.c:4787) br_dev_queue_push_xmit (net/bridge/br_forward.c:53) br_handle_frame_finish (net/bridge/br_input.c:229) br_handle_frame (net/bridge/br_input.c:315) __netif_receive_skb_core.constprop.0 (net/core/dev.c:6099) __netif_receive_skb_list_core (net/core/dev.c:6287) netif_receive_skb_list_internal (net/core/dev.c:6445) napi_complete_done (net/core/dev.c:6813) gro_cell_poll (net/core/gro_cells.c:74) __napi_poll (net/core/dev.c:7735)net_rx_action (net/core/dev.c:7798 net/core/dev.c:7955) handle_softirqs (kernel/softirq.c:622)do_softirq (kernel/softirq.c:523 kernel/softirq.c:510 ) __local_bh_enable_ip (kernel/softirq.c:450) tun_get_user (drivers/net/tun.c:1986 (discriminator 1)) tun_chr_write_iter (drivers/net/tun.c:2032)
The issue is completely latent until qdisc read transport header in commit 7fb4c1967011 ("net: pull headers in qdisc_pkt_len_segs_init()"). The crash requires four conditions to line up:
1. The incoming packet is encapsulated and carries GSO metadata. The outer transport header offset is stored in skb->transport_header while the packet is still in the outer tunnel context.
2. The tunnel receiver strips the outer headers. skb->data is advanced to the inner frame, but skb->transport_header is left pointing to the now-removed outer L4 header, so it becomes a negative offset relative to the new data.
3. The inner frame is not delivered to the local IP stack. Instead, it is forwarded at L2 by a bridge or HSR, so ip_rcv_core() never runs and the transport header is not reset to the inner L4 offset.
4. The forwarding path calls __dev_queue_xmit(), which enters qdisc_pkt_len_segs_init(). That function computes the GSO header length from skb_transport_offset(skb). Because the offset is negative, the unsigned cast overflows and pskb_may_pull(skb, hdr_len + sizeof(struct tcphdr)) reads past the end of the skb, triggering a KASAN fault or page fault.
The issue specifically requires GSO packets (shinfo->gso_size != 0), which are processed/aggregated through gro_cells. Fix this by clearing transport_header to the ~0U sentinel in gro_cell for all tunnnel driver. GTP does not support GRO/GSO, drop the evil GSO packets in GTP directly.
--- drivers/net/gtp.c | 5 +++++ include/linux/skbuff.h | 5 +++++ net/core/gro_cells.c | 2 ++ 3 files changed, 12 insertions(+)
drivers/net/gtp.c +5 -0
@@ -315,6 +315,11 @@ static int gtp_inner_proto(struct sk_buff *skb, unsigned int hdrlen,static int gtp_rx (struct pdp_ctx *pctx,struct sk_buff *skb,unsigned int hdrlen,unsigned int role,__u16 inner_proto) { +if (skb_is_gso (skb)) { +netdev_dbg (pctx->dev,"GSO is not supported in GTP\n" ); + goto err; + } +if (!gtp_check_ms (skb, pctx, hdrlen, role, inner_proto)) {netdev_dbg (pctx->dev,"No PDP ctx for this MS\n" );return 1 ;
include/linux/skbuff.h +5 -0
@@ -3014,6 +3014,11 @@ static inline bool skb_transport_header_was_set(const struct sk_buff *skb) return skb->transport_header != (typeof(skb->transport_header))~0U; } +static inline void skb_unset_transport_header (struct sk_buff *skb) +{ + skb->transport_header = (typeof(skb->transport_header))~0U; +} +static inline unsigned char *skb_transport_header (const struct sk_buff *skb) {DEBUG_NET_WARN_ON_ONCE (!skb_transport_header_was_set (skb));
net/core/gro_cells.c +2 -0
@@ -20,6 +20,8 @@ int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)if (unlikely (!(dev->flags &IFF_UP ))) goto drop; +skb_unset_transport_header (skb); +if (!gcells->cells ||skb_cloned (skb) ||netif_elide_gro (dev)) { res =netif_rx (skb); goto unlock;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 518/1102 net/sched: act_api: budget all shared attributes in notify skbs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <[email protected]>
[ Upstream commit 13eb543cebef6d6c3ec42e31afe3856f51b7126b ]
tcf_action_shared_attrs_size() is supposed to return an upper bound on the netlink attributes every action dump emits outside of TCA_ACT_OPTIONS, so that tcf_add_notify_msg(), tcf_del_notify_msg() and friends can allocate an skb large enough for the reply. It has fallen behind the dump path and is now an underestimate for every single action.
Attributes, such as, TCA_ACT_IN_HW_COUNT and TCA_STATS_BASIC_HW are emitted unconditionally and never accounted for. TCA_STATS_PKT64, TCA_ACT_USED_HW_STATS, TCA_STATS_RATE_EST, TCA_STATS_RATE_EST64 require specific conditions, but are also not accounted for.
Fix the issue by budgeting all of them so that we have a legitimate upper bound. Even tough for of them require specific conditions, they are cheap so, to avoid overcomplicating, we opted to account for them unconditionally as well to account for a real worst case scenario.
--- net/sched/act_api.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
net/sched/act_api.c +11 -2
@@ -443,12 +443,21 @@ static size_t tcf_action_shared_attrs_size(const struct tc_action *act) +nla_total_size (IFNAMSIZ )/* TCA_ACT_KIND */ + cookie_len/* TCA_ACT_COOKIE */ +nla_total_size (sizeof (struct nla_bitfield32 ))/* TCA_ACT_HW_STATS */ +/* TCA_ACT_USED_HW_STATS */ + +nla_total_size (sizeof (struct nla_bitfield32 )) + +nla_total_size (sizeof (u32))/* TCA_ACT_IN_HW_COUNT */ +nla_total_size (0 )/* TCA_ACT_STATS nested */ +nla_total_size (sizeof (struct nla_bitfield32 ))/* TCA_ACT_FLAGS */ /* TCA_STATS_BASIC */ +nla_total_size_64bit (sizeof (struct gnet_stats_basic )) -/* TCA_STATS_PKT64 */ - +nla_total_size_64bit (sizeof (u64)) +/* TCA_STATS_BASIC_HW */ + +nla_total_size_64bit (sizeof (struct gnet_stats_basic )) +/* TCA_STATS_PKT64, emitted by both of the basic copies above */ + +2 *nla_total_size_64bit (sizeof (u64)) +/* TCA_STATS_RATE_EST */ + +nla_total_size_64bit (sizeof (struct gnet_stats_rate_est )) +/* TCA_STATS_RATE_EST64 */ + +nla_total_size_64bit (sizeof (struct gnet_stats_rate_est64 ))/* TCA_STATS_QUEUE */ +nla_total_size_64bit (sizeof (struct gnet_stats_queue )) +nla_total_size (0 )/* TCA_ACT_OPTIONS nested */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 519/1102 net/sched: act_api: size the RTM_GETACTION reply from the actions
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <[email protected]>
[ Upstream commit e9ca46ebc3262b498626c4095826b8fa034bbf21 ]
tca_action_gd() already walks every requested action and accumulates attr_size += tcf_action_fill_size(act), then wraps the result in tcf_action_full_attrs_size(). For RTM_DELACTION that value is handed to tcf_del_notify_msg(), which allocates max(attr_size, NLMSG_GOODSIZE). For RTM_GETACTION it is silently discarded and tcf_get_notify() allocates a fixed NLMSG_GOODSIZE skb instead.
Any action whose dump exceeds that fixed budget therefore cannot be read back. For example, act_pedit overruns the budget with 32 actions of four munge keys each, act_police with 32 policers once the optional rate/peakrate/result/avrate attributes are present
Fix this by passing attr_size through and allocate the reply the way the add and delete paths do.
Note on exposure: RTM_GETACTION is the only one of the three action commands that is not capability checked - tc_ctl_action() requires CAP_NET_ADMIN for RTM_NEWACTION and RTM_DELACTION only - so this turns a fixed NLMSG_GOODSIZE reply into a user sized allocation on an unprivileged path. It is bounded by TCA_ACT_MAX_PRIO actions per request, and tca_action_gd() does not reject duplicate indices, so a single large action can be requested 32 times; an act_bpf program near BPF_MAXINSNS is about 32KB of dump, or roughly 1MB for one request. Creating such an action still requires CAP_NET_ADMIN, and the add and delete paths have sized their skbs this way since the Fixes commit. Should this ever need bounding, GFP_KERNEL_ACCOUNT would charge the reply to the caller's memcg.
--- net/sched/act_api.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/sched/act_api.c +4 -3
@@ -1673,12 +1673,12 @@ static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],static int tcf_get_notify (struct net *net,u32 portid,struct nlmsghdr *n, -struct tc_action *actions[],int event, +struct tc_action *actions[],size_t attr_size,int event,struct netlink_ext_ack *extack) {struct sk_buff *skb; - skb =alloc_skb (NLMSG_GOODSIZE ,GFP_KERNEL ); + skb =alloc_skb (max (attr_size,NLMSG_GOODSIZE ),GFP_KERNEL );if (!skb)return -ENOBUFS ; if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
@@ -2029,7 +2029,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, attr_size =tcf_action_full_attrs_size (attr_size);if (event ==RTM_GETACTION ) - ret =tcf_get_notify (net, portid, n, actions, event, extack); + ret =tcf_get_notify (net, portid, n, actions, attr_size, event, + extack);else {/* delete */ ret =tcf_del_notify (net, n, actions, portid, attr_size, extack);if (ret)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 520/1102 net/sched: act_api: fix skb sizing and action leak on reoffload delete
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <[email protected]>
[ Upstream commit 251367a0a3319fa565daf7468b0afd933b1f5ab1 ]
tcf_reoffload_del_notify_msg() sizes the RTM_DELACTION skb with tcf_action_fill_size(action) alone. Unlike every other notification path it never wraps that in tcf_action_full_attrs_size(), so the nlmsg_put() header, struct tcamsg and the TCA_ACT_TAB nest that tca_get_fill() emits - 24 bytes on x86_64 - are not budgeted. As long as the single action stays well under NLMSG_GOODSIZE the floor in alloc_skb() hides this, but once its fill size crosses NLMSG_GOODSIZE the allocation is exactly 24 bytes short and tca_get_fill() runs out of tailroom. That is now easy to reach for an offloadable act_pedit with a large tcfp_nkeys, which commit 8e2efb3f45a5 ("net/sched: add get_fill_size callbacks for actions missing them") started accounting for properly.
When that happens tcf_reoffload_del_notify() returns early, before tcf_idr_release_unsafe(), and tcf_action_reoffload_cb() discards the return value:
if (tc_act_skip_sw(p->tcfa_flags) && !tc_act_in_hw(p)) tcf_reoffload_del_notify(net, p);
The action has just lost its last hardware instance and is skip_sw, so it is left installed while processing no packets, and with no notification to tell userspace about it. An -ENOBUFS from alloc_skb() gets the same treatment.
Fix this by budgeting the message header the way the add and delete paths do, and release the action even when the notification cannot be built - dropping the notification is strictly better than leaking a dead action, and there is no caller left to report the error to.
--- net/sched/act_api.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
net/sched/act_api.c +11 -6
@@ -1843,11 +1843,13 @@ static int tcf_action_delete(struct net *net, struct tc_action *actions[])static struct sk_buff *tcf_reoffload_del_notify_msg (struct net *net,struct tc_action *action) { -size_t attr_size =tcf_action_fill_size (action);struct tc_action *actions[TCA_ACT_MAX_PRIO ] = { [0 ] = action, };struct sk_buff *skb; +size_t attr_size; + + attr_size =tcf_action_full_attrs_size (tcf_action_fill_size (action)); skb =alloc_skb (max (attr_size,NLMSG_GOODSIZE ),GFP_KERNEL );if (!skb)
@@ -1864,15 +1866,18 @@ static struct sk_buff *tcf_reoffload_del_notify_msg(struct net *net,static int tcf_reoffload_del_notify (struct net *net,struct tc_action *action) {const struct tc_action_ops *ops = action->ops; -struct sk_buff *skb; +struct sk_buff *skb =NULL ;int ret; -if (!rtnl_notify_needed (net,0 ,RTNLGRP_TC )) { - skb =NULL ; - }else { +if (rtnl_notify_needed (net,0 ,RTNLGRP_TC )) { skb =tcf_reoffload_del_notify_msg (net, action); +/* The action has already lost its hardware instance and is +* skip_sw, so it must be released whether or not the +* notification can be built. Drop the notification rather +* than leave an action behind that processes no packets. +*/ if (IS_ERR (skb)) -return PTR_ERR (skb); + skb =NULL ; } ret =tcf_idr_release_unsafe (action);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 521/1102 sctp: fix a TOCTOU race in SCTP_CMD_TIMER_START
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
[ Upstream commit 2188569e7e1b0bc3f3b557dc97ab7a02befc11c8 ]
The SCTP_CMD_TIMER_START handler checks timer_pending() before calling timer_reduce(). The timer can expire and detach between these operations, causing timer_reduce() to rearm the timer without taking the association reference required for the newly armed timer.
The timer callback later unconditionally drops its association reference, which can leave the association reference count unbalanced and result in use-after-free during association teardown.
Use the return value of timer_reduce() to determine whether the timer was actually armed. Take the association reference only when timer_reduce() successfully starts a new timer, closing the race between checking the timer state and rearming it.
This issue was reported by Nico Yip (@_cyeaa_) working with TrendAI Zero Day Initiative.
--- net/sctp/sm_sideeffect.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
net/sctp/sm_sideeffect.c +1 -10
@@ -1539,17 +1539,8 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, timeout = asoc->timeouts[cmd->obj.to];BUG_ON (!timeout); -/* -* SCTP has a hard time with timer starts. Because we process -* timer starts as side effects, it can be hard to tell if we -* have already started a timer or not, which leads to BUG -* halts when we call add_timer. So here, instead of just starting -* a timer, if the timer is already started, and just mod -* the timer with the shorter of the two expiration times -*/ -if (!timer_pending (timer)) +if (!timer_reduce (timer, jiffies + timeout))sctp_association_hold (asoc); -timer_reduce (timer, jiffies + timeout);break ;case SCTP_CMD_TIMER_RESTART :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 522/1102 scsi: mpi3mr: Fix NULL pointer dereference in mpi3mr_sas_port_add()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Milan P. Gandhi <[email protected]>
[ Upstream commit dba9e2181ca5e875f98b8b9b4535cdaab87dcb0d ]
sas_port_alloc_num() can return NULL on memory allocation failure. The return value is passed directly to sas_port_add() without a NULL check, which causes a NULL pointer dereference.
Additionally, if sas_port_add() fails, the allocated port is not freed before jumping to out_fail, leaking the sas_port structure. Call sas_port_free() to properly release it.
--- drivers/scsi/mpi3mr/mpi3mr_transport.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/scsi/mpi3mr/mpi3mr_transport.c +6 -0
@@ -1428,9 +1428,15 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, } port =sas_port_alloc_num (mr_sas_node->parent_dev); +if (!port) { +ioc_err (mrioc,"failure at %s:%d/%s()!\n" , + __FILE__, __LINE__, __func__); + goto out_fail; + }if ((sas_port_add (port))) {ioc_err (mrioc,"failure at %s:%d/%s()!\n" , __FILE__, __LINE__, __func__); +sas_port_free (port); goto out_fail; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 523/1102 scsi: mpi3mr: Fix target device refcount leak in mpi3mr_sas_port_add()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Milan P. Gandhi <[email protected]>
[ Upstream commit 419d129f970aaa6567dbac366b0c93784bf9ec97 ]
mpi3mr_get_tgtdev_by_addr() increments the target device kref when it returns a device. If a subsequent error triggers a goto out_fail after the tgtdev reference is acquired, the reference is never released because the out_fail path does not call mpi3mr_tgtdev_put(). This prevents the target device structure from ever being freed.
Add a tgtdev put in the out_fail path, guarded by a NULL check since tgtdev is only acquired for SAS_END_DEVICE types and the same cleanup path is shared by earlier error cases where tgtdev is still NULL.
--- drivers/scsi/mpi3mr/mpi3mr_transport.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/mpi3mr/mpi3mr_transport.c +2 -0
@@ -1507,6 +1507,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,list_for_each_entry_safe (mr_sas_phy, next, &mr_sas_port->phy_list, port_siblings)list_del (&mr_sas_phy->port_siblings); +if (tgtdev) +mpi3mr_tgtdev_put (tgtdev);kfree (mr_sas_port);return NULL ; }
Signature · 1 line
2.53.0