Skip to content

Commit 753f29e

Browse files
committed
patches: mainline: Apply workaround for __read_overflow error in iwlwifi
Signed-off-by: Nathan Chancellor <[email protected]>
1 parent b70e012 commit 753f29e

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

patches/mainline/series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
d8720235d5b5cad86c1f07f65117ef2a96f8bec7.patch
2+
v2_20250425_kees_wifi_iwlwifi_mld_work_around_clang_loop_unrolling_bug.patch
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
From git@z Thu Jan 1 00:00:00 1970
2+
Subject: [PATCH v2] wifi: iwlwifi: mld: Work around Clang loop unrolling
3+
bug
4+
From: Kees Cook <[email protected]>
5+
Date: Fri, 25 Apr 2025 11:44:22 -0700
6+
Message-Id: <[email protected]>
7+
MIME-Version: 1.0
8+
Content-Type: text/plain; charset="utf-8"
9+
Content-Transfer-Encoding: 7bit
10+
11+
The nested loop in iwl_mld_send_proto_offload() confuses Clang into
12+
thinking there could be final loop iteration past the end of the "nsc"
13+
array (which is only 4 entries). The FORTIFY checking in memcmp()
14+
(via ipv6_addr_cmp()) notices this (due to the available bytes in the
15+
out-of-bounds position of &nsc[4] being 0), and errors out, failing
16+
the build. For some reason (likely due to architectural loop unrolling
17+
configurations), this is only exposed on ARM builds currently. Due to
18+
Clang's lack of inline tracking[1], the warning is not very helpful:
19+
20+
include/linux/fortify-string.h:719:4: error: call to '__read_overflow' declared with 'error' attribute: detected read beyond size of object (1st parameter)
21+
719 | __read_overflow();
22+
| ^
23+
1 error generated.
24+
25+
But this was tracked down to iwl_mld_send_proto_offload()'s
26+
ipv6_addr_cmp() call.
27+
28+
An upstream Clang bug has been filed[2] to track this, but for now.
29+
Fix the build by explicitly bounding the inner loop by "n_nsc", which is
30+
what "c" is already limited to. Additionally do not repeat the ns_config
31+
and targ_addrs array sizes with their open-coded names since they can
32+
be determined at compile-time with ARRAY_SIZE().
33+
34+
Reported-by: Nathan Chancellor <[email protected]>
35+
Closes: https://github.com/ClangBuiltLinux/linux/issues/2076
36+
Link: https://github.com/llvm/llvm-project/pull/73552 [1]
37+
Link: https://github.com/llvm/llvm-project/issues/136603 [2]
38+
Signed-off-by: Kees Cook <[email protected]>
39+
Reviewed-by: Nathan Chancellor <[email protected]>
40+
Link: https://lore.kernel.org/r/[email protected]
41+
---
42+
v2:
43+
- move "j < n_nsc" forward to stabilize loop bounds (Nathan)
44+
- use ARRAY_SIZE() for robustness
45+
v1: https://lore.kernel.org/all/[email protected]/
46+
Cc: Miri Korenblit <[email protected]>
47+
Cc: Johannes Berg <[email protected]>
48+
Cc: Yedidya Benshimol <[email protected]>
49+
Cc: Emmanuel Grumbach <[email protected]>
50+
Cc: Avraham Stern <[email protected]>
51+
52+
---
53+
drivers/net/wireless/intel/iwlwifi/mld/d3.c | 14 +++++---------
54+
1 file changed, 5 insertions(+), 9 deletions(-)
55+
56+
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
57+
index dc736fdc176d..c51a6596617d 100644
58+
--- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c
59+
+++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
60+
@@ -1728,17 +1728,13 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld,
61+
#if IS_ENABLED(CONFIG_IPV6)
62+
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
63+
struct iwl_mld_wowlan_data *wowlan_data = &mld_vif->wowlan_data;
64+
- struct iwl_ns_config *nsc;
65+
- struct iwl_targ_addr *addrs;
66+
- int n_nsc, n_addrs;
67+
+ const int n_addrs = ARRAY_SIZE(cmd->targ_addrs);
68+
+ struct iwl_targ_addr *addrs = cmd->targ_addrs;
69+
+ const int n_nsc = ARRAY_SIZE(cmd->ns_config);
70+
+ struct iwl_ns_config *nsc = cmd->ns_config;
71+
int i, c;
72+
int num_skipped = 0;
73+
74+
- nsc = cmd->ns_config;
75+
- n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L;
76+
- addrs = cmd->targ_addrs;
77+
- n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L;
78+
-
79+
/* For each address we have (and that will fit) fill a target
80+
* address struct and combine for NS offload structs with the
81+
* solicited node addresses.
82+
@@ -1759,7 +1755,7 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld,
83+
84+
addrconf_addr_solict_mult(&wowlan_data->target_ipv6_addrs[i],
85+
&solicited_addr);
86+
- for (j = 0; j < c; j++)
87+
+ for (j = 0; j < n_nsc && j < c; j++)
88+
if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
89+
&solicited_addr) == 0)
90+
break;
91+
--
92+
2.34.1
93+

0 commit comments

Comments
 (0)