diff options
Diffstat (limited to 'SOURCES/patch-5.19-redhat.patch')
-rw-r--r-- | SOURCES/patch-5.19-redhat.patch | 545 |
1 files changed, 541 insertions, 4 deletions
diff --git a/SOURCES/patch-5.19-redhat.patch b/SOURCES/patch-5.19-redhat.patch index 64174be..2012e45 100644 --- a/SOURCES/patch-5.19-redhat.patch +++ b/SOURCES/patch-5.19-redhat.patch @@ -33,6 +33,7 @@ drivers/gpu/drm/v3d/v3d_debugfs.c | 18 +- drivers/gpu/drm/v3d/v3d_drv.c | 12 +- drivers/gpu/drm/v3d/v3d_gem.c | 12 +- + drivers/gpu/drm/vc4/vc4_hdmi.c | 29 + drivers/hid/hid-rmi.c | 64 -- drivers/hwtracing/coresight/coresight-etm4x-core.c | 19 + drivers/input/rmi4/rmi_driver.c | 124 +-- @@ -43,7 +44,10 @@ drivers/net/phy/bcm-phy-lib.h | 19 + drivers/net/phy/bcm-phy-ptp.c | 944 +++++++++++++++++++++ drivers/net/phy/broadcom.c | 33 +- + drivers/net/wireless/mac80211_hwsim.c | 2 + drivers/pci/quirks.c | 24 + + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 10 +- + drivers/scsi/stex.c | 17 +- drivers/soc/bcm/bcm2835-power.c | 72 +- drivers/usb/core/hub.c | 7 + include/linux/efi.h | 22 +- @@ -52,16 +56,25 @@ include/linux/mfd/bcm2835-pm.h | 1 + include/linux/rmi.h | 1 + include/linux/security.h | 5 + + include/scsi/scsi_cmnd.h | 2 +- init/Kconfig | 2 +- kernel/module/signing.c | 9 +- net/bluetooth/hci_event.c | 20 + + net/ipv4/fib_semantics.c | 8 +- + net/mac80211/ieee80211_i.h | 8 + + net/mac80211/rx.c | 12 +- + net/mac80211/util.c | 34 +- + net/mctp/af_mctp.c | 23 +- + net/mctp/route.c | 10 +- + net/wireless/scan.c | 77 +- scripts/pahole-flags.sh | 4 + scripts/tags.sh | 2 + security/integrity/platform_certs/load_uefi.c | 6 +- security/lockdown/Kconfig | 13 + security/lockdown/lockdown.c | 1 + security/security.c | 6 + - 63 files changed, 1779 insertions(+), 348 deletions(-) + tools/testing/selftests/net/fib_nexthops.sh | 5 + + 76 files changed, 1939 insertions(+), 425 deletions(-) diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml index e6485f7b046f..217c42874f41 100644 @@ -253,7 +266,7 @@ index 000000000000..733a26bd887a + +endmenu diff --git a/Makefile b/Makefile -index ff4a15867145..975c3f82db13 100644 +index af05237987ef..ec594b2177f0 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,10 @@ $(if $(filter __%, $(MAKECMDGOALS)), \ @@ -1296,6 +1309,59 @@ index 2352e9640922..725a252e837b 100644 fail: kfree(*container); *container = NULL; +diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c +index 199bc398817f..eb3aaaca2b80 100644 +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -2889,12 +2889,37 @@ static int vc4_hdmi_runtime_resume(struct device *dev) + struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); + unsigned long __maybe_unused flags; + u32 __maybe_unused value; ++ unsigned long rate; + int ret; + ++ /* ++ * The HSM clock is in the HDMI power domain, so we need to set ++ * its frequency while the power domain is active so that it ++ * keeps its rate. ++ */ ++ ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ); ++ if (ret) ++ return ret; ++ + ret = clk_prepare_enable(vc4_hdmi->hsm_clock); + if (ret) + return ret; + ++ /* ++ * Whenever the RaspberryPi boots without an HDMI monitor ++ * plugged in, the firmware won't have initialized the HSM clock ++ * rate and it will be reported as 0. ++ * ++ * If we try to access a register of the controller in such a ++ * case, it will lead to a silent CPU stall. Let's make sure we ++ * prevent such a case. ++ */ ++ rate = clk_get_rate(vc4_hdmi->hsm_clock); ++ if (!rate) { ++ ret = -EINVAL; ++ goto err_disable_clk; ++ } ++ + if (vc4_hdmi->variant->reset) + vc4_hdmi->variant->reset(vc4_hdmi); + +@@ -2916,6 +2941,10 @@ static int vc4_hdmi_runtime_resume(struct device *dev) + #endif + + return 0; ++ ++err_disable_clk: ++ clk_disable_unprepare(vc4_hdmi->hsm_clock); ++ return ret; + } + + static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 311eee599ce9..2460c6bd46f8 100644 --- a/drivers/hid/hid-rmi.c @@ -2881,6 +2947,19 @@ index e36809aa6d30..876bc45ede60 100644 return 0; } +diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c +index b511e705a46e..6c81422fd226 100644 +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -4251,6 +4251,8 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, + + rx_status.band = channel->band; + rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); ++ if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates) ++ goto out; + rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); + + hdr = (void *)skb->data; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2e68f50bc7ae..00e1d5bc83a5 100644 --- a/drivers/pci/quirks.c @@ -2916,6 +2995,68 @@ index 2e68f50bc7ae..00e1d5bc83a5 100644 /* * Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero) * class code. Fix it. +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 5223d4c9afdf..39f14a5b78cd 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1124,7 +1124,7 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, + struct rockchip_usb2phy_port *rport, + struct device_node *child_np) + { +- int ret; ++ int ret, id; + + rport->port_id = USB2PHY_PORT_OTG; + rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG]; +@@ -1162,13 +1162,15 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, + + ret = devm_extcon_register_notifier(rphy->dev, rphy->edev, + EXTCON_USB_HOST, &rport->event_nb); +- if (ret) ++ if (ret) { + dev_err(rphy->dev, "register USB HOST notifier failed\n"); ++ goto out; ++ } + + if (!of_property_read_bool(rphy->dev->of_node, "extcon")) { + /* do initial sync of usb state */ +- ret = property_enabled(rphy->grf, &rport->port_cfg->utmi_id); +- extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !ret); ++ id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id); ++ extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id); + } + } + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index e6420f2127ce..8def242675ef 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -665,16 +665,17 @@ static int stex_queuecommand_lck(struct scsi_cmnd *cmd) + return 0; + case PASSTHRU_CMD: + if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { +- struct st_drvver ver; ++ const struct st_drvver ver = { ++ .major = ST_VER_MAJOR, ++ .minor = ST_VER_MINOR, ++ .oem = ST_OEM, ++ .build = ST_BUILD_VER, ++ .signature[0] = PASSTHRU_SIGNATURE, ++ .console_id = host->max_id - 1, ++ .host_no = hba->host->host_no, ++ }; + size_t cp_len = sizeof(ver); + +- ver.major = ST_VER_MAJOR; +- ver.minor = ST_VER_MINOR; +- ver.oem = ST_OEM; +- ver.build = ST_BUILD_VER; +- ver.signature[0] = PASSTHRU_SIGNATURE; +- ver.console_id = host->max_id - 1; +- ver.host_no = hba->host->host_no; + cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len); + if (sizeof(ver) == cp_len) + cmd->result = DID_OK << 16; diff --git a/drivers/soc/bcm/bcm2835-power.c b/drivers/soc/bcm/bcm2835-power.c index 1e0041ec8132..5bcd047768b6 100644 --- a/drivers/soc/bcm/bcm2835-power.c @@ -3217,6 +3358,19 @@ index 3cc127bb5bfd..2fecdfb03eb5 100644 #endif /* CONFIG_SECURITY */ #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE) +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index 1e80e70dfa92..5ce1aac64edd 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -201,7 +201,7 @@ static inline unsigned int scsi_get_resid(struct scsi_cmnd *cmd) + for_each_sg(scsi_sglist(cmd), sg, nseg, __i) + + static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd, +- void *buf, int buflen) ++ const void *buf, int buflen) + { + return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + buf, buflen); diff --git a/init/Kconfig b/init/Kconfig index c7900e8975f1..ea721c12c251 100644 --- a/init/Kconfig @@ -3254,10 +3408,10 @@ index a2ff4242e623..f0d2be1ee4f1 100644 int module_sig_check(struct load_info *info, int flags) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c -index 2c320a8fe70d..e097bf4ce549 100644 +index 81e5bcdbbe94..ff74e2a55e8f 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c -@@ -3997,6 +3997,26 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data, +@@ -3999,6 +3999,26 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data, break; } } @@ -3284,6 +3438,373 @@ index 2c320a8fe70d..e097bf4ce549 100644 if (i == ARRAY_SIZE(hci_cc_table)) { /* Unknown opcode, assume byte 0 contains the status, so +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index db7b2503f068..36653cd5964a 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -888,13 +888,13 @@ int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi, + return 1; + } + ++ /* cannot match on nexthop object attributes */ ++ if (fi->nh) ++ return 1; ++ + if (cfg->fc_oif || cfg->fc_gw_family) { + struct fib_nh *nh; + +- /* cannot match on nexthop object attributes */ +- if (fi->nh) +- return 1; +- + nh = fib_info_nh(fi, 0); + if (cfg->fc_encap) { + if (fib_encap_match(net, cfg->fc_encap_type, +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 48fbccbf2a54..44c8701af95c 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1640,6 +1640,14 @@ struct ieee802_11_elems { + + /* whether a parse error occurred while retrieving these elements */ + bool parse_error; ++ ++ /* ++ * scratch buffer that can be used for various element parsing related ++ * tasks, e.g., element de-fragmentation etc. ++ */ ++ size_t scratch_len; ++ u8 *scratch_pos; ++ u8 scratch[]; + }; + + static inline struct ieee80211_local *hw_to_local( +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index b938806a5184..2d584a86dbf3 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1988,10 +1988,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + + if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS || + mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + +- NUM_DEFAULT_BEACON_KEYS) { +- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, +- skb->data, +- skb->len); ++ NUM_DEFAULT_BEACON_KEYS) { ++ if (rx->sdata->dev) ++ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, ++ skb->data, ++ skb->len); + return RX_DROP_MONITOR; /* unexpected BIP keyidx */ + } + +@@ -2139,7 +2140,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + /* either the frame has been decrypted or will be dropped */ + status->flag |= RX_FLAG_DECRYPTED; + +- if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE)) ++ if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE && ++ rx->sdata->dev)) + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, + skb->data, skb->len); + +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 3f698e508dd7..8f36ab8fcfb2 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1439,6 +1439,8 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) { + if (elem->datalen < 2) + continue; ++ if (elem->data[0] < 1 || elem->data[0] > 8) ++ continue; + + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 new_bssid[ETH_ALEN]; +@@ -1501,25 +1503,27 @@ struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, + const struct element *non_inherit = NULL; + u8 *nontransmitted_profile; + int nontransmitted_profile_len = 0; ++ size_t scratch_len = len; + +- elems = kzalloc(sizeof(*elems), GFP_ATOMIC); ++ elems = kzalloc(sizeof(*elems) + scratch_len, GFP_ATOMIC); + if (!elems) + return NULL; + elems->ie_start = start; + elems->total_len = len; +- +- nontransmitted_profile = kmalloc(len, GFP_ATOMIC); +- if (nontransmitted_profile) { +- nontransmitted_profile_len = +- ieee802_11_find_bssid_profile(start, len, elems, +- transmitter_bssid, +- bss_bssid, +- nontransmitted_profile); +- non_inherit = +- cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, +- nontransmitted_profile, +- nontransmitted_profile_len); +- } ++ elems->scratch_len = scratch_len; ++ elems->scratch_pos = elems->scratch; ++ ++ nontransmitted_profile = elems->scratch_pos; ++ nontransmitted_profile_len = ++ ieee802_11_find_bssid_profile(start, len, elems, ++ transmitter_bssid, ++ bss_bssid, ++ nontransmitted_profile); ++ elems->scratch_pos += nontransmitted_profile_len; ++ elems->scratch_len -= nontransmitted_profile_len; ++ non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, ++ nontransmitted_profile, ++ nontransmitted_profile_len); + + crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter, + crc, non_inherit); +@@ -1548,8 +1552,6 @@ struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, + offsetofend(struct ieee80211_bssid_index, dtim_count)) + elems->dtim_count = elems->bssid_index->dtim_count; + +- kfree(nontransmitted_profile); +- + elems->crc = crc; + + return elems; +diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c +index c2fc2a7b2528..b6b5e496fa40 100644 +--- a/net/mctp/af_mctp.c ++++ b/net/mctp/af_mctp.c +@@ -295,11 +295,12 @@ __must_hold(&net->mctp.keys_lock) + mctp_dev_release_key(key->dev, key); + spin_unlock_irqrestore(&key->lock, flags); + +- hlist_del(&key->hlist); +- hlist_del(&key->sklist); +- +- /* unref for the lists */ +- mctp_key_unref(key); ++ if (!hlist_unhashed(&key->hlist)) { ++ hlist_del_init(&key->hlist); ++ hlist_del_init(&key->sklist); ++ /* unref for the lists */ ++ mctp_key_unref(key); ++ } + + kfree_skb(skb); + } +@@ -373,9 +374,17 @@ static int mctp_ioctl_alloctag(struct mctp_sock *msk, unsigned long arg) + + ctl.tag = tag | MCTP_TAG_OWNER | MCTP_TAG_PREALLOC; + if (copy_to_user((void __user *)arg, &ctl, sizeof(ctl))) { +- spin_lock_irqsave(&key->lock, flags); +- __mctp_key_remove(key, net, flags, MCTP_TRACE_KEY_DROPPED); ++ unsigned long fl2; ++ /* Unwind our key allocation: the keys list lock needs to be ++ * taken before the individual key locks, and we need a valid ++ * flags value (fl2) to pass to __mctp_key_remove, hence the ++ * second spin_lock_irqsave() rather than a plain spin_lock(). ++ */ ++ spin_lock_irqsave(&net->mctp.keys_lock, flags); ++ spin_lock_irqsave(&key->lock, fl2); ++ __mctp_key_remove(key, net, fl2, MCTP_TRACE_KEY_DROPPED); + mctp_key_unref(key); ++ spin_unlock_irqrestore(&net->mctp.keys_lock, flags); + return -EFAULT; + } + +diff --git a/net/mctp/route.c b/net/mctp/route.c +index 3b24b8d18b5b..2155f15a074c 100644 +--- a/net/mctp/route.c ++++ b/net/mctp/route.c +@@ -228,12 +228,12 @@ __releases(&key->lock) + + if (!key->manual_alloc) { + spin_lock_irqsave(&net->mctp.keys_lock, flags); +- hlist_del(&key->hlist); +- hlist_del(&key->sklist); ++ if (!hlist_unhashed(&key->hlist)) { ++ hlist_del_init(&key->hlist); ++ hlist_del_init(&key->sklist); ++ mctp_key_unref(key); ++ } + spin_unlock_irqrestore(&net->mctp.keys_lock, flags); +- +- /* unref for the lists */ +- mctp_key_unref(key); + } + + /* and one for the local reference */ +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 0134e5d5c81a..39fb9cc25cdc 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev, + lockdep_assert_held(&rdev->bss_lock); + + bss->refcount++; +- if (bss->pub.hidden_beacon_bss) { +- bss = container_of(bss->pub.hidden_beacon_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } +- if (bss->pub.transmitted_bss) { +- bss = container_of(bss->pub.transmitted_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } ++ ++ if (bss->pub.hidden_beacon_bss) ++ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++; ++ ++ if (bss->pub.transmitted_bss) ++ bss_from_pub(bss->pub.transmitted_bss)->refcount++; + } + + static inline void bss_ref_put(struct cfg80211_registered_device *rdev, +@@ -304,7 +298,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, + tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); + tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; + +- while (tmp_old + tmp_old[1] + 2 - ie <= ielen) { ++ while (tmp_old + 2 - ie <= ielen && ++ tmp_old + tmp_old[1] + 2 - ie <= ielen) { + if (tmp_old[0] == 0) { + tmp_old++; + continue; +@@ -364,7 +359,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, + * copied to new ie, skip ssid, capability, bssid-index ie + */ + tmp_new = sub_copy; +- while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { ++ while (tmp_new + 2 - sub_copy <= subie_len && ++ tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { + if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP || + tmp_new[0] == WLAN_EID_SSID)) { + memcpy(pos, tmp_new, tmp_new[1] + 2); +@@ -427,6 +423,15 @@ cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss, + + rcu_read_unlock(); + ++ /* ++ * This is a bit weird - it's not on the list, but already on another ++ * one! The only way that could happen is if there's some BSSID/SSID ++ * shared by multiple APs in their multi-BSSID profiles, potentially ++ * with hidden SSID mixed in ... ignore it. ++ */ ++ if (!list_empty(&nontrans_bss->nontrans_list)) ++ return -EINVAL; ++ + /* add to the list */ + list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list); + return 0; +@@ -1602,6 +1607,23 @@ struct cfg80211_non_tx_bss { + u8 bssid_index; + }; + ++static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known, ++ const struct cfg80211_bss_ies *new_ies, ++ const struct cfg80211_bss_ies *old_ies) ++{ ++ struct cfg80211_internal_bss *bss; ++ ++ /* Assign beacon IEs to all sub entries */ ++ list_for_each_entry(bss, &known->hidden_list, hidden_list) { ++ const struct cfg80211_bss_ies *ies; ++ ++ ies = rcu_access_pointer(bss->pub.beacon_ies); ++ WARN_ON(ies != old_ies); ++ ++ rcu_assign_pointer(bss->pub.beacon_ies, new_ies); ++ } ++} ++ + static bool + cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, + struct cfg80211_internal_bss *known, +@@ -1625,7 +1647,6 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); + } else if (rcu_access_pointer(new->pub.beacon_ies)) { + const struct cfg80211_bss_ies *old; +- struct cfg80211_internal_bss *bss; + + if (known->pub.hidden_beacon_bss && + !list_empty(&known->hidden_list)) { +@@ -1653,16 +1674,7 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, + if (old == rcu_access_pointer(known->pub.ies)) + rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies); + +- /* Assign beacon IEs to all sub entries */ +- list_for_each_entry(bss, &known->hidden_list, hidden_list) { +- const struct cfg80211_bss_ies *ies; +- +- ies = rcu_access_pointer(bss->pub.beacon_ies); +- WARN_ON(ies != old); +- +- rcu_assign_pointer(bss->pub.beacon_ies, +- new->pub.beacon_ies); +- } ++ cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old); + + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); +@@ -1739,6 +1751,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, + new->refcount = 1; + INIT_LIST_HEAD(&new->hidden_list); + INIT_LIST_HEAD(&new->pub.nontrans_list); ++ /* we'll set this later if it was non-NULL */ ++ new->pub.transmitted_bss = NULL; + + if (rcu_access_pointer(tmp->pub.proberesp_ies)) { + hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); +@@ -2021,10 +2035,15 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, + spin_lock_bh(&rdev->bss_lock); + if (cfg80211_add_nontrans_list(non_tx_data->tx_bss, + &res->pub)) { +- if (__cfg80211_unlink_bss(rdev, res)) ++ if (__cfg80211_unlink_bss(rdev, res)) { + rdev->bss_generation++; ++ res = NULL; ++ } + } + spin_unlock_bh(&rdev->bss_lock); ++ ++ if (!res) ++ return NULL; + } + + trace_cfg80211_return_bss(&res->pub); +@@ -2143,6 +2162,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) { + if (elem->datalen < 4) + continue; ++ if (elem->data[0] < 1 || (int)elem->data[0] > 8) ++ continue; + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 profile_len; + +@@ -2279,7 +2300,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, + size_t new_ie_len; + struct cfg80211_bss_ies *new_ies; + const struct cfg80211_bss_ies *old; +- u8 cpy_len; ++ size_t cpy_len; + + lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock); + +@@ -2346,6 +2367,8 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, + } else { + old = rcu_access_pointer(nontrans_bss->beacon_ies); + rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies); ++ cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss), ++ new_ies, old); + rcu_assign_pointer(nontrans_bss->ies, new_ies); + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh index 0d99ef17e4a5..d4f3d63cb434 100755 --- a/scripts/pahole-flags.sh @@ -3387,3 +3908,19 @@ index 8b62654ff3f9..1c03d1cff35c 100644 #ifdef CONFIG_PERF_EVENTS int security_perf_event_open(struct perf_event_attr *attr, int type) { +diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh +index d5a0dd548989..ee5e98204d3d 100755 +--- a/tools/testing/selftests/net/fib_nexthops.sh ++++ b/tools/testing/selftests/net/fib_nexthops.sh +@@ -1223,6 +1223,11 @@ ipv4_fcnal() + log_test $rc 0 "Delete nexthop route warning" + run_cmd "$IP route delete 172.16.101.1/32 nhid 12" + run_cmd "$IP nexthop del id 12" ++ ++ run_cmd "$IP nexthop add id 21 via 172.16.1.6 dev veth1" ++ run_cmd "$IP ro add 172.16.101.0/24 nhid 21" ++ run_cmd "$IP ro del 172.16.101.0/24 nexthop via 172.16.1.7 dev veth1 nexthop via 172.16.1.8 dev veth1" ++ log_test $? 2 "Delete multipath route with only nh id based entry" + } + + ipv4_grp_fcnal() |