From: Jiri Pirko jiri@nvidia.com
[ Upstream commit 633d76ad01ad0321a1ace3e5cc4fed06753d7ac4 ]
The checks in question were introduced by: commit 6b4db2e528f6 ("devlink: Fix use-after-free after a failed reload"). That fixed an issue of reload with mlxsw driver.
Back then, that was a valid fix, because there was a limitation in place that prevented drivers from registering/unregistering params when devlink instance was registered.
It was possible to do the fix differently by changing drivers to register/unregister params in appropriate places making sure the ops operate only on memory which is allocated and initialized. But that, as a dependency, would require to remove the limitation mentioned above.
Eventually, this limitation was lifted by: commit 1d18bb1a4ddd ("devlink: allow registering parameters after the instance")
Also, the alternative fix (which also fixed another issue) was done by: commit 74cbc3c03c82 ("mlxsw: spectrum_acl_tcam: Move devlink param to TCAM code").
Therefore, the checks are no longer relevant. Each driver should make sure to have the params registered only when the memory the ops are working with is allocated and initialized.
So remove the checks.
Signed-off-by: Jiri Pirko jiri@nvidia.com Reviewed-by: Ido Schimmel idosch@nvidia.com Reviewed-by: Jakub Kicinski kuba@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/devlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/core/devlink.c b/net/core/devlink.c index 5a4a4b34ac15c..6ab335d2a0f56 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -5218,7 +5218,7 @@ static int devlink_param_get(struct devlink *devlink, const struct devlink_param *param, struct devlink_param_gset_ctx *ctx) { - if (!param->get || devlink->reload_failed) + if (!param->get) return -EOPNOTSUPP; return param->get(devlink, param->id, ctx); } @@ -5227,7 +5227,7 @@ static int devlink_param_set(struct devlink *devlink, const struct devlink_param *param, struct devlink_param_gset_ctx *ctx) { - if (!param->set || devlink->reload_failed) + if (!param->set) return -EOPNOTSUPP; return param->set(devlink, param->id, ctx); }
From: Azeem Shaikh azeemshaikh38@gmail.com
[ Upstream commit babb80b3ecc6f40c962e13c654ebcd27f25ee327 ]
strlcpy() reads the entire source buffer first. This read may exceed the destination size limit. This is both inefficient and can lead to linear read overflows if a source string is not NUL-terminated [1]. In an effort to remove strlcpy() completely [2], replace strlcpy() here with strscpy().
Direct replacement is safe here since return value of -errno is used to check for truncation instead of sizeof(dest).
[1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy [2] https://github.com/KSPP/linux/issues/89
Signed-off-by: Azeem Shaikh azeemshaikh38@gmail.com Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/lrw.c | 6 +++--- crypto/xts.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/crypto/lrw.c b/crypto/lrw.c index 8d59a66b65255..fb8892ed179f5 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c @@ -357,10 +357,10 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb) * cipher name. */ if (!strncmp(cipher_name, "ecb(", 4)) { - unsigned len; + int len;
- len = strlcpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); - if (len < 2 || len >= sizeof(ecb_name)) + len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); + if (len < 2) goto err_free_inst;
if (ecb_name[len - 1] != ')') diff --git a/crypto/xts.c b/crypto/xts.c index de6cbcf69bbd6..b05020657cdc8 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -396,10 +396,10 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb) * cipher name. */ if (!strncmp(cipher_name, "ecb(", 4)) { - unsigned len; + int len;
- len = strlcpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); - if (len < 2 || len >= sizeof(ctx->name)) + len = strscpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); + if (len < 2) goto err_free_inst;
if (ctx->name[len - 1] != ')')
From: Wojciech Drewek wojciech.drewek@intel.com
[ Upstream commit 7aa529a69e92b9aff585e569d5003f7c15d8d60b ]
There is possibility that ice_eswitch_port_start_xmit might be called while some resources are still not allocated which might cause NULL pointer dereference. Fix this by checking if switchdev configuration was finished.
Reviewed-by: Paul Menzel pmenzel@molgen.mpg.de Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Wojciech Drewek wojciech.drewek@intel.com Tested-by: Sujai Buvaneswaran sujai.buvaneswaran@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/ice/ice_eswitch.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c index 2ffe5708a045b..7de4a8a4b563c 100644 --- a/drivers/net/ethernet/intel/ice/ice_eswitch.c +++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c @@ -361,6 +361,9 @@ ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev) np = netdev_priv(netdev); vsi = np->vsi;
+ if (!vsi || !ice_is_switchdev_running(vsi->back)) + return NETDEV_TX_BUSY; + if (ice_is_reset_in_progress(vsi->back->state) || test_bit(ICE_VF_DIS, vsi->back->state)) return NETDEV_TX_BUSY;
From: Dmitry Antipov dmantipov@yandex.ru
[ Upstream commit 810e41cebb6c6e394f2068f839e1a3fc745a5dcc ]
When compiling with gcc 13.1 and CONFIG_FORTIFY_SOURCE=y, I've noticed the following:
In function ‘fortify_memcpy_chk’, inlined from ‘ath_tx_complete_aggr’ at drivers/net/wireless/ath/ath9k/xmit.c:556:4, inlined from ‘ath_tx_process_buffer’ at drivers/net/wireless/ath/ath9k/xmit.c:773:3: ./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning] 529 | __read_overflow2_field(q_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘fortify_memcpy_chk’, inlined from ‘ath_tx_count_frames’ at drivers/net/wireless/ath/ath9k/xmit.c:473:3, inlined from ‘ath_tx_complete_aggr’ at drivers/net/wireless/ath/ath9k/xmit.c:572:2, inlined from ‘ath_tx_process_buffer’ at drivers/net/wireless/ath/ath9k/xmit.c:773:3: ./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning] 529 | __read_overflow2_field(q_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In both cases, the compiler complains on:
memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
which is the legal way to copy both 'ba_low' and following 'ba_high' members of 'struct ath_tx_status' at once (that is, issue one 8-byte 'memcpy()' for two 4-byte fields). Since the fortification logic seems interprets this trick as an attempt to overread 4-byte 'ba_low', silence relevant warnings by using the convenient 'struct_group()' quirk.
Suggested-by: Johannes Berg johannes@sipsolutions.net Signed-off-by: Dmitry Antipov dmantipov@yandex.ru Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230620080855.396851-2-dmantipov@yandex.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/mac.h | 6 ++++-- drivers/net/wireless/ath/ath9k/xmit.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index af44b33814ddc..f03d792732da7 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -115,8 +115,10 @@ struct ath_tx_status { u8 qid; u16 desc_id; u8 tid; - u32 ba_low; - u32 ba_high; + struct_group(ba, + u32 ba_low; + u32 ba_high; + ); u32 evm0; u32 evm1; u32 evm2; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index ba271a10d4ab1..eeabdd67fbccd 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -462,7 +462,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, isaggr = bf_isaggr(bf); if (isaggr) { seq_st = ts->ts_seqnum; - memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); + memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3); }
while (bf) { @@ -545,7 +545,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (isaggr && txok) { if (ts->ts_flags & ATH9K_TX_BA) { seq_st = ts->ts_seqnum; - memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); + memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3); } else { /* * AR5416 can become deaf/mute when BA
From: Dongliang Mu dzm91@hust.edu.cn
[ Upstream commit 061115fbfb2ce5870c9a004d68dc63138c07c782 ]
Smatch reports:
ath_pci_probe() warn: argument 4 to %lx specifier is cast from pointer ath_ahb_probe() warn: argument 4 to %lx specifier is cast from pointer
Fix it by modifying %lx to %p in the printk format string.
Note that with this change, the pointer address will be printed as a hashed value by default. This is appropriate because the kernel should not leak kernel pointers to user space in an informational message. If someone wants to see the real address for debugging purposes, this can be achieved with the no_hash_pointers kernel option.
Signed-off-by: Dongliang Mu dzm91@hust.edu.cn Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230723040403.296723-1-dzm91@hust.edu.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/ahb.c | 4 ++-- drivers/net/wireless/ath/ath9k/pci.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 9cd12b20b18d8..9bfaadfa6c009 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -132,8 +132,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
ah = sc->sc_ah; ath9k_hw_name(ah, hw_name, sizeof(hw_name)); - wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)mem, irq); + wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n", + hw_name, mem, irq);
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index a074e23013c58..f0e3901e8182a 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -988,8 +988,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) sc->sc_ah->msi_reg = 0;
ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); - wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)sc->mem, pdev->irq); + wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n", + hw_name, sc->mem, pdev->irq);
return 0;
From: Dmitry Antipov dmantipov@yandex.ru
[ Upstream commit dcce94b80a954a8968ff29fafcfb066d6197fa9a ]
When compiling with gcc 13.1 and CONFIG_FORTIFY_SOURCE=y, I've noticed the following:
In function ‘fortify_memcpy_chk’, inlined from ‘mwifiex_construct_tdls_action_frame’ at drivers/net/wireless/marvell/mwifiex/tdls.c:765:3, inlined from ‘mwifiex_send_tdls_action_frame’ at drivers/net/wireless/marvell/mwifiex/tdls.c:856:6: ./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning] 529 | __read_overflow2_field(q_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The compiler actually complains on:
memmove(pos + ETH_ALEN, &mgmt->u.action.category, sizeof(mgmt->u.action.u.tdls_discover_resp));
and it happens because the fortification logic interprets this as an attempt to overread 1-byte 'u.action.category' member of 'struct ieee80211_mgmt'. To silence this warning, it's enough to pass an address of 'u.action' itself instead of an address of its first member.
This also fixes an improper usage of 'sizeof()'. Since 'skb' is extended with 'sizeof(mgmt->u.action.u.tdls_discover_resp) + 1' bytes (where 1 is actually 'sizeof(mgmt->u.action.category)'), I assume that the same number of bytes should be copied.
Suggested-by: Brian Norris briannorris@chromium.org Signed-off-by: Dmitry Antipov dmantipov@yandex.ru Reviewed-by: Brian Norris briannorris@chromium.org Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230629085115.180499-2-dmantipov@yandex.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/tdls.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c index 97bb87c3676bb..6c60621b6cccb 100644 --- a/drivers/net/wireless/marvell/mwifiex/tdls.c +++ b/drivers/net/wireless/marvell/mwifiex/tdls.c @@ -735,6 +735,7 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, int ret; u16 capab; struct ieee80211_ht_cap *ht_cap; + unsigned int extra; u8 radio, *pos;
capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; @@ -753,7 +754,10 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
switch (action_code) { case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: - skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1); + /* See the layout of 'struct ieee80211_mgmt'. */ + extra = sizeof(mgmt->u.action.u.tdls_discover_resp) + + sizeof(mgmt->u.action.category); + skb_put(skb, extra); mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; @@ -762,8 +766,7 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, mgmt->u.action.u.tdls_discover_resp.capability = cpu_to_le16(capab); /* move back for addr4 */ - memmove(pos + ETH_ALEN, &mgmt->u.action.category, - sizeof(mgmt->u.action.u.tdls_discover_resp)); + memmove(pos + ETH_ALEN, &mgmt->u.action, extra); /* init address 4 */ eth_broadcast_addr(pos);
From: Matt Whitlock kernel@mattwhitlock.name
[ Upstream commit 98c4d0abf5c478db1ad126ff0c187dbb84c0803c ]
mt7921_usb_sdio_tx_prepare_skb() calls mt7921_usb_sdio_write_txwi() and mt7921_skb_add_usb_sdio_hdr(), both of which blindly assume that adequate headroom will be available in the passed skb. This assumption typically is satisfied when the skb was allocated in the net core for transmission via the mt7921 netdev (although even that is only an optimization and is not strictly guaranteed), but the assumption is sometimes not satisfied when the skb originated in the receive path of another netdev and was passed through to the mt7921, such as by the bridge layer. Blindly prepending bytes to an skb is always wrong.
This commit introduces a call to skb_cow_head() before the call to mt7921_usb_sdio_write_txwi() in mt7921_usb_sdio_tx_prepare_skb() to ensure that at least MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE bytes can be pushed onto the skb.
Without this fix, I can trivially cause kernel panics by bridging an MT7921AU-based USB 802.11ax interface with an Ethernet interface on an Intel Atom-based x86 system using its onboard RTL8169 PCI Ethernet adapter and also on an ARM-based Raspberry Pi 1 using its onboard SMSC9512 USB Ethernet adapter. Note that the panics do not occur in every system configuration, as they occur only if the receiving netdev leaves less headroom in its received skbs than the mt7921 needs for its SDIO headers.
Here is an example stack trace of this panic on Raspberry Pi OS Lite 2023-02-21 running kernel 6.1.24+ [1]:
skb_panic from skb_push+0x44/0x48 skb_push from mt7921_usb_sdio_tx_prepare_skb+0xd4/0x190 [mt7921_common] mt7921_usb_sdio_tx_prepare_skb [mt7921_common] from mt76u_tx_queue_skb+0x94/0x1d0 [mt76_usb] mt76u_tx_queue_skb [mt76_usb] from __mt76_tx_queue_skb+0x4c/0xc8 [mt76] __mt76_tx_queue_skb [mt76] from mt76_txq_schedule.part.0+0x13c/0x398 [mt76] mt76_txq_schedule.part.0 [mt76] from mt76_txq_schedule_all+0x24/0x30 [mt76] mt76_txq_schedule_all [mt76] from mt7921_tx_worker+0x58/0xf4 [mt7921_common] mt7921_tx_worker [mt7921_common] from __mt76_worker_fn+0x9c/0xec [mt76] __mt76_worker_fn [mt76] from kthread+0xbc/0xe0 kthread from ret_from_fork+0x14/0x34
After this fix, bridging the mt7921 interface works fine on both of my previously problematic systems.
[1] https://github.com/raspberrypi/firmware/tree/5c276f55a4b21345cd4d6200a504ee9...
Link: https://github.com/openwrt/openwrt/issues/11796 Signed-off-by: Matt Whitlock kernel@mattwhitlock.name Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 1c0d8cf19b8eb..49ddca84f7862 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -1167,6 +1167,10 @@ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, if (unlikely(tx_info->skb->len <= ETH_HLEN)) return -EINVAL;
+ err = skb_cow_head(skb, MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE); + if (err) + return err; + if (!wcid) wcid = &dev->mt76.global_wcid;
From: Dmitry Antipov dmantipov@yandex.ru
[ Upstream commit 1ad8237e971630c66a1a6194491e0837b64d00e0 ]
When compiling with gcc 13.1 and CONFIG_FORTIFY_SOURCE=y, I've noticed the following:
In function ‘fortify_memcpy_chk’, inlined from ‘wil_rx_crypto_check_edma’ at drivers/net/wireless/ath/wil6210/txrx_edma.c:566:2: ./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning] 529 | __read_overflow2_field(q_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where the compiler complains on:
const u8 *pn; ... pn = (u8 *)&st->ext.pn_15_0; ... memcpy(cc->pn, pn, IEEE80211_GCMP_PN_LEN);
and:
In function ‘fortify_memcpy_chk’, inlined from ‘wil_rx_crypto_check’ at drivers/net/wireless/ath/wil6210/txrx.c:684:2: ./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning] 529 | __read_overflow2_field(q_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where the compiler complains on:
const u8 *pn = (u8 *)&d->mac.pn_15_0; ... memcpy(cc->pn, pn, IEEE80211_GCMP_PN_LEN);
In both cases, the fortification logic interprets 'memcpy()' as 6-byte overread of 2-byte field 'pn_15_0' of 'struct wil_rx_status_extension' and 'pn_15_0' of 'struct vring_rx_mac', respectively. To silence these warnings, last two fields of the aforementioned structures are grouped using 'struct_group_attr(pn, __packed' quirk.
Signed-off-by: Dmitry Antipov dmantipov@yandex.ru Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230621093711.80118-1-dmantipov@yandex.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wil6210/txrx.c | 2 +- drivers/net/wireless/ath/wil6210/txrx.h | 6 ++++-- drivers/net/wireless/ath/wil6210/txrx_edma.c | 2 +- drivers/net/wireless/ath/wil6210/txrx_edma.h | 6 ++++-- 4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 237cbd5c5060b..f29ac6de71399 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -666,7 +666,7 @@ static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb) struct wil_tid_crypto_rx *c = mc ? &s->group_crypto_rx : &s->tid_crypto_rx[tid]; struct wil_tid_crypto_rx_single *cc = &c->key_id[key_id]; - const u8 *pn = (u8 *)&d->mac.pn_15_0; + const u8 *pn = (u8 *)&d->mac.pn;
if (!cc->key_set) { wil_err_ratelimited(wil, diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index 1ae1bec1b97f1..689f68d89a440 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h @@ -343,8 +343,10 @@ struct vring_rx_mac { u32 d0; u32 d1; u16 w4; - u16 pn_15_0; - u32 pn_47_16; + struct_group_attr(pn, __packed, + u16 pn_15_0; + u32 pn_47_16; + ); } __packed;
/* Rx descriptor - DMA part diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index 201c8c35e0c9e..1ba1f21ebea26 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -548,7 +548,7 @@ static int wil_rx_crypto_check_edma(struct wil6210_priv *wil, s = &wil->sta[cid]; c = mc ? &s->group_crypto_rx : &s->tid_crypto_rx[tid]; cc = &c->key_id[key_id]; - pn = (u8 *)&st->ext.pn_15_0; + pn = (u8 *)&st->ext.pn;
if (!cc->key_set) { wil_err_ratelimited(wil, diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h index c736f7413a35f..ee90e225bb050 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.h +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h @@ -330,8 +330,10 @@ struct wil_rx_status_extension { u32 d0; u32 d1; __le16 seq_num; /* only lower 12 bits */ - u16 pn_15_0; - u32 pn_47_16; + struct_group_attr(pn, __packed, + u16 pn_15_0; + u32 pn_47_16; + ); } __packed;
struct wil_rx_status_extended {
From: John Watts contact@jookia.org
[ Upstream commit 8cda0c6dfd42ee6f2586e7dffb553aaf1fcb62ca ]
The Allwinner D1's CAN controllers have the ACPC and ACPM registers moved down. Compensate for this by adding an offset quirk for the acceptance registers.
Signed-off-by: John Watts contact@jookia.org Link: https://lore.kernel.org/all/20230721221552.1973203-5-contact@jookia.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/sun4i_can.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index 2b78f9197681b..dd0c6cd76c5f5 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -205,9 +205,11 @@ * struct sun4ican_quirks - Differences between SoC variants. * * @has_reset: SoC needs reset deasserted. + * @acp_offset: Offset of ACPC and ACPM registers */ struct sun4ican_quirks { bool has_reset; + int acp_offset; };
struct sun4ican_priv { @@ -216,6 +218,7 @@ struct sun4ican_priv { struct clk *clk; struct reset_control *reset; spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */ + int acp_offset; };
static const struct can_bittiming_const sun4ican_bittiming_const = { @@ -338,8 +341,8 @@ static int sun4i_can_start(struct net_device *dev) }
/* set filters - we accept all */ - writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR); - writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR); + writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR + priv->acp_offset); + writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR + priv->acp_offset);
/* clear error counters and error code capture */ writel(0, priv->base + SUN4I_REG_ERRC_ADDR); @@ -768,10 +771,12 @@ static const struct ethtool_ops sun4ican_ethtool_ops = {
static const struct sun4ican_quirks sun4ican_quirks_a10 = { .has_reset = false, + .acp_offset = 0, };
static const struct sun4ican_quirks sun4ican_quirks_r40 = { .has_reset = true, + .acp_offset = 0, };
static const struct of_device_id sun4ican_of_match[] = { @@ -872,6 +877,7 @@ static int sun4ican_probe(struct platform_device *pdev) priv->base = addr; priv->clk = clk; priv->reset = reset; + priv->acp_offset = quirks->acp_offset; spin_lock_init(&priv->cmdreg_lock);
platform_set_drvdata(pdev, dev);
From: John Watts contact@jookia.org
[ Upstream commit 8abb95250ae6af2d51993da8fcae18da2ce24cc4 ]
The controllers present in the D1 are extremely similar to the R40 and require the same reset quirks, but An extra quirk is needed to support receiving packets.
Signed-off-by: John Watts contact@jookia.org Link: https://lore.kernel.org/all/20230721221552.1973203-6-contact@jookia.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/Kconfig | 4 ++-- drivers/net/can/sun4i_can.c | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 3048ad77edb35..8236aabebb394 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -174,10 +174,10 @@ config CAN_SLCAN
config CAN_SUN4I tristate "Allwinner A10 CAN controller" - depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST + depends on MACH_SUN4I || MACH_SUN7I || RISCV || COMPILE_TEST help Say Y here if you want to use CAN controller found on Allwinner - A10/A20 SoCs. + A10/A20/D1 SoCs.
To compile this driver as a module, choose M here: the module will be called sun4i_can. diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index dd0c6cd76c5f5..c3a6b028ea4d6 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -91,6 +91,8 @@ #define SUN4I_REG_BUF12_ADDR 0x0070 /* CAN Tx/Rx Buffer 12 */ #define SUN4I_REG_ACPC_ADDR 0x0040 /* CAN Acceptance Code 0 */ #define SUN4I_REG_ACPM_ADDR 0x0044 /* CAN Acceptance Mask 0 */ +#define SUN4I_REG_ACPC_ADDR_D1 0x0028 /* CAN Acceptance Code 0 on the D1 */ +#define SUN4I_REG_ACPM_ADDR_D1 0x002C /* CAN Acceptance Mask 0 on the D1 */ #define SUN4I_REG_RBUF_RBACK_START_ADDR 0x0180 /* CAN transmit buffer start */ #define SUN4I_REG_RBUF_RBACK_END_ADDR 0x01b0 /* CAN transmit buffer end */
@@ -779,6 +781,11 @@ static const struct sun4ican_quirks sun4ican_quirks_r40 = { .acp_offset = 0, };
+static const struct sun4ican_quirks sun4ican_quirks_d1 = { + .has_reset = true, + .acp_offset = (SUN4I_REG_ACPC_ADDR_D1 - SUN4I_REG_ACPC_ADDR), +}; + static const struct of_device_id sun4ican_of_match[] = { { .compatible = "allwinner,sun4i-a10-can", @@ -789,6 +796,9 @@ static const struct of_device_id sun4ican_of_match[] = { }, { .compatible = "allwinner,sun8i-r40-can", .data = &sun4ican_quirks_r40 + }, { + .compatible = "allwinner,sun20i-d1-can", + .data = &sun4ican_quirks_d1 }, { /* sentinel */ }, @@ -915,4 +925,4 @@ module_platform_driver(sun4i_can_driver); MODULE_AUTHOR("Peter Chen xingkongcp@gmail.com"); MODULE_AUTHOR("Gerhard Bertelsmann info@gerhard-bertelsmann.de"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20)"); +MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20/D1)");
Hi!
From: John Watts contact@jookia.org
[ Upstream commit 8abb95250ae6af2d51993da8fcae18da2ce24cc4 ]
The controllers present in the D1 are extremely similar to the R40 and require the same reset quirks, but An extra quirk is needed to support receiving packets.
Well, we are not adding the rest of support to 6.1, so we don't need this, either. It will be unused.
BR, Pavel
+++ b/drivers/net/can/Kconfig @@ -174,10 +174,10 @@ config CAN_SLCAN config CAN_SUN4I tristate "Allwinner A10 CAN controller"
- depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
- depends on MACH_SUN4I || MACH_SUN7I || RISCV || COMPILE_TEST help Say Y here if you want to use CAN controller found on Allwinner
A10/A20 SoCs.
A10/A20/D1 SoCs.
To compile this driver as a module, choose M here: the module will be called sun4i_can. diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index dd0c6cd76c5f5..c3a6b028ea4d6 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -91,6 +91,8 @@ #define SUN4I_REG_BUF12_ADDR 0x0070 /* CAN Tx/Rx Buffer 12 */ #define SUN4I_REG_ACPC_ADDR 0x0040 /* CAN Acceptance Code 0 */ #define SUN4I_REG_ACPM_ADDR 0x0044 /* CAN Acceptance Mask 0 */ +#define SUN4I_REG_ACPC_ADDR_D1 0x0028 /* CAN Acceptance Code 0 on the D1 */ +#define SUN4I_REG_ACPM_ADDR_D1 0x002C /* CAN Acceptance Mask 0 on the D1 */ #define SUN4I_REG_RBUF_RBACK_START_ADDR 0x0180 /* CAN transmit buffer start */ #define SUN4I_REG_RBUF_RBACK_END_ADDR 0x01b0 /* CAN transmit buffer end */ @@ -779,6 +781,11 @@ static const struct sun4ican_quirks sun4ican_quirks_r40 = { .acp_offset = 0, }; +static const struct sun4ican_quirks sun4ican_quirks_d1 = {
- .has_reset = true,
- .acp_offset = (SUN4I_REG_ACPC_ADDR_D1 - SUN4I_REG_ACPC_ADDR),
+};
static const struct of_device_id sun4ican_of_match[] = { { .compatible = "allwinner,sun4i-a10-can", @@ -789,6 +796,9 @@ static const struct of_device_id sun4ican_of_match[] = { }, { .compatible = "allwinner,sun8i-r40-can", .data = &sun4ican_quirks_r40
- }, {
.compatible = "allwinner,sun20i-d1-can",
}, { /* sentinel */ },.data = &sun4ican_quirks_d1
@@ -915,4 +925,4 @@ module_platform_driver(sun4i_can_driver); MODULE_AUTHOR("Peter Chen xingkongcp@gmail.com"); MODULE_AUTHOR("Gerhard Bertelsmann info@gerhard-bertelsmann.de"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20)"); +MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20/D1)");
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 8936bf53a091ad6a34b480c22002f1cb2422ab38 ]
Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") started applying strict rules to standard string functions.
It does not work well with conventional socket code around each protocol- specific sockaddr_XXX struct, which is cast from sockaddr_storage and has a bigger size than fortified functions expect. See these commits:
commit 06d4c8a80836 ("af_unix: Fix fortify_panic() in unix_bind_bsd().") commit ecb4534b6a1c ("af_unix: Terminate sun_path when bind()ing pathname socket.") commit a0ade8404c3b ("af_packet: Fix warning of fortified memcpy() in packet_getname().")
We must cast the protocol-specific address back to sockaddr_storage to call such functions.
However, in the case of getsockaddr(SO_PEERNAME), the rationale is a bit unclear as the buffer is defined by char[128] which is the same size as sockaddr_storage.
Let's use sockaddr_storage explicitly.
Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Eric Dumazet edumazet@google.com Reviewed-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/sock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/core/sock.c b/net/core/sock.c index 509773919d302..9adaca71caa72 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1769,14 +1769,14 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
case SO_PEERNAME: { - char address[128]; + struct sockaddr_storage address;
- lv = sock->ops->getname(sock, (struct sockaddr *)address, 2); + lv = sock->ops->getname(sock, (struct sockaddr *)&address, 2); if (lv < 0) return -ENOTCONN; if (lv < len) return -EINVAL; - if (copy_to_sockptr(optval, address, len)) + if (copy_to_sockptr(optval, &address, len)) return -EFAULT; goto lenout; }
From: xu xin xu.xin16@zte.com.cn
[ Upstream commit c67180efc507e04a87f22aa68bd7dd832db006b7 ]
For now, No matter what error pointer ip_neigh_for_gw() returns, ip_finish_output2() always return -EINVAL, which may mislead the upper users.
For exemple, an application uses sendto to send an UDP packet, but when the neighbor table overflows, sendto() will get a value of -EINVAL, and it will cause users to waste a lot of time checking parameters for errors.
Return the real errno instead of -EINVAL.
Signed-off-by: xu xin xu.xin16@zte.com.cn Reviewed-by: Yang Yang yang.yang29@zte.com.cn Cc: Si Hao si.hao@zte.com.cn Reviewed-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Vadim Fedorenko vadim.fedorenko@linux.dev Link: https://lore.kernel.org/r/20230807015408.248237-1-xu.xin16@zte.com.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/ip_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index acfe58d2f1dd7..831c627e03ff8 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -234,7 +234,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s net_dbg_ratelimited("%s: No header cache and no neighbour!\n", __func__); kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL); - return -EINVAL; + return PTR_ERR(neigh); }
static int ip_finish_output_gso(struct net *net, struct sock *sk,
From: Mark O'Donovan shiftee@posteo.net
[ Upstream commit 9e47a758b70167c9301d2b44d2569f86c7796f2d ]
During NVMeTCP Authentication a controller can trigger a kernel oops by specifying the 8192 bit Diffie Hellman group and passing a correctly sized, but zeroed Diffie Hellamn value. mpi_cmp_ui() was detecting this if the second parameter was 0, but 1 is passed from dh_is_pubkey_valid(). This causes the null pointer u->d to be dereferenced towards the end of mpi_cmp_ui()
Signed-off-by: Mark O'Donovan shiftee@posteo.net Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- lib/mpi/mpi-cmp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/mpi/mpi-cmp.c b/lib/mpi/mpi-cmp.c index c4cfa3ff05818..0835b6213235e 100644 --- a/lib/mpi/mpi-cmp.c +++ b/lib/mpi/mpi-cmp.c @@ -25,8 +25,12 @@ int mpi_cmp_ui(MPI u, unsigned long v) mpi_limb_t limb = v;
mpi_normalize(u); - if (!u->nlimbs && !limb) - return 0; + if (u->nlimbs == 0) { + if (v == 0) + return 0; + else + return -1; + } if (u->sign) return -1; if (u->nlimbs > 1)
From: Ying Hsu yinghsu@chromium.org
[ Upstream commit 573ebae162111063eedc6c838a659ba628f66a0f ]
If hci_unregister_dev() frees the hci_dev object but hci_suspend_notifier may still be accessing it, it can cause the program to crash. Here's the call trace: <4>[102152.653246] Call Trace: <4>[102152.653254] hci_suspend_sync+0x109/0x301 [bluetooth] <4>[102152.653259] hci_suspend_dev+0x78/0xcd [bluetooth] <4>[102152.653263] hci_suspend_notifier+0x42/0x7a [bluetooth] <4>[102152.653268] notifier_call_chain+0x43/0x6b <4>[102152.653271] __blocking_notifier_call_chain+0x48/0x69 <4>[102152.653273] __pm_notifier_call_chain+0x22/0x39 <4>[102152.653276] pm_suspend+0x287/0x57c <4>[102152.653278] state_store+0xae/0xe5 <4>[102152.653281] kernfs_fop_write+0x109/0x173 <4>[102152.653284] __vfs_write+0x16f/0x1a2 <4>[102152.653287] ? selinux_file_permission+0xca/0x16f <4>[102152.653289] ? security_file_permission+0x36/0x109 <4>[102152.653291] vfs_write+0x114/0x21d <4>[102152.653293] __x64_sys_write+0x7b/0xdb <4>[102152.653296] do_syscall_64+0x59/0x194 <4>[102152.653299] entry_SYSCALL_64_after_hwframe+0x5c/0xc1
This patch holds the reference count of the hci_dev object while processing it in hci_suspend_notifier to avoid potential crash caused by the race condition.
Signed-off-by: Ying Hsu yinghsu@chromium.org Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_core.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d034bf2a999e1..146ad00ad1b9c 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2436,6 +2436,9 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) return NOTIFY_DONE;
+ /* To avoid a potential race with hci_unregister_dev. */ + hci_dev_hold(hdev); + if (action == PM_SUSPEND_PREPARE) ret = hci_suspend_dev(hdev); else if (action == PM_POST_SUSPEND) @@ -2445,6 +2448,7 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", action, ret);
+ hci_dev_put(hdev); return NOTIFY_DONE; }
From: Eric Dumazet edumazet@google.com
[ Upstream commit 8fe08d70a2b61b35a0a1235c78cf321e7528351f ]
sk_diag_put_flags(), netlink_setsockopt(), netlink_getsockopt() and others use nlk->flags without correct locking.
Use set_bit(), clear_bit(), test_bit(), assign_bit() to remove data-races.
Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Eric Dumazet edumazet@google.com Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/netlink/af_netlink.c | 90 ++++++++++++++-------------------------- net/netlink/af_netlink.h | 22 ++++++---- net/netlink/diag.c | 10 ++--- 3 files changed, 48 insertions(+), 74 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index ed123cf462afe..387e430a35ccc 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -84,7 +84,7 @@ struct listeners {
static inline int netlink_is_kernel(struct sock *sk) { - return nlk_sk(sk)->flags & NETLINK_F_KERNEL_SOCKET; + return nlk_test_bit(KERNEL_SOCKET, sk); }
struct netlink_table *nl_table __read_mostly; @@ -349,9 +349,7 @@ static void netlink_deliver_tap_kernel(struct sock *dst, struct sock *src,
static void netlink_overrun(struct sock *sk) { - struct netlink_sock *nlk = nlk_sk(sk); - - if (!(nlk->flags & NETLINK_F_RECV_NO_ENOBUFS)) { + if (!nlk_test_bit(RECV_NO_ENOBUFS, sk)) { if (!test_and_set_bit(NETLINK_S_CONGESTED, &nlk_sk(sk)->state)) { sk->sk_err = ENOBUFS; @@ -1391,9 +1389,7 @@ EXPORT_SYMBOL_GPL(netlink_has_listeners);
bool netlink_strict_get_check(struct sk_buff *skb) { - const struct netlink_sock *nlk = nlk_sk(NETLINK_CB(skb).sk); - - return nlk->flags & NETLINK_F_STRICT_CHK; + return nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk); } EXPORT_SYMBOL_GPL(netlink_strict_get_check);
@@ -1437,7 +1433,7 @@ static void do_one_broadcast(struct sock *sk, return;
if (!net_eq(sock_net(sk), p->net)) { - if (!(nlk->flags & NETLINK_F_LISTEN_ALL_NSID)) + if (!nlk_test_bit(LISTEN_ALL_NSID, sk)) return;
if (!peernet_has_id(sock_net(sk), p->net)) @@ -1470,7 +1466,7 @@ static void do_one_broadcast(struct sock *sk, netlink_overrun(sk); /* Clone failed. Notify ALL listeners. */ p->failure = 1; - if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) + if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) p->delivery_failure = 1; goto out; } @@ -1485,7 +1481,7 @@ static void do_one_broadcast(struct sock *sk, val = netlink_broadcast_deliver(sk, p->skb2); if (val < 0) { netlink_overrun(sk); - if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) + if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) p->delivery_failure = 1; } else { p->congested |= val; @@ -1565,7 +1561,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) !test_bit(p->group - 1, nlk->groups)) goto out;
- if (p->code == ENOBUFS && nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) { + if (p->code == ENOBUFS && nlk_test_bit(RECV_NO_ENOBUFS, sk)) { ret = 1; goto out; } @@ -1632,7 +1628,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; struct netlink_sock *nlk = nlk_sk(sk); unsigned int val = 0; - int err; + int nr = -1;
if (level != SOL_NETLINK) return -ENOPROTOOPT; @@ -1643,14 +1639,12 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
switch (optname) { case NETLINK_PKTINFO: - if (val) - nlk->flags |= NETLINK_F_RECV_PKTINFO; - else - nlk->flags &= ~NETLINK_F_RECV_PKTINFO; - err = 0; + nr = NETLINK_F_RECV_PKTINFO; break; case NETLINK_ADD_MEMBERSHIP: case NETLINK_DROP_MEMBERSHIP: { + int err; + if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) return -EPERM; err = netlink_realloc_groups(sk); @@ -1670,61 +1664,38 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) nlk->netlink_unbind(sock_net(sk), val);
- err = 0; break; } case NETLINK_BROADCAST_ERROR: - if (val) - nlk->flags |= NETLINK_F_BROADCAST_SEND_ERROR; - else - nlk->flags &= ~NETLINK_F_BROADCAST_SEND_ERROR; - err = 0; + nr = NETLINK_F_BROADCAST_SEND_ERROR; break; case NETLINK_NO_ENOBUFS: + assign_bit(NETLINK_F_RECV_NO_ENOBUFS, &nlk->flags, val); if (val) { - nlk->flags |= NETLINK_F_RECV_NO_ENOBUFS; clear_bit(NETLINK_S_CONGESTED, &nlk->state); wake_up_interruptible(&nlk->wait); - } else { - nlk->flags &= ~NETLINK_F_RECV_NO_ENOBUFS; } - err = 0; break; case NETLINK_LISTEN_ALL_NSID: if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_BROADCAST)) return -EPERM; - - if (val) - nlk->flags |= NETLINK_F_LISTEN_ALL_NSID; - else - nlk->flags &= ~NETLINK_F_LISTEN_ALL_NSID; - err = 0; + nr = NETLINK_F_LISTEN_ALL_NSID; break; case NETLINK_CAP_ACK: - if (val) - nlk->flags |= NETLINK_F_CAP_ACK; - else - nlk->flags &= ~NETLINK_F_CAP_ACK; - err = 0; + nr = NETLINK_F_CAP_ACK; break; case NETLINK_EXT_ACK: - if (val) - nlk->flags |= NETLINK_F_EXT_ACK; - else - nlk->flags &= ~NETLINK_F_EXT_ACK; - err = 0; + nr = NETLINK_F_EXT_ACK; break; case NETLINK_GET_STRICT_CHK: - if (val) - nlk->flags |= NETLINK_F_STRICT_CHK; - else - nlk->flags &= ~NETLINK_F_STRICT_CHK; - err = 0; + nr = NETLINK_F_STRICT_CHK; break; default: - err = -ENOPROTOOPT; + return -ENOPROTOOPT; } - return err; + if (nr >= 0) + assign_bit(nr, &nlk->flags, val); + return 0; }
static int netlink_getsockopt(struct socket *sock, int level, int optname, @@ -1791,7 +1762,7 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, return -EINVAL;
len = sizeof(int); - val = nlk->flags & flag ? 1 : 0; + val = test_bit(flag, &nlk->flags);
if (put_user(len, optlen) || copy_to_user(optval, &val, len)) @@ -1968,9 +1939,9 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, msg->msg_namelen = sizeof(*addr); }
- if (nlk->flags & NETLINK_F_RECV_PKTINFO) + if (nlk_test_bit(RECV_PKTINFO, sk)) netlink_cmsg_recv_pktinfo(msg, skb); - if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID) + if (nlk_test_bit(LISTEN_ALL_NSID, sk)) netlink_cmsg_listen_all_nsid(sk, msg, skb);
memset(&scm, 0, sizeof(scm)); @@ -2047,7 +2018,7 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module, goto out_sock_release;
nlk = nlk_sk(sk); - nlk->flags |= NETLINK_F_KERNEL_SOCKET; + set_bit(NETLINK_F_KERNEL_SOCKET, &nlk->flags);
netlink_table_grab(); if (!nl_table[unit].registered) { @@ -2183,7 +2154,7 @@ static int netlink_dump_done(struct netlink_sock *nlk, struct sk_buff *skb, nl_dump_check_consistent(cb, nlh); memcpy(nlmsg_data(nlh), &nlk->dump_done_errno, sizeof(nlk->dump_done_errno));
- if (extack->_msg && nlk->flags & NETLINK_F_EXT_ACK) { + if (extack->_msg && test_bit(NETLINK_F_EXT_ACK, &nlk->flags)) { nlh->nlmsg_flags |= NLM_F_ACK_TLVS; if (!nla_put_string(skb, NLMSGERR_ATTR_MSG, extack->_msg)) nlmsg_end(skb, nlh); @@ -2312,8 +2283,8 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, const struct nlmsghdr *nlh, struct netlink_dump_control *control) { - struct netlink_sock *nlk, *nlk2; struct netlink_callback *cb; + struct netlink_sock *nlk; struct sock *sk; int ret;
@@ -2348,8 +2319,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, cb->min_dump_alloc = control->min_dump_alloc; cb->skb = skb;
- nlk2 = nlk_sk(NETLINK_CB(skb).sk); - cb->strict_check = !!(nlk2->flags & NETLINK_F_STRICT_CHK); + cb->strict_check = nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk);
if (control->start) { ret = control->start(cb); @@ -2391,7 +2361,7 @@ netlink_ack_tlv_len(struct netlink_sock *nlk, int err, { size_t tlvlen;
- if (!extack || !(nlk->flags & NETLINK_F_EXT_ACK)) + if (!extack || !test_bit(NETLINK_F_EXT_ACK, &nlk->flags)) return 0;
tlvlen = 0; @@ -2463,7 +2433,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, * requests to cap the error message, and get extra error data if * requested. */ - if (err && !(nlk->flags & NETLINK_F_CAP_ACK)) + if (err && !test_bit(NETLINK_F_CAP_ACK, &nlk->flags)) payload += nlmsg_len(nlh); else flags |= NLM_F_CAPPED; diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h index 5f454c8de6a4d..b30b8fc760f71 100644 --- a/net/netlink/af_netlink.h +++ b/net/netlink/af_netlink.h @@ -8,14 +8,16 @@ #include <net/sock.h>
/* flags */ -#define NETLINK_F_KERNEL_SOCKET 0x1 -#define NETLINK_F_RECV_PKTINFO 0x2 -#define NETLINK_F_BROADCAST_SEND_ERROR 0x4 -#define NETLINK_F_RECV_NO_ENOBUFS 0x8 -#define NETLINK_F_LISTEN_ALL_NSID 0x10 -#define NETLINK_F_CAP_ACK 0x20 -#define NETLINK_F_EXT_ACK 0x40 -#define NETLINK_F_STRICT_CHK 0x80 +enum { + NETLINK_F_KERNEL_SOCKET, + NETLINK_F_RECV_PKTINFO, + NETLINK_F_BROADCAST_SEND_ERROR, + NETLINK_F_RECV_NO_ENOBUFS, + NETLINK_F_LISTEN_ALL_NSID, + NETLINK_F_CAP_ACK, + NETLINK_F_EXT_ACK, + NETLINK_F_STRICT_CHK, +};
#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) #define NLGRPLONGS(x) (NLGRPSZ(x)/sizeof(unsigned long)) @@ -23,10 +25,10 @@ struct netlink_sock { /* struct sock has to be the first member of netlink_sock */ struct sock sk; + unsigned long flags; u32 portid; u32 dst_portid; u32 dst_group; - u32 flags; u32 subscriptions; u32 ngroups; unsigned long *groups; @@ -54,6 +56,8 @@ static inline struct netlink_sock *nlk_sk(struct sock *sk) return container_of(sk, struct netlink_sock, sk); }
+#define nlk_test_bit(nr, sk) test_bit(NETLINK_F_##nr, &nlk_sk(sk)->flags) + struct netlink_table { struct rhashtable hash; struct hlist_head mc_list; diff --git a/net/netlink/diag.c b/net/netlink/diag.c index e4f21b1067bcc..9c4f231be2757 100644 --- a/net/netlink/diag.c +++ b/net/netlink/diag.c @@ -27,15 +27,15 @@ static int sk_diag_put_flags(struct sock *sk, struct sk_buff *skb)
if (nlk->cb_running) flags |= NDIAG_FLAG_CB_RUNNING; - if (nlk->flags & NETLINK_F_RECV_PKTINFO) + if (nlk_test_bit(RECV_PKTINFO, sk)) flags |= NDIAG_FLAG_PKTINFO; - if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) + if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) flags |= NDIAG_FLAG_BROADCAST_ERROR; - if (nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) + if (nlk_test_bit(RECV_NO_ENOBUFS, sk)) flags |= NDIAG_FLAG_NO_ENOBUFS; - if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID) + if (nlk_test_bit(LISTEN_ALL_NSID, sk)) flags |= NDIAG_FLAG_LISTEN_ALL_NSID; - if (nlk->flags & NETLINK_F_CAP_ACK) + if (nlk_test_bit(CAP_ACK, sk)) flags |= NDIAG_FLAG_CAP_ACK;
return nla_put_u32(skb, NETLINK_DIAG_FLAGS, flags);
From: Alexander Steffen Alexander.Steffen@infineon.com
[ Upstream commit 280db21e153d8810ce3b93640c63ae922bcb9e8e ]
Similar to the transmission of TPM responses, also the transmission of TPM commands may become corrupted. Instead of aborting when detecting such issues, try resending the command again.
Signed-off-by: Alexander Steffen Alexander.Steffen@infineon.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_core.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 44f71f2c8cfa0..5889d9edaf940 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -498,10 +498,17 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len) int rc; u32 ordinal; unsigned long dur; + unsigned int try;
- rc = tpm_tis_send_data(chip, buf, len); - if (rc < 0) - return rc; + for (try = 0; try < TPM_RETRY; try++) { + rc = tpm_tis_send_data(chip, buf, len); + if (rc >= 0) + /* Data transfer done successfully */ + break; + else if (rc != -EIO) + /* Data transfer failed, not recoverable */ + return rc; + }
rc = tpm_tis_verify_crc(priv, len, buf); if (rc < 0) {
From: Giulio Benetti giulio.benetti@benettiengineering.com
[ Upstream commit 5ae4b0d8875caa44946e579420c7fd5740d58653 ]
Errata ERR010450 only shows up if voltage is 1.8V, but if the device is supplied by 3v3 the errata can be ignored. So let's check for if quirk SDHCI_QUIRK2_NO_1_8_V is defined or not before limiting the frequency.
Cc: Jim Reinhart jimr@tekvox.com Cc: James Autry jautry@tekvox.com Cc: Matthew Maron matthewm@tekvox.com Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com Acked-by: Haibo Chen haibo.chen@nxp.com Acked-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/20230811214853.8623-1-giulio.benetti@benettiengine... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-esdhc-imx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index b63cf1f9e8fb9..3c7b32c0d3f3f 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -171,8 +171,8 @@ #define ESDHC_FLAG_HS400 BIT(9) /* * The IP has errata ERR010450 - * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't - * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. + * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card + * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. */ #define ESDHC_FLAG_ERR010450 BIT(10) /* The IP supports HS400ES mode */ @@ -932,7 +932,8 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host, | ESDHC_CLOCK_MASK); sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
- if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) { + if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) && + (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) { unsigned int max_clock;
max_clock = imx_data->is_ddr ? 45000000 : 150000000;
From: "GONG, Ruiqi" gongruiqi1@huawei.com
[ Upstream commit 3a198c95c95da10ad844cbeade2fe40bdf14c411 ]
The following message shows up when compiling with W=1:
In function ‘fortify_memcpy_chk’, inlined from ‘alx_get_ethtool_stats’ at drivers/net/ethernet/atheros/alx/ethtool.c:297:2: ./include/linux/fortify-string.h:592:4: error: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror=attribute-warning] 592 | __read_overflow2_field(q_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to get alx stats altogether, alx_get_ethtool_stats() reads beyond hw->stats.rx_ok. Fix this warning by directly copying hw->stats, and refactor the unnecessarily complicated BUILD_BUG_ON btw.
Signed-off-by: GONG, Ruiqi gongruiqi1@huawei.com Reviewed-by: Simon Horman horms@kernel.org Link: https://lore.kernel.org/r/20230821013218.1614265-1-gongruiqi@huaweicloud.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/atheros/alx/ethtool.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c index b716adacd8159..7f6b69a523676 100644 --- a/drivers/net/ethernet/atheros/alx/ethtool.c +++ b/drivers/net/ethernet/atheros/alx/ethtool.c @@ -292,9 +292,8 @@ static void alx_get_ethtool_stats(struct net_device *netdev, spin_lock(&alx->stats_lock);
alx_update_hw_stats(hw); - BUILD_BUG_ON(sizeof(hw->stats) - offsetof(struct alx_hw_stats, rx_ok) < - ALX_NUM_STATS * sizeof(u64)); - memcpy(data, &hw->stats.rx_ok, ALX_NUM_STATS * sizeof(u64)); + BUILD_BUG_ON(sizeof(hw->stats) != ALX_NUM_STATS * sizeof(u64)); + memcpy(data, &hw->stats, sizeof(hw->stats));
spin_unlock(&alx->stats_lock); }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 19e4a47ee74718a22e963e8a647c8c3bfe8bb05c ]
Before checking the action code, check that it even exists in the frame.
Reported-by: syzbot+be9c824e6f269d608288@syzkaller.appspotmail.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/rx.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0f81492da0b46..3bebf28ea7464 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3623,6 +3623,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) break; goto queue; case WLAN_CATEGORY_S1G: + if (len < offsetofend(typeof(*mgmt), + u.action.u.s1g.action_code)) + break; + switch (mgmt->u.action.u.s1g.action_code) { case WLAN_S1G_TWT_SETUP: case WLAN_S1G_TWT_TEARDOWN:
From: "GONG, Ruiqi" gongruiqi1@huawei.com
[ Upstream commit a7ed3465daa240bdf01a5420f64336fee879c09d ]
When compiling with gcc 13 and CONFIG_FORTIFY_SOURCE=y, the following warning appears:
In function ‘fortify_memcpy_chk’, inlined from ‘size_entry_mwt’ at net/bridge/netfilter/ebtables.c:2118:2: ./include/linux/fortify-string.h:592:25: error: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror=attribute-warning] 592 | __read_overflow2_field(q_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The compiler is complaining:
memcpy(&offsets[1], &entry->watchers_offset, sizeof(offsets) - sizeof(offsets[0]));
where memcpy reads beyong &entry->watchers_offset to copy {watchers,target,next}_offset altogether into offsets[]. Silence the warning by wrapping these three up via struct_group().
Signed-off-by: GONG, Ruiqi gongruiqi1@huawei.com Reviewed-by: Gustavo A. R. Silva gustavoars@kernel.org Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/uapi/linux/netfilter_bridge/ebtables.h | 14 ++++++++------ net/bridge/netfilter/ebtables.c | 3 +-- 2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h index a494cf43a7552..b0caad82b6937 100644 --- a/include/uapi/linux/netfilter_bridge/ebtables.h +++ b/include/uapi/linux/netfilter_bridge/ebtables.h @@ -182,12 +182,14 @@ struct ebt_entry { unsigned char sourcemsk[ETH_ALEN]; unsigned char destmac[ETH_ALEN]; unsigned char destmsk[ETH_ALEN]; - /* sizeof ebt_entry + matches */ - unsigned int watchers_offset; - /* sizeof ebt_entry + matches + watchers */ - unsigned int target_offset; - /* sizeof ebt_entry + matches + watchers + target */ - unsigned int next_offset; + __struct_group(/* no tag */, offsets, /* no attrs */, + /* sizeof ebt_entry + matches */ + unsigned int watchers_offset; + /* sizeof ebt_entry + matches + watchers */ + unsigned int target_offset; + /* sizeof ebt_entry + matches + watchers + target */ + unsigned int next_offset; + ); unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); };
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 757ec46fc45a0..aa23479b20b2a 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -2115,8 +2115,7 @@ static int size_entry_mwt(const struct ebt_entry *entry, const unsigned char *ba return ret;
offsets[0] = sizeof(struct ebt_entry); /* matches come first */ - memcpy(&offsets[1], &entry->watchers_offset, - sizeof(offsets) - sizeof(offsets[0])); + memcpy(&offsets[1], &entry->offsets, sizeof(entry->offsets));
if (state->buf_kern_start) { buf_start = state->buf_kern_start + state->buf_kern_offset;
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 5d4e04bf3a0f098bd9033de3a5291810fa14c7a6 ]
If the AP uses our own address as its MLD address or BSSID, then clearly something's wrong. Reject such connections so we don't try and fail later.
Reported-by: syzbot+2676771ed06a6df166ad@syzkaller.appspotmail.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/mlme.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 581df7f4c5240..e7fa0608341d8 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -277,6 +277,11 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, ether_addr_equal(req->bss->bssid, wdev->u.client.connected_addr)) return -EALREADY;
+ if (ether_addr_equal(req->bss->bssid, dev->dev_addr) || + (req->link_id >= 0 && + ether_addr_equal(req->ap_mld_addr, dev->dev_addr))) + return -EINVAL; + return rdev_auth(rdev, dev, req); }
@@ -331,6 +336,9 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, if (req->links[i].bss == req->links[j].bss) return -EINVAL; } + + if (ether_addr_equal(req->links[i].bss->bssid, dev->dev_addr)) + return -EINVAL; }
if (wdev->connected && @@ -338,6 +346,11 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, !ether_addr_equal(wdev->u.client.connected_addr, req->prev_bssid))) return -EALREADY;
+ if ((req->bss && ether_addr_equal(req->bss->bssid, dev->dev_addr)) || + (req->link_id >= 0 && + ether_addr_equal(req->ap_mld_addr, dev->dev_addr))) + return -EINVAL; + cfg80211_oper_and_ht_capa(&req->ht_capa_mask, rdev->wiphy.ht_capa_mod_mask); cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit abc76cf552e13cfa88a204b362a86b0e08e95228 ]
If there's no OCB state, don't ask the driver/mac80211 to leave, since that's just confusing. Since set/clear the chandef state, that's a simple check.
Reported-by: syzbot+09d1cd2f71e6dd3bfd2c@syzkaller.appspotmail.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/ocb.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/wireless/ocb.c b/net/wireless/ocb.c index 27a1732264f95..29afaf3da54f3 100644 --- a/net/wireless/ocb.c +++ b/net/wireless/ocb.c @@ -68,6 +68,9 @@ int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, if (!rdev->ops->leave_ocb) return -EOPNOTSUPP;
+ if (!wdev->u.ocb.chandef.chan) + return -ENOTCONN; + err = rdev_leave_ocb(rdev, dev); if (!err) memset(&wdev->u.ocb.chandef, 0, sizeof(wdev->u.ocb.chandef));
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 67dfa589aa8806c7959cbca2f4613b8d41c75a06 ]
When probing a client, first check if we have it, and then check for the channel context, otherwise you can trigger the warning there easily by probing when the AP isn't even started yet. Since a client existing means the AP is also operating, we can then keep the warning.
Also simplify the moved code a bit.
Reported-by: syzbot+999fac712d84878a7379@syzkaller.appspotmail.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/cfg.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 23a44edcb11f7..cf3453b532d67 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3991,19 +3991,20 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, mutex_lock(&local->mtx);
rcu_read_lock(); + sta = sta_info_get_bss(sdata, peer); + if (!sta) { + ret = -ENOLINK; + goto unlock; + } + + qos = sta->sta.wme; + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { ret = -EINVAL; goto unlock; } band = chanctx_conf->def.chan->band; - sta = sta_info_get_bss(sdata, peer); - if (sta) { - qos = sta->sta.wme; - } else { - ret = -ENOLINK; - goto unlock; - }
if (qos) { fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit fba360a047d5eeeb9d4b7c3a9b1c8308980ce9a6 ]
While technically some control frames like ACK are shorter and end after Address 1, such frames shouldn't be forwarded through wmediumd or similar userspace, so require the full 3-address header to avoid accessing invalid memory if shorter frames are passed in.
Reported-by: syzbot+b2645b5bf1512b81fa22@syzkaller.appspotmail.com Reviewed-by: Jeff Johnson quic_jjohnson@quicinc.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mac80211_hwsim.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index da5c355405f68..db70cef854bc4 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -4906,14 +4906,15 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]); frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
+ if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) || + frame_data_len > IEEE80211_MAX_DATA_LEN) + goto err; + /* Allocate new skb here */ skb = alloc_skb(frame_data_len, GFP_KERNEL); if (skb == NULL) goto err;
- if (frame_data_len > IEEE80211_MAX_DATA_LEN) - goto err; - /* Copy the data */ skb_put_data(skb, frame_data, frame_data_len);
From: Hao Luo haoluo@google.com
[ Upstream commit 29d67fdebc42af6466d1909c60fdd1ef4f3e5240 ]
I hit a memory leak when testing bpf_program__set_attach_target(). Basically, set_attach_target() may allocate btf_vmlinux, for example, when setting attach target for bpf_iter programs. But btf_vmlinux is freed only in bpf_object_load(), which means if we only open bpf object but not load it, setting attach target may leak btf_vmlinux.
So let's free btf_vmlinux in bpf_object__close() anyway.
Signed-off-by: Hao Luo haoluo@google.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20230822193840.1509809-1-haoluo@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index b9a29d1053765..383e93d699bf4 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8169,6 +8169,7 @@ void bpf_object__close(struct bpf_object *obj) bpf_object__elf_finish(obj); bpf_object_unload(obj); btf__free(obj->btf); + btf__free(obj->btf_vmlinux); btf_ext__free(obj->btf_ext);
for (i = 0; i < obj->nr_maps; i++)
From: Bastien Nocera hadess@hadess.net
[ Upstream commit d831e3612111d385e8629104af5429808ef26e25 ]
The quirks table was named "blacklist_table" which isn't a good description for that table as devices detected using it weren't ignored by the driver.
Rename the table to match what it actually does.
Signed-off-by: Bastien Nocera hadess@hadess.net Reviewed-by: Paul Menzel pmenzel@molgen.mpg.de Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index d6f405763c56f..7bb774457e129 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -174,7 +174,7 @@ static const struct usb_device_id btusb_table[] = {
MODULE_DEVICE_TABLE(usb, btusb_table);
-static const struct usb_device_id blacklist_table[] = { +static const struct usb_device_id quirks_table[] = { /* CSR BlueCore devices */ { USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
@@ -3767,7 +3767,7 @@ static int btusb_probe(struct usb_interface *intf, if (!id->driver_info) { const struct usb_device_id *match;
- match = usb_match_id(intf, blacklist_table); + match = usb_match_id(intf, quirks_table); if (match) id = match; }
On 9/8/2023 11:17 AM, Sasha Levin wrote:
From: Jiri Pirko jiri@nvidia.com
[ Upstream commit 633d76ad01ad0321a1ace3e5cc4fed06753d7ac4 ]
The checks in question were introduced by: commit 6b4db2e528f6 ("devlink: Fix use-after-free after a failed reload"). That fixed an issue of reload with mlxsw driver.
Back then, that was a valid fix, because there was a limitation in place that prevented drivers from registering/unregistering params when devlink instance was registered.
It was possible to do the fix differently by changing drivers to register/unregister params in appropriate places making sure the ops operate only on memory which is allocated and initialized. But that, as a dependency, would require to remove the limitation mentioned above.
Eventually, this limitation was lifted by: commit 1d18bb1a4ddd ("devlink: allow registering parameters after the instance")
Also, the alternative fix (which also fixed another issue) was done by: commit 74cbc3c03c82 ("mlxsw: spectrum_acl_tcam: Move devlink param to TCAM code").
Therefore, the checks are no longer relevant. Each driver should make sure to have the params registered only when the memory the ops are working with is allocated and initialized.
So remove the checks.
Signed-off-by: Jiri Pirko jiri@nvidia.com Reviewed-by: Ido Schimmel idosch@nvidia.com Reviewed-by: Jakub Kicinski kuba@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org
I believe my comments on the v5.4 backport apply here as well.
Thanks, Jake
linux-stable-mirror@lists.linaro.org