From: Greg Kroah-Hartman Date: Wed, 30 Nov 2022 17:13:46 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v5.10.157~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ac62c8a7b0a96dd0ac68571940be037fae0a628b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: fuse-lock-inode-unconditionally-in-fuse_fallocate.patch genirq-always-limit-the-affinity-to-online-cpus.patch genirq-msi-shutdown-managed-interrupts-with-unsatifiable-affinities.patch genirq-take-the-proposed-affinity-at-face-value-if-force-true.patch irqchip-gic-v3-always-trust-the-managed-affinity-provided-by-the-core-code.patch wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_channel_list-attribute.patch wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_oper_channel-attribute.patch wifi-wilc1000-validate-number-of-channels.patch wifi-wilc1000-validate-pairwise-and-authentication-suite-offsets.patch --- diff --git a/queue-5.15/fuse-lock-inode-unconditionally-in-fuse_fallocate.patch b/queue-5.15/fuse-lock-inode-unconditionally-in-fuse_fallocate.patch new file mode 100644 index 00000000000..a89c8f8b66f --- /dev/null +++ b/queue-5.15/fuse-lock-inode-unconditionally-in-fuse_fallocate.patch @@ -0,0 +1,89 @@ +From 44361e8cf9ddb23f17bdcc40ca944abf32e83e79 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Wed, 23 Nov 2022 09:10:42 +0100 +Subject: fuse: lock inode unconditionally in fuse_fallocate() + +From: Miklos Szeredi + +commit 44361e8cf9ddb23f17bdcc40ca944abf32e83e79 upstream. + +file_modified() must be called with inode lock held. fuse_fallocate() +didn't lock the inode in case of just FALLOC_KEEP_SIZE flags value, which +resulted in a kernel Warning in notify_change(). + +Lock the inode unconditionally, like all other fallocate implementations +do. + +Reported-by: Pengfei Xu +Reported-and-tested-by: syzbot+462da39f0667b357c4b6@syzkaller.appspotmail.com +Fixes: 4a6f278d4827 ("fuse: add file_modified() to fallocate") +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman +--- + fs/fuse/file.c | 41 ++++++++++++++++++----------------------- + 1 file changed, 18 insertions(+), 23 deletions(-) + +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -2937,11 +2937,9 @@ static long fuse_file_fallocate(struct f + .mode = mode + }; + int err; +- bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || +- (mode & (FALLOC_FL_PUNCH_HOLE | +- FALLOC_FL_ZERO_RANGE)); +- +- bool block_faults = FUSE_IS_DAX(inode) && lock_inode; ++ bool block_faults = FUSE_IS_DAX(inode) && ++ (!(mode & FALLOC_FL_KEEP_SIZE) || ++ (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))); + + if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | + FALLOC_FL_ZERO_RANGE)) +@@ -2950,22 +2948,20 @@ static long fuse_file_fallocate(struct f + if (fm->fc->no_fallocate) + return -EOPNOTSUPP; + +- if (lock_inode) { +- inode_lock(inode); +- if (block_faults) { +- filemap_invalidate_lock(inode->i_mapping); +- err = fuse_dax_break_layouts(inode, 0, 0); +- if (err) +- goto out; +- } +- +- if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) { +- loff_t endbyte = offset + length - 1; +- +- err = fuse_writeback_range(inode, offset, endbyte); +- if (err) +- goto out; +- } ++ inode_lock(inode); ++ if (block_faults) { ++ filemap_invalidate_lock(inode->i_mapping); ++ err = fuse_dax_break_layouts(inode, 0, 0); ++ if (err) ++ goto out; ++ } ++ ++ if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) { ++ loff_t endbyte = offset + length - 1; ++ ++ err = fuse_writeback_range(inode, offset, endbyte); ++ if (err) ++ goto out; + } + + if (!(mode & FALLOC_FL_KEEP_SIZE) && +@@ -3015,8 +3011,7 @@ out: + if (block_faults) + filemap_invalidate_unlock(inode->i_mapping); + +- if (lock_inode) +- inode_unlock(inode); ++ inode_unlock(inode); + + fuse_flush_time_update(inode); + diff --git a/queue-5.15/genirq-always-limit-the-affinity-to-online-cpus.patch b/queue-5.15/genirq-always-limit-the-affinity-to-online-cpus.patch new file mode 100644 index 00000000000..75d3c116461 --- /dev/null +++ b/queue-5.15/genirq-always-limit-the-affinity-to-online-cpus.patch @@ -0,0 +1,95 @@ +From foo@baz Wed Nov 30 06:09:32 PM CET 2022 +From: Luiz Capitulino +Date: Mon, 28 Nov 2022 17:08:33 +0000 +Subject: genirq: Always limit the affinity to online CPUs +To: , +Cc: , , Luiz Capitulino +Message-ID: <9a311a850001dc60bf1f83a21f43f9567d658c15.1669655291.git.luizcap@amazon.com> + +From: Luiz Capitulino + +From: Marc Zyngier + +commit 33de0aa4bae982ed6f7c777f86b5af3e627ac937 upstream. + +[ Fixed small conflicts due to the HK_FLAG_MANAGED_IRQ flag been + renamed on upstream ] + +When booting with maxcpus= (or even loading a driver +while most CPUs are offline), it is pretty easy to observe managed +affinities containing a mix of online and offline CPUs being passed +to the irqchip driver. + +This means that the irqchip cannot trust the affinity passed down +from the core code, which is a bit annoying and requires (at least +in theory) all drivers to implement some sort of affinity narrowing. + +In order to address this, always limit the cpumask to the set of +online CPUs. + +Signed-off-by: Marc Zyngier +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20220405185040.206297-3-maz@kernel.org + +Signed-off-by: Luiz Capitulino +Signed-off-by: Greg Kroah-Hartman +--- + kernel/irq/manage.c | 25 +++++++++++++++++-------- + 1 file changed, 17 insertions(+), 8 deletions(-) + +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -222,11 +222,16 @@ int irq_do_set_affinity(struct irq_data + { + struct irq_desc *desc = irq_data_to_desc(data); + struct irq_chip *chip = irq_data_get_irq_chip(data); ++ const struct cpumask *prog_mask; + int ret; + ++ static DEFINE_RAW_SPINLOCK(tmp_mask_lock); ++ static struct cpumask tmp_mask; ++ + if (!chip || !chip->irq_set_affinity) + return -EINVAL; + ++ raw_spin_lock(&tmp_mask_lock); + /* + * If this is a managed interrupt and housekeeping is enabled on + * it check whether the requested affinity mask intersects with +@@ -248,24 +253,28 @@ int irq_do_set_affinity(struct irq_data + */ + if (irqd_affinity_is_managed(data) && + housekeeping_enabled(HK_FLAG_MANAGED_IRQ)) { +- const struct cpumask *hk_mask, *prog_mask; +- +- static DEFINE_RAW_SPINLOCK(tmp_mask_lock); +- static struct cpumask tmp_mask; ++ const struct cpumask *hk_mask; + + hk_mask = housekeeping_cpumask(HK_FLAG_MANAGED_IRQ); + +- raw_spin_lock(&tmp_mask_lock); + cpumask_and(&tmp_mask, mask, hk_mask); + if (!cpumask_intersects(&tmp_mask, cpu_online_mask)) + prog_mask = mask; + else + prog_mask = &tmp_mask; +- ret = chip->irq_set_affinity(data, prog_mask, force); +- raw_spin_unlock(&tmp_mask_lock); + } else { +- ret = chip->irq_set_affinity(data, mask, force); ++ prog_mask = mask; + } ++ ++ /* Make sure we only provide online CPUs to the irqchip */ ++ cpumask_and(&tmp_mask, prog_mask, cpu_online_mask); ++ if (!cpumask_empty(&tmp_mask)) ++ ret = chip->irq_set_affinity(data, &tmp_mask, force); ++ else ++ ret = -EINVAL; ++ ++ raw_spin_unlock(&tmp_mask_lock); ++ + switch (ret) { + case IRQ_SET_MASK_OK: + case IRQ_SET_MASK_OK_DONE: diff --git a/queue-5.15/genirq-msi-shutdown-managed-interrupts-with-unsatifiable-affinities.patch b/queue-5.15/genirq-msi-shutdown-managed-interrupts-with-unsatifiable-affinities.patch new file mode 100644 index 00000000000..435b6a443b6 --- /dev/null +++ b/queue-5.15/genirq-msi-shutdown-managed-interrupts-with-unsatifiable-affinities.patch @@ -0,0 +1,61 @@ +From foo@baz Wed Nov 30 06:09:32 PM CET 2022 +From: Luiz Capitulino +Date: Mon, 28 Nov 2022 17:08:32 +0000 +Subject: genirq/msi: Shutdown managed interrupts with unsatifiable affinities +To: , +Cc: , , John Garry , David Decotigny , "Luiz Capitulino" +Message-ID: <987f78b332076edcf0b05d169bcd2694edee7c05.1669655291.git.luizcap@amazon.com> + +From: Luiz Capitulino + +From: Marc Zyngier + +commit d802057c7c553ad426520a053da9f9fe08e2c35a upstream. + +[ This commit is almost a rewrite because it conflicts with Thomas + Gleixner's refactoring of this code in v5.17-rc1. I wasn't sure if + I should drop all the s-o-bs (including Mark's), but decided + to keep as the original commit ] + +When booting with maxcpus=, interrupt controllers +such as the GICv3 ITS may not be able to satisfy the affinity of +some managed interrupts, as some of the HW resources are simply +not available. + +The same thing happens when loading a driver using managed interrupts +while CPUs are offline. + +In order to deal with this, do not try to activate such interrupt +if there is no online CPU capable of handling it. Instead, place +it in shutdown state. Once a capable CPU shows up, it will be +activated. + +Reported-by: John Garry +Reported-by: David Decotigny +Signed-off-by: Marc Zyngier +Signed-off-by: Thomas Gleixner +Tested-by: John Garry +Link: https://lore.kernel.org/r/20220405185040.206297-2-maz@kernel.org + +Signed-off-by: Luiz Capitulino +Signed-off-by: Greg Kroah-Hartman +--- + kernel/irq/msi.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/kernel/irq/msi.c ++++ b/kernel/irq/msi.c +@@ -596,6 +596,13 @@ int __msi_domain_alloc_irqs(struct irq_d + irqd_clr_can_reserve(irq_data); + if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK) + irqd_set_msi_nomask_quirk(irq_data); ++ if ((info->flags & MSI_FLAG_ACTIVATE_EARLY) && ++ irqd_affinity_is_managed(irq_data) && ++ !cpumask_intersects(irq_data_get_affinity_mask(irq_data), ++ cpu_online_mask)) { ++ irqd_set_managed_shutdown(irq_data); ++ continue; ++ } + } + ret = irq_domain_activate_irq(irq_data, can_reserve); + if (ret) diff --git a/queue-5.15/genirq-take-the-proposed-affinity-at-face-value-if-force-true.patch b/queue-5.15/genirq-take-the-proposed-affinity-at-face-value-if-force-true.patch new file mode 100644 index 00000000000..caa7cdf53a9 --- /dev/null +++ b/queue-5.15/genirq-take-the-proposed-affinity-at-face-value-if-force-true.patch @@ -0,0 +1,61 @@ +From foo@baz Wed Nov 30 06:09:32 PM CET 2022 +From: Luiz Capitulino +Date: Mon, 28 Nov 2022 17:08:35 +0000 +Subject: genirq: Take the proposed affinity at face value if force==true +To: , +Cc: , , Marek Szyprowski , Luiz Capitulino +Message-ID: <56bb8afbb97c6ed2364ba49dd0695ce7681aa3ec.1669655291.git.luizcap@amazon.com> + +From: Luiz Capitulino + +From: Marc Zyngier + +commit c48c8b829d2b966a6649827426bcdba082ccf922 upstream. + +Although setting the affinity of an interrupt to a set of CPUs that doesn't +have any online CPU is generally frowned apon, there are a few limited +cases where such affinity is set from a CPUHP notifier, setting the +affinity to a CPU that isn't online yet. + +The saving grace is that this is always done using the 'force' attribute, +which gives a hint that the affinity setting can be outside of the online +CPU mask and the callsite set this flag with the knowledge that the +underlying interrupt controller knows to handle it. + +This restores the expected behaviour on Marek's system. + +Fixes: 33de0aa4bae9 ("genirq: Always limit the affinity to online CPUs") +Reported-by: Marek Szyprowski +Signed-off-by: Marc Zyngier +Signed-off-by: Thomas Gleixner +Tested-by: Marek Szyprowski +Link: https://lore.kernel.org/r/4b7fc13c-887b-a664-26e8-45aed13f048a@samsung.com +Link: https://lore.kernel.org/r/20220414140011.541725-1-maz@kernel.org + +Signed-off-by: Luiz Capitulino +Signed-off-by: Greg Kroah-Hartman +--- + kernel/irq/manage.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -266,10 +266,16 @@ int irq_do_set_affinity(struct irq_data + prog_mask = mask; + } + +- /* Make sure we only provide online CPUs to the irqchip */ ++ /* ++ * Make sure we only provide online CPUs to the irqchip, ++ * unless we are being asked to force the affinity (in which ++ * case we do as we are told). ++ */ + cpumask_and(&tmp_mask, prog_mask, cpu_online_mask); +- if (!cpumask_empty(&tmp_mask)) ++ if (!force && !cpumask_empty(&tmp_mask)) + ret = chip->irq_set_affinity(data, &tmp_mask, force); ++ else if (force) ++ ret = chip->irq_set_affinity(data, mask, force); + else + ret = -EINVAL; + diff --git a/queue-5.15/irqchip-gic-v3-always-trust-the-managed-affinity-provided-by-the-core-code.patch b/queue-5.15/irqchip-gic-v3-always-trust-the-managed-affinity-provided-by-the-core-code.patch new file mode 100644 index 00000000000..a847a77d0d0 --- /dev/null +++ b/queue-5.15/irqchip-gic-v3-always-trust-the-managed-affinity-provided-by-the-core-code.patch @@ -0,0 +1,39 @@ +From foo@baz Wed Nov 30 06:09:32 PM CET 2022 +From: Luiz Capitulino +Date: Mon, 28 Nov 2022 17:08:34 +0000 +Subject: irqchip/gic-v3: Always trust the managed affinity provided by the core code +To: , +Cc: , , Luiz Capitulino +Message-ID: + +From: Luiz Capitulino + +From: Marc Zyngier + +commit 3f893a5962d31c0164efdbf6174ed0784f1d7603 upstream. + +Now that the core code has been fixed to always give us an affinity +that only includes online CPUs, directly use this affinity when +computing a target CPU. + +Signed-off-by: Marc Zyngier +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20220405185040.206297-4-maz@kernel.org + +Signed-off-by: Luiz Capitulino +Signed-off-by: Greg Kroah-Hartman +--- + drivers/irqchip/irq-gic-v3-its.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -1620,7 +1620,7 @@ static int its_select_cpu(struct irq_dat + + cpu = cpumask_pick_least_loaded(d, tmpmask); + } else { +- cpumask_and(tmpmask, irq_data_get_affinity_mask(d), cpu_online_mask); ++ cpumask_copy(tmpmask, aff_mask); + + /* If we cannot cross sockets, limit the search to that node */ + if ((its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) && diff --git a/queue-5.15/series b/queue-5.15/series index f602f6b5330..3a23e2e4197 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -184,3 +184,12 @@ scsi-iscsi-fix-possible-memory-leak-when-device_regi.patch gpu-host1x-avoid-trying-to-use-gart-on-tegra20.patch dm-integrity-flush-the-journal-on-suspend.patch dm-integrity-clear-the-journal-on-suspend.patch +fuse-lock-inode-unconditionally-in-fuse_fallocate.patch +wifi-wilc1000-validate-pairwise-and-authentication-suite-offsets.patch +wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_oper_channel-attribute.patch +wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_channel_list-attribute.patch +wifi-wilc1000-validate-number-of-channels.patch +genirq-msi-shutdown-managed-interrupts-with-unsatifiable-affinities.patch +genirq-always-limit-the-affinity-to-online-cpus.patch +irqchip-gic-v3-always-trust-the-managed-affinity-provided-by-the-core-code.patch +genirq-take-the-proposed-affinity-at-face-value-if-force-true.patch diff --git a/queue-5.15/wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_channel_list-attribute.patch b/queue-5.15/wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_channel_list-attribute.patch new file mode 100644 index 00000000000..15fab1cc925 --- /dev/null +++ b/queue-5.15/wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_channel_list-attribute.patch @@ -0,0 +1,38 @@ +From f9b62f9843c7b0afdaecabbcebf1dbba18599408 Mon Sep 17 00:00:00 2001 +From: Phil Turnbull +Date: Wed, 23 Nov 2022 10:35:42 -0500 +Subject: wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_CHANNEL_LIST attribute + +From: Phil Turnbull + +commit f9b62f9843c7b0afdaecabbcebf1dbba18599408 upstream. + +Validate that the IEEE80211_P2P_ATTR_CHANNEL_LIST attribute contains +enough space for a 'struct wilc_attr_oper_ch'. If the attribute is too +small then it can trigger an out-of-bounds write later in the function. + +'struct wilc_attr_oper_ch' is variable sized so also check 'attr_len' +does not extend beyond the end of 'buf'. + +Signed-off-by: Phil Turnbull +Tested-by: Ajay Kathat +Acked-by: Ajay Kathat +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20221123153543.8568-4-philipturnbull@github.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c ++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c +@@ -947,7 +947,8 @@ static inline void wilc_wfi_cfg_parse_ch + if (index + sizeof(*e) + attr_size > len) + return; + +- if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST) ++ if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST && ++ attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e))) + ch_list_idx = index; + else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL && + attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e))) diff --git a/queue-5.15/wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_oper_channel-attribute.patch b/queue-5.15/wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_oper_channel-attribute.patch new file mode 100644 index 00000000000..9624ff00bb8 --- /dev/null +++ b/queue-5.15/wifi-wilc1000-validate-length-of-ieee80211_p2p_attr_oper_channel-attribute.patch @@ -0,0 +1,52 @@ +From 051ae669e4505abbe05165bebf6be7922de11f41 Mon Sep 17 00:00:00 2001 +From: Phil Turnbull +Date: Wed, 23 Nov 2022 10:35:41 -0500 +Subject: wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_OPER_CHANNEL attribute + +From: Phil Turnbull + +commit 051ae669e4505abbe05165bebf6be7922de11f41 upstream. + +Validate that the IEEE80211_P2P_ATTR_OPER_CHANNEL attribute contains +enough space for a 'struct struct wilc_attr_oper_ch'. If the attribute is +too small then it triggers an out-of-bounds write later in the function. + +Signed-off-by: Phil Turnbull +Tested-by: Ajay Kathat +Acked-by: Ajay Kathat +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20221123153543.8568-3-philipturnbull@github.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/microchip/wilc1000/cfg80211.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c ++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c +@@ -939,14 +939,24 @@ static inline void wilc_wfi_cfg_parse_ch + return; + + while (index + sizeof(*e) <= len) { ++ u16 attr_size; ++ + e = (struct wilc_attr_entry *)&buf[index]; ++ attr_size = le16_to_cpu(e->attr_len); ++ ++ if (index + sizeof(*e) + attr_size > len) ++ return; ++ + if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST) + ch_list_idx = index; +- else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL) ++ else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL && ++ attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e))) + op_ch_idx = index; ++ + if (ch_list_idx && op_ch_idx) + break; +- index += le16_to_cpu(e->attr_len) + sizeof(*e); ++ ++ index += sizeof(*e) + attr_size; + } + + if (ch_list_idx) { diff --git a/queue-5.15/wifi-wilc1000-validate-number-of-channels.patch b/queue-5.15/wifi-wilc1000-validate-number-of-channels.patch new file mode 100644 index 00000000000..d0ab424b55b --- /dev/null +++ b/queue-5.15/wifi-wilc1000-validate-number-of-channels.patch @@ -0,0 +1,62 @@ +From 0cdfa9e6f0915e3d243e2393bfa8a22e12d553b0 Mon Sep 17 00:00:00 2001 +From: Phil Turnbull +Date: Wed, 23 Nov 2022 10:35:43 -0500 +Subject: wifi: wilc1000: validate number of channels + +From: Phil Turnbull + +commit 0cdfa9e6f0915e3d243e2393bfa8a22e12d553b0 upstream. + +There is no validation of 'e->no_of_channels' which can trigger an +out-of-bounds write in the following 'memset' call. Validate that the +number of channels does not extends beyond the size of the channel list +element. + +Signed-off-by: Phil Turnbull +Tested-by: Ajay Kathat +Acked-by: Ajay Kathat +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20221123153543.8568-5-philipturnbull@github.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/microchip/wilc1000/cfg80211.c | 22 +++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c ++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c +@@ -961,19 +961,29 @@ static inline void wilc_wfi_cfg_parse_ch + } + + if (ch_list_idx) { +- u16 attr_size; +- struct wilc_ch_list_elem *e; +- int i; ++ u16 elem_size; + + ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx]; +- attr_size = le16_to_cpu(ch_list->attr_len); +- for (i = 0; i < attr_size;) { ++ /* the number of bytes following the final 'elem' member */ ++ elem_size = le16_to_cpu(ch_list->attr_len) - ++ (sizeof(*ch_list) - sizeof(struct wilc_attr_entry)); ++ for (unsigned int i = 0; i < elem_size;) { ++ struct wilc_ch_list_elem *e; ++ + e = (struct wilc_ch_list_elem *)(ch_list->elem + i); ++ ++ i += sizeof(*e); ++ if (i > elem_size) ++ break; ++ ++ i += e->no_of_channels; ++ if (i > elem_size) ++ break; ++ + if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) { + memset(e->ch_list, sta_ch, e->no_of_channels); + break; + } +- i += e->no_of_channels; + } + } + diff --git a/queue-5.15/wifi-wilc1000-validate-pairwise-and-authentication-suite-offsets.patch b/queue-5.15/wifi-wilc1000-validate-pairwise-and-authentication-suite-offsets.patch new file mode 100644 index 00000000000..61b6b51646e --- /dev/null +++ b/queue-5.15/wifi-wilc1000-validate-pairwise-and-authentication-suite-offsets.patch @@ -0,0 +1,55 @@ +From cd21d99e595ec1d8721e1058dcdd4f1f7de1d793 Mon Sep 17 00:00:00 2001 +From: Phil Turnbull +Date: Wed, 23 Nov 2022 10:35:40 -0500 +Subject: wifi: wilc1000: validate pairwise and authentication suite offsets + +From: Phil Turnbull + +commit cd21d99e595ec1d8721e1058dcdd4f1f7de1d793 upstream. + +There is no validation of 'offset' which can trigger an out-of-bounds +read when extracting RSN capabilities. + +Signed-off-by: Phil Turnbull +Tested-by: Ajay Kathat +Acked-by: Ajay Kathat +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20221123153543.8568-2-philipturnbull@github.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/microchip/wilc1000/hif.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/microchip/wilc1000/hif.c ++++ b/drivers/net/wireless/microchip/wilc1000/hif.c +@@ -467,14 +467,25 @@ void *wilc_parse_join_bss_param(struct c + + rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len); + if (rsn_ie) { ++ int rsn_ie_len = sizeof(struct element) + rsn_ie[1]; + int offset = 8; + +- param->mode_802_11i = 2; +- param->rsn_found = true; + /* extract RSN capabilities */ +- offset += (rsn_ie[offset] * 4) + 2; +- offset += (rsn_ie[offset] * 4) + 2; +- memcpy(param->rsn_cap, &rsn_ie[offset], 2); ++ if (offset < rsn_ie_len) { ++ /* skip over pairwise suites */ ++ offset += (rsn_ie[offset] * 4) + 2; ++ ++ if (offset < rsn_ie_len) { ++ /* skip over authentication suites */ ++ offset += (rsn_ie[offset] * 4) + 2; ++ ++ if (offset + 1 < rsn_ie_len) { ++ param->mode_802_11i = 2; ++ param->rsn_found = true; ++ memcpy(param->rsn_cap, &rsn_ie[offset], 2); ++ } ++ } ++ } + } + + if (param->rsn_found) {