diff mbox series

iw: alignment issue in print_he_capability() on arm926

Message ID CA+GyqeZ976F6Zbcr5oo2_f_ECiy4tqb0vTjtSNtPexO07N-H4A@mail.gmail.com (mailing list archive)
State Rejected
Delegated to: Johannes Berg
Headers show
Series iw: alignment issue in print_he_capability() on arm926 | expand

Commit Message

admin LI May 17, 2024, 10:30 a.m. UTC
Hello, I'm using iw 5.16 with Yocto kirkstone 4.0.13, kernel 6.1.55 on
SAM9G25 cpu.

When I execute `iw wlan0 scan` kernel report many Alignment traps, looks like:
Alignment trap: iw (6376) PC=0x00461ff8 Instr=0xe1f720b2
Address=0x0048e771 FSR 0x001
Alignment trap: iw (6376) PC=0x00461ff8 Instr=0xe1f720b2
Address=0x0048e773 FSR 0x001
Alignment trap: iw (6376) PC=0x004631c8 Instr=0xe1d420b0
Address=0x0048e771 FSR 0x001
Alignment trap: iw (6376) PC=0x00463190 Instr=0xe1d420b0
Address=0x0048e771 FSR 0x001

Upon investigation, they came from LDRH instructions inside __print_he_capa().

There are 2 callers, print_he_info() haven't issue as variables are
aligned in stack,  but in print_he_capability() u16 variables are
directly casted from u8 without alignment check.

I tried a tentative fix which works but it's not clean enough to be
submitted as a patch:

---
 util.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

Comments

Johannes Berg May 17, 2024, 11:22 a.m. UTC | #1
On Fri, 2024-05-17 at 12:30 +0200, admin LI wrote:
> Hello, I'm using iw 5.16 with Yocto kirkstone 4.0.13, kernel 6.1.55 on
> SAM9G25 cpu.
> 
> When I execute `iw wlan0 scan` kernel report many Alignment traps, looks like:
> Alignment trap: iw (6376) PC=0x00461ff8 Instr=0xe1f720b2
> Address=0x0048e771 FSR 0x001
> Alignment trap: iw (6376) PC=0x00461ff8 Instr=0xe1f720b2
> Address=0x0048e773 FSR 0x001
> Alignment trap: iw (6376) PC=0x004631c8 Instr=0xe1d420b0
> Address=0x0048e771 FSR 0x001
> Alignment trap: iw (6376) PC=0x00463190 Instr=0xe1d420b0
> Address=0x0048e771 FSR 0x001
> 

Is that kind of thing not fixed up there? Does it even matter?

But I guess if we want to fix it, we'd really want something like
get_unaligned_le*() like in the kernel, not manually memcpy() in all the
code.

johannes
diff mbox series

Patch

diff --git a/util.c b/util.c
index 8a2ba10..941c6bf 100644
--- a/util.c
+++ b/util.c
@@ -4,6 +4,7 @@ 
 #include <stdbool.h>
 #include "iw.h"
 #include "nl80211.h"
+#include <malloc.h>

 void mac_addr_n2a(char *mac_addr, const unsigned char *arg)
 {
@@ -1657,20 +1658,23 @@  void print_eht_info(struct nlattr *nl_iftype, int band)

 void print_he_capability(const uint8_t *ie, int len)
 {
- const void *mac_cap, *phy_cap, *mcs_set;
+ const __u16 mac_cap[3], phy_cap[6] = {0}, *mcs_set;
  int mcs_len;
  int i = 0;

- mac_cap = &ie[i];
+ memcpy(mac_cap, &ie[i], 6);
  i += 6;

- phy_cap = &ie[i];
+ memcpy(phy_cap, &ie[i], 11);
  i += 11;

- mcs_set = &ie[i];
  mcs_len = len - i;
+ mcs_set = memalign(2, mcs_len);
+ memcpy(mcs_set, &ie[i], mcs_len);

  __print_he_capa(mac_cap, phy_cap - 1, mcs_set, mcs_len, NULL, 0, false);
+
+    free(mcs_set);
 }

 void iw_hexdump(const char *prefix, const __u8 *buf, size_t size)