From e6f9eab90ebc80170b2fb2af61217d5eb0421564 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <jouni@codeaurora.org>
Date: Thu, 25 Apr 2019 23:57:47 +0300
Subject: [PATCH] HE: Fix HE Operation element byte order on bigendian CPUs

The first four octets of the element were used as a host byte order u32.
That is not correct on bigendian CPUs, so handle byte swapping needs
properly. Mark the he_oper_params field as le32 to explicitly indicate
the byte order and swap the generated params content based on CPU byte
order.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
---
 src/ap/ieee802_11_he.c       | 20 ++++++++++----------
 src/common/ieee802_11_defs.h |  4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
index 8798ada32..0dbfc7019 100644
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -62,6 +62,7 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid)
 	struct ieee80211_he_operation *oper;
 	u8 *pos = eid;
 	int oper_size = 6;
+	u32 params = 0;
 
 	if (!hapd->iface->current_mode)
 		return eid;
@@ -74,25 +75,24 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid)
 	os_memset(oper, 0, sizeof(*oper));
 
 	if (hapd->iface->conf->he_op.he_default_pe_duration)
-		oper->he_oper_params |=
-			(hapd->iface->conf->he_op.he_default_pe_duration <<
-			 HE_OPERATION_DFLT_PE_DURATION_OFFSET);
+		params |= (hapd->iface->conf->he_op.he_default_pe_duration <<
+			   HE_OPERATION_DFLT_PE_DURATION_OFFSET);
 
 	if (hapd->iface->conf->he_op.he_twt_required)
-		oper->he_oper_params |= HE_OPERATION_TWT_REQUIRED;
+		params |= HE_OPERATION_TWT_REQUIRED;
 
 	if (hapd->iface->conf->he_op.he_rts_threshold)
-		oper->he_oper_params |=
-			(hapd->iface->conf->he_op.he_rts_threshold <<
-			 HE_OPERATION_RTS_THRESHOLD_OFFSET);
+		params |= (hapd->iface->conf->he_op.he_rts_threshold <<
+			   HE_OPERATION_RTS_THRESHOLD_OFFSET);
 
 	if (hapd->iface->conf->he_op.he_bss_color)
-		oper->he_oper_params |=
-			(hapd->iface->conf->he_op.he_bss_color <<
-			 HE_OPERATION_BSS_COLOR_OFFSET);
+		params |= (hapd->iface->conf->he_op.he_bss_color <<
+			   HE_OPERATION_BSS_COLOR_OFFSET);
 
 	/* TODO: conditional MaxBSSID Indicator subfield */
 
+	oper->he_oper_params = host_to_le32(params);
+
 	pos += oper_size;
 
 	return pos;
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 90615ece6..7eadc7710 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -2110,8 +2110,8 @@ struct ieee80211_he_capabilities {
 } STRUCT_PACKED;
 
 struct ieee80211_he_operation {
-	u32 he_oper_params; /* HE Operation Parameters[3] and
-			     * BSS Color Information[1] */
+	le32 he_oper_params; /* HE Operation Parameters[3] and
+			      * BSS Color Information[1] */
 	u8 he_mcs_nss_set[2];
 	u8 vht_op_info_chwidth;
 	u8 vht_op_info_chan_center_freq_seg0_idx;