From 62b8a31a162406485c5108b77d8cfe5b722cff9c Mon Sep 17 00:00:00 2001
From: "Yang Shelley (CSS ICW ENG WFS SW WFSW 1)" <Shelley.Yang@infineon.com>
Date: Tue, 11 Feb 2025 14:22:40 +0800
Subject: [PATCH 06/13] brcmfmac: Add support for SSID protection nl vendor cmd

- CVE-2023-52424(SSID confusion attack)
- Support ifx vendor command to enable SSID protection by app to IOVAR

Enable method:
- AP mode:
    Add "ssid_protection=1" in hostapd conf file.
- STA mode:
    Trigger by command "wpa_cli -i wlan0 set_network 0 ssid_protection 1"

Fixes SWLINUX-5036

Signed-off-by: Yang Shelley (CSS ICW ENG WFS SW WFSW 1) <Shelley.Yang@infineon.com>
---
 .../broadcom/brcm80211/brcmfmac/vendor.c      |  8 +++++
 .../broadcom/brcm80211/brcmfmac/vendor_ifx.c  | 30 +++++++++++++++++++
 .../broadcom/brcm80211/brcmfmac/vendor_ifx.h  | 21 ++++++++++++-
 3 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
index 308ea07..cfc6079 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
@@ -371,6 +371,14 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = {
 			   VENDOR_CMD_RAW_DATA,
 			   ifx_cfg80211_vndr_cmds_get_pfn_status)
 	},
+	{
+		IFX_SUBCMD(SSID_PROT,
+			   (WIPHY_VENDOR_CMD_NEED_WDEV |
+			   WIPHY_VENDOR_CMD_NEED_NETDEV),
+			   ifx_vendor_attr_ssid_prot_policy,
+			   ifx_cfg80211_vndr_cmds_ssid_prot),
+		.maxattr = IFX_VENDOR_ATTR_SSID_PROT_MAX
+	},
 };
 
 const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c
index f9bc583..cc1f3bf 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c
@@ -1211,3 +1211,33 @@ int ifx_cfg80211_vndr_cmds_get_pfn_status(struct wiphy *wiphy,
 	brcmf_dbg(TRACE, "Exit\n");
 	return 0;
 }
+
+int ifx_cfg80211_vndr_cmds_ssid_prot(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data, int len)
+{
+	int ret = 0;
+	int val = 0;
+	struct brcmf_cfg80211_vif *vif;
+	struct brcmf_if *ifp;
+	const struct nlattr *attr_iter;
+	int tmp, attr_type = 0;
+
+	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
+	ifp = vif->ifp;
+
+	nla_for_each_attr(attr_iter, data, len, tmp) {
+		attr_type = nla_type(attr_iter);
+		if (attr_type == IFX_VENDOR_ATTR_SSID_PROT_ENABLE) {
+			val = nla_get_u8(attr_iter);
+			ret = brcmf_fil_iovar_int_set(ifp, "ssid_protection", val);
+			if (ret < 0)
+				brcmf_err("Failed set ssid_protection, ret=%d\n", ret);
+			else
+				brcmf_dbg(INFO, "ssid_protection is %s\n",
+					  val ? "enabled" : "disabled");
+		}
+	}
+	return ret;
+}
+
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h
index 3c4d294..517ac78 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h
@@ -113,6 +113,8 @@ struct bcm_iov_buf {
  *	String parsing and calling corresponding function handler for a specific command
  *	given by user.
  *
+ * @IFX_VENDOR_SCMD_SSID_PROT: Vendor command to enable/disable SSID protection
+ *
  * @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
  *      Make sure it located at the end of the list.
  */
@@ -146,7 +148,9 @@ enum ifx_nl80211_vendor_subcmds {
 	SCMD(HWCAPS)		= 26,
 	SCMD(WNM_WL_CAP)	= 27,
 	SCMD(CMDSTR)		= 28,
-	SCMD(MAX)		= 29
+	/* Reserved 29 */
+	SCMD(SSID_PROT)		= 30,
+	SCMD(MAX)		= 31
 };
 
 /*
@@ -700,6 +704,19 @@ struct ifx_maxidle_wnm {
 	int protect;
 };
 
+enum ifx_vendor_attr_ssid_prot {
+	IFX_VENDOR_ATTR_SSID_PROT_UNSPEC,
+	IFX_VENDOR_ATTR_SSID_PROT_ENABLE,
+	IFX_VENDOR_ATTR_SSID_PROT_MAX
+};
+
+static const struct nla_policy
+ifx_vendor_attr_ssid_prot_policy[IFX_VENDOR_ATTR_SSID_PROT_MAX + 1] = {
+	[IFX_VENDOR_ATTR_SSID_PROT_UNSPEC] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_SSID_PROT_ENABLE] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_SSID_PROT_MAX] = {.type = NLA_U8},
+};
+
 #define WL_MKEEP_ALIVE_VERSION		1
 #define WL_MKEEP_ALIVE_IMMEDIATE	0x80000000
 
@@ -807,4 +824,6 @@ int ifx_cfg80211_vndr_cmds_config_pfn(struct wiphy *wiphy,
 				      struct wireless_dev *wdev, const void  *data, int len);
 int ifx_cfg80211_vndr_cmds_get_pfn_status(struct wiphy *wiphy,
 					  struct wireless_dev *wdev, const void  *data, int len);
+int ifx_cfg80211_vndr_cmds_ssid_prot(struct wiphy *wiphy,
+				     struct wireless_dev *wdev, const void *data, int len);
 #endif /* IFX_VENDOR_H */
-- 
2.25.1

