From: Greg Kroah-Hartman Date: Thu, 23 May 2024 11:48:05 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.19.315~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=681f153de72b83fa273d4289f3fb63d058a20833;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: ima-fix-deadlock-when-traversing-ima_default_rules.patch net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch net-bcmgenet-synchronize-umac_cmd-access.patch revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch --- diff --git a/queue-5.10/ima-fix-deadlock-when-traversing-ima_default_rules.patch b/queue-5.10/ima-fix-deadlock-when-traversing-ima_default_rules.patch new file mode 100644 index 00000000000..868701054c8 --- /dev/null +++ b/queue-5.10/ima-fix-deadlock-when-traversing-ima_default_rules.patch @@ -0,0 +1,143 @@ +From eb0782bbdfd0d7c4786216659277c3fd585afc0e Mon Sep 17 00:00:00 2001 +From: liqiong +Date: Sat, 9 Oct 2021 18:38:21 +0800 +Subject: ima: fix deadlock when traversing "ima_default_rules". + +From: liqiong + +commit eb0782bbdfd0d7c4786216659277c3fd585afc0e upstream. + +The current IMA ruleset is identified by the variable "ima_rules" +that default to "&ima_default_rules". When loading a custom policy +for the first time, the variable is updated to "&ima_policy_rules" +instead. That update isn't RCU-safe, and deadlocks are possible. +Indeed, some functions like ima_match_policy() may loop indefinitely +when traversing "ima_default_rules" with list_for_each_entry_rcu(). + +When iterating over the default ruleset back to head, if the list +head is "ima_default_rules", and "ima_rules" have been updated to +"&ima_policy_rules", the loop condition (&entry->list != ima_rules) +stays always true, traversing won't terminate, causing a soft lockup +and RCU stalls. + +Introduce a temporary value for "ima_rules" when iterating over +the ruleset to avoid the deadlocks. + +Signed-off-by: liqiong +Reviewed-by: THOBY Simon +Fixes: 38d859f991f3 ("IMA: policy can now be updated multiple times") +Reported-by: kernel test robot (Fix sparse: incompatible types in comparison expression.) +Signed-off-by: Mimi Zohar +Signed-off-by: GUO Zihua +Signed-off-by: Greg Kroah-Hartman +--- + security/integrity/ima/ima_policy.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -210,7 +210,7 @@ static struct ima_rule_entry *arch_polic + static LIST_HEAD(ima_default_rules); + static LIST_HEAD(ima_policy_rules); + static LIST_HEAD(ima_temp_rules); +-static struct list_head *ima_rules = &ima_default_rules; ++static struct list_head __rcu *ima_rules = (struct list_head __rcu *)(&ima_default_rules); + + static int ima_policy __initdata; + +@@ -648,12 +648,14 @@ int ima_match_policy(struct inode *inode + { + struct ima_rule_entry *entry; + int action = 0, actmask = flags | (flags << 1); ++ struct list_head *ima_rules_tmp; + + if (template_desc) + *template_desc = ima_template_desc_current(); + + rcu_read_lock(); +- list_for_each_entry_rcu(entry, ima_rules, list) { ++ ima_rules_tmp = rcu_dereference(ima_rules); ++ list_for_each_entry_rcu(entry, ima_rules_tmp, list) { + + if (!(entry->action & actmask)) + continue; +@@ -701,11 +703,15 @@ int ima_match_policy(struct inode *inode + void ima_update_policy_flag(void) + { + struct ima_rule_entry *entry; ++ struct list_head *ima_rules_tmp; + +- list_for_each_entry(entry, ima_rules, list) { ++ rcu_read_lock(); ++ ima_rules_tmp = rcu_dereference(ima_rules); ++ list_for_each_entry_rcu(entry, ima_rules_tmp, list) { + if (entry->action & IMA_DO_MASK) + ima_policy_flag |= entry->action; + } ++ rcu_read_unlock(); + + ima_appraise |= (build_ima_appraise | temp_ima_appraise); + if (!ima_appraise) +@@ -898,10 +904,10 @@ void ima_update_policy(void) + + list_splice_tail_init_rcu(&ima_temp_rules, policy, synchronize_rcu); + +- if (ima_rules != policy) { ++ if (ima_rules != (struct list_head __rcu *)policy) { + ima_policy_flag = 0; +- ima_rules = policy; + ++ rcu_assign_pointer(ima_rules, policy); + /* + * IMA architecture specific policy rules are specified + * as strings and converted to an array of ima_entry_rules +@@ -989,7 +995,7 @@ static int ima_lsm_rule_init(struct ima_ + pr_warn("rule for LSM \'%s\' is undefined\n", + entry->lsm[lsm_rule].args_p); + +- if (ima_rules == &ima_default_rules) { ++ if (ima_rules == (struct list_head __rcu *)(&ima_default_rules)) { + kfree(entry->lsm[lsm_rule].args_p); + entry->lsm[lsm_rule].args_p = NULL; + result = -EINVAL; +@@ -1598,9 +1604,11 @@ void *ima_policy_start(struct seq_file * + { + loff_t l = *pos; + struct ima_rule_entry *entry; ++ struct list_head *ima_rules_tmp; + + rcu_read_lock(); +- list_for_each_entry_rcu(entry, ima_rules, list) { ++ ima_rules_tmp = rcu_dereference(ima_rules); ++ list_for_each_entry_rcu(entry, ima_rules_tmp, list) { + if (!l--) { + rcu_read_unlock(); + return entry; +@@ -1619,7 +1627,8 @@ void *ima_policy_next(struct seq_file *m + rcu_read_unlock(); + (*pos)++; + +- return (&entry->list == ima_rules) ? NULL : entry; ++ return (&entry->list == &ima_default_rules || ++ &entry->list == &ima_policy_rules) ? NULL : entry; + } + + void ima_policy_stop(struct seq_file *m, void *v) +@@ -1823,6 +1832,7 @@ bool ima_appraise_signature(enum kernel_ + struct ima_rule_entry *entry; + bool found = false; + enum ima_hooks func; ++ struct list_head *ima_rules_tmp; + + if (id >= READING_MAX_ID) + return false; +@@ -1834,7 +1844,8 @@ bool ima_appraise_signature(enum kernel_ + func = read_idmap[id] ?: FILE_CHECK; + + rcu_read_lock(); +- list_for_each_entry_rcu(entry, ima_rules, list) { ++ ima_rules_tmp = rcu_dereference(ima_rules); ++ list_for_each_entry_rcu(entry, ima_rules_tmp, list) { + if (entry->action != APPRAISE) + continue; + diff --git a/queue-5.10/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch b/queue-5.10/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch new file mode 100644 index 00000000000..0ae8c9ef972 --- /dev/null +++ b/queue-5.10/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch @@ -0,0 +1,48 @@ +From d85cf67a339685beae1d0aee27b7f61da95455be Mon Sep 17 00:00:00 2001 +From: Doug Berger +Date: Thu, 25 Apr 2024 15:27:19 -0700 +Subject: net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access + +From: Doug Berger + +commit d85cf67a339685beae1d0aee27b7f61da95455be upstream. + +The EXT_RGMII_OOB_CTRL register can be written from different +contexts. It is predominantly written from the adjust_link +handler which is synchronized by the phydev->lock, but can +also be written from a different context when configuring the +mii in bcmgenet_mii_config(). + +The chances of contention are quite low, but it is conceivable +that adjust_link could occur during resume when WoL is enabled +so use the phydev->lock synchronizer in bcmgenet_mii_config() +to be sure. + +Fixes: afe3f907d20f ("net: bcmgenet: power on MII block for all MII modes") +Cc: stable@vger.kernel.org +Signed-off-by: Doug Berger +Acked-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c +@@ -264,6 +264,7 @@ int bcmgenet_mii_config(struct net_devic + * block for the interface to work + */ + if (priv->ext_phy) { ++ mutex_lock(&phydev->lock); + reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); + reg &= ~ID_MODE_DIS; + reg |= id_mode_dis; +@@ -272,6 +273,7 @@ int bcmgenet_mii_config(struct net_devic + else + reg |= RGMII_MODE_EN; + bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); ++ mutex_unlock(&phydev->lock); + } + + if (init) diff --git a/queue-5.10/net-bcmgenet-synchronize-umac_cmd-access.patch b/queue-5.10/net-bcmgenet-synchronize-umac_cmd-access.patch new file mode 100644 index 00000000000..b929f66d22f --- /dev/null +++ b/queue-5.10/net-bcmgenet-synchronize-umac_cmd-access.patch @@ -0,0 +1,167 @@ +From 0d5e2a82232605b337972fb2c7d0cbc46898aca1 Mon Sep 17 00:00:00 2001 +From: Doug Berger +Date: Thu, 25 Apr 2024 15:27:21 -0700 +Subject: net: bcmgenet: synchronize UMAC_CMD access + +From: Doug Berger + +commit 0d5e2a82232605b337972fb2c7d0cbc46898aca1 upstream. + +The UMAC_CMD register is written from different execution +contexts and has insufficient synchronization protections to +prevent possible corruption. Of particular concern are the +acceses from the phy_device delayed work context used by the +adjust_link call and the BH context that may be used by the +ndo_set_rx_mode call. + +A spinlock is added to the driver to protect contended register +accesses (i.e. reg_lock) and it is used to synchronize accesses +to UMAC_CMD. + +Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") +Cc: stable@vger.kernel.org +Signed-off-by: Doug Berger +Acked-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 12 +++++++++++- + drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 ++ + drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 6 ++++++ + drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 ++ + 4 files changed, 21 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -2420,14 +2420,18 @@ static void umac_enable_set(struct bcmge + { + u32 reg; + ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); +- if (reg & CMD_SW_RESET) ++ if (reg & CMD_SW_RESET) { ++ spin_unlock_bh(&priv->reg_lock); + return; ++ } + if (enable) + reg |= mask; + else + reg &= ~mask; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + + /* UniMAC stops on a packet boundary, wait for a full-size packet + * to be processed +@@ -2443,8 +2447,10 @@ static void reset_umac(struct bcmgenet_p + udelay(10); + + /* issue soft reset and disable MAC while updating its registers */ ++ spin_lock_bh(&priv->reg_lock); + bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); + udelay(2); ++ spin_unlock_bh(&priv->reg_lock); + } + + static void bcmgenet_intr_disable(struct bcmgenet_priv *priv) +@@ -3572,16 +3578,19 @@ static void bcmgenet_set_rx_mode(struct + * 3. The number of filters needed exceeds the number filters + * supported by the hardware. + */ ++ spin_lock(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) || + (nfilter > MAX_MDF_FILTER)) { + reg |= CMD_PROMISC; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock(&priv->reg_lock); + bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL); + return; + } else { + reg &= ~CMD_PROMISC; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock(&priv->reg_lock); + } + + /* update MDF filter */ +@@ -3975,6 +3984,7 @@ static int bcmgenet_probe(struct platfor + goto err; + } + ++ spin_lock_init(&priv->reg_lock); + spin_lock_init(&priv->lock); + + SET_NETDEV_DEV(dev, &pdev->dev); +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h +@@ -627,6 +627,8 @@ struct bcmgenet_rxnfc_rule { + /* device context */ + struct bcmgenet_priv { + void __iomem *base; ++ /* reg_lock: lock to serialize access to shared registers */ ++ spinlock_t reg_lock; + enum bcmgenet_version version; + struct net_device *dev; + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +@@ -134,6 +134,7 @@ int bcmgenet_wol_power_down_cfg(struct b + } + + /* Can't suspend with WoL if MAC is still in reset */ ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + if (reg & CMD_SW_RESET) + reg &= ~CMD_SW_RESET; +@@ -141,6 +142,7 @@ int bcmgenet_wol_power_down_cfg(struct b + /* disable RX */ + reg &= ~CMD_RX_EN; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + mdelay(10); + + if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) { +@@ -186,6 +188,7 @@ int bcmgenet_wol_power_down_cfg(struct b + } + + /* Enable CRC forward */ ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + priv->crc_fwd_en = 1; + reg |= CMD_CRC_FWD; +@@ -193,6 +196,7 @@ int bcmgenet_wol_power_down_cfg(struct b + /* Receiver must be enabled for WOL MP detection */ + reg |= CMD_RX_EN; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + + reg = UMAC_IRQ_MPD_R; + if (hfb_enable) +@@ -239,7 +243,9 @@ void bcmgenet_wol_power_up_cfg(struct bc + } + + /* Disable CRC Forward */ ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + reg &= ~CMD_CRC_FWD; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + } +--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c +@@ -91,6 +91,7 @@ void bcmgenet_mii_setup(struct net_devic + reg |= RGMII_LINK; + bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); + ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) | + CMD_HD_EN | +@@ -103,6 +104,7 @@ void bcmgenet_mii_setup(struct net_devic + reg |= CMD_TX_EN | CMD_RX_EN; + } + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + + priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0; + bcmgenet_eee_enable_set(dev, diff --git a/queue-5.10/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch b/queue-5.10/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch new file mode 100644 index 00000000000..9cf841b13d1 --- /dev/null +++ b/queue-5.10/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch @@ -0,0 +1,53 @@ +From harshit.m.mogalapalli@oracle.com Thu May 23 13:26:46 2024 +From: Harshit Mogalapalli +Date: Mon, 6 May 2024 01:49:26 -0700 +Subject: Revert "selftests: mm: fix map_hugetlb failure on 64K page size systems" +To: stable@vger.kernel.org +Cc: sashal@kernel.org, vegard.nossum@oracle.com, darren.kenny@oracle.com, Harshit Mogalapalli +Message-ID: <20240506084926.2943076-1-harshit.m.mogalapalli@oracle.com> + + +This reverts commit c9c3cc6a13bddc76bb533ad8147a5528cac5ba5a which is +commit 91b80cc5b39f00399e8e2d17527cad2c7fa535e2 upstream. + +map_hugetlb.c:18:10: fatal error: vm_util.h: No such file or directory + 18 | #include "vm_util.h" + | ^~~~~~~~~~~ +compilation terminated. + +vm_util.h is not present in 5.10.y, as commit:642bc52aed9c ("selftests: +vm: bring common functions to a new file") is not present in stable +kernels <=6.1.y + +Signed-off-by: Harshit Mogalapalli +--- + tools/testing/selftests/vm/map_hugetlb.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/tools/testing/selftests/vm/map_hugetlb.c ++++ b/tools/testing/selftests/vm/map_hugetlb.c +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include "vm_util.h" + + #define LENGTH (256UL*1024*1024) + #define PROTECTION (PROT_READ | PROT_WRITE) +@@ -71,16 +70,10 @@ int main(int argc, char **argv) + { + void *addr; + int ret; +- size_t hugepage_size; + size_t length = LENGTH; + int flags = FLAGS; + int shift = 0; + +- hugepage_size = default_huge_page_size(); +- /* munmap with fail if the length is not page aligned */ +- if (hugepage_size > length) +- length = hugepage_size; +- + if (argc > 1) + length = atol(argv[1]) << 20; + if (argc > 2) { diff --git a/queue-5.10/series b/queue-5.10/series index ca44d55c23e..9f56926b9e3 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -1,2 +1,6 @@ pinctrl-core-handle-radix_tree_insert-errors-in-pinctrl_register_one_pin.patch x86-xen-drop-usergs_sysret64-paravirt-call.patch +revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch +net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch +net-bcmgenet-synchronize-umac_cmd-access.patch +ima-fix-deadlock-when-traversing-ima_default_rules.patch