* [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls
@ 2017-11-23 1:29 ishraq.i.ashraf
2017-11-23 13:24 ` Dan Carpenter
` (5 more replies)
0 siblings, 6 replies; 17+ messages in thread
From: ishraq.i.ashraf @ 2017-11-23 1:29 UTC (permalink / raw)
To: gregkh
Cc: himanshujha199640, goudapatilk, insafonov, devel, linux-kernel,
Ishraq Ibne Ashraf
From: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
Commit 8bfb36766064 ("wireless: wext: remove ndo_do_ioctl fallback") breaks private WEXT
IOCTL calls of this driver as these are not invoked through ndo_do_ioctl
interface anymore. As a result hostapd stops working with this driver. In
this patch this problem is solved by implementing equivalent private IOCTL
functions of the existing ones which are accessed via iw_handler_def
interface.
Signed-off-by: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
---
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1042 ++++++++++++++++++++++++
1 file changed, 1042 insertions(+)
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index c0664dc..7503751 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -3061,6 +3061,1046 @@ static iw_handler rtw_handlers[] = {
NULL, /*---hole---*/
};
+static int get_private_handler_ieee_param(struct adapter *padapter,
+ union iwreq_data *wrqu,
+ void *param)
+{
+ /*
+ * This function is expected to be called in master mode, which allows no
+ * power saving. So we just check hw_init_completed.
+ */
+
+ if (!padapter->hw_init_completed)
+ return -EPERM;
+
+ if (!wrqu->data.pointer)
+ return -EINVAL;
+
+ /*
+ * Since we don't allocate memory for param in this function, we assume
+ * the caller of this function will properly allocate and deallocate memory
+ * for param.
+ */
+ if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+
+ DBG_88E("%s\n", __func__);
+
+ flush_all_cam_entry(padapter); // Clear CAM.
+
+ return rtw_sta_flush(padapter);
+}
+
+static int rtw_add_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct sta_info *psta = NULL;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_add_sta: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_add_sta: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
+
+ if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
+ return -EINVAL;
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+ return -EINVAL;
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (psta) {
+ int flags = param->u.add_sta.flags;
+ psta->aid = param->u.add_sta.aid; // aid = 1~2007.
+
+ memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
+
+ // Check WMM cap.
+ if (WLAN_STA_WME&flags)
+ psta->qos_option = 1;
+ else
+ psta->qos_option = 0;
+
+ if (pmlmepriv->qospriv.qos_option == 0)
+ psta->qos_option = 0;
+
+ // Check 802.11n HT cap.
+ if (WLAN_STA_HT&flags) {
+ psta->htpriv.ht_option = true;
+ psta->qos_option = 1;
+ memcpy(&psta->htpriv.ht_cap,
+ ¶m->u.add_sta.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
+ } else {
+ psta->htpriv.ht_option = false;
+ }
+
+ if (pmlmepriv->htpriv.ht_option == false)
+ psta->htpriv.ht_option = false;
+
+ update_sta_info_apmode(padapter, psta);
+ } else {
+ ret = -ENOMEM;
+ }
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_del_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct sta_info *psta = NULL;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ int updated = 0;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_del_sta: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_del_sta: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
+ return -EINVAL;
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+ return -EINVAL;
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (psta) {
+ spin_lock_bh(&pstapriv->asoc_list_lock);
+ if (!list_empty(&psta->asoc_list)) {
+ list_del_init(&psta->asoc_list);
+ pstapriv->asoc_list_cnt--;
+ updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
+ }
+ spin_unlock_bh(&pstapriv->asoc_list_lock);
+ associated_clients_update(padapter, updated);
+ psta = NULL;
+ } else {
+ DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
+ }
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_set_beacon_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ int len = 0;
+ unsigned char *pbuf = NULL;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_set_beacon: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_set_beacon: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ len = wrqu->data.length;
+ pbuf = param->u.bcn_ie.buf;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return -EINVAL;
+
+ memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
+
+ if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
+ pstapriv->max_num_sta = NUM_STA;
+
+ if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS) // 12 = Param header, 2 = Not packed.
+ ret = 0;
+ else
+ ret = -EINVAL;
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_set_encryption_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ int param_len = 0;
+ struct ieee_param *param = NULL;
+ u32 wep_key_idx, wep_key_len, wep_total_len;
+ struct ndis_802_11_wep *pwep = NULL;
+ struct sta_info *psta = NULL, *pbcmc_sta = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &(padapter->securitypriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ ret = -ENOMEM;
+ DBG_88E(" r871x_set_encryption: ieee_param allocate fail !!!\n");
+
+ goto exit;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" r871x_set_encryption: ieee_param get fail !!!\n");
+
+ goto exit;
+ }
+
+ param_len = wrqu->data.length;
+
+ DBG_88E("%s\n", __func__);
+ param->u.crypt.err = 0;
+ param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+ if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ if (param->u.crypt.idx >= WEP_KEYS) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ } else {
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
+ goto exit;
+ }
+ }
+
+ if (strcmp(param->u.crypt.alg, "none") == 0 && (!psta)) {
+ // TODO: Clear default encryption keys.
+
+ DBG_88E("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
+ goto exit;
+ }
+ if (strcmp(param->u.crypt.alg, "WEP") == 0 && (!psta)) {
+ DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
+ wep_key_idx = param->u.crypt.idx;
+ wep_key_len = param->u.crypt.key_len;
+ DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
+ if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (wep_key_len > 0) {
+ wep_key_len = wep_key_len <= 5 ? 5 : 13;
+ wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
+ pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
+ if (!pwep) {
+ DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
+ goto exit;
+ }
+
+ memset(pwep, 0, wep_total_len);
+
+ pwep->KeyLength = wep_key_len;
+ pwep->Length = wep_total_len;
+ }
+
+ pwep->KeyIndex = wep_key_idx;
+
+ memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
+
+ if (param->u.crypt.set_tx) {
+ DBG_88E("wep, set_tx = 1\n");
+
+ psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
+ psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
+ if (pwep->KeyLength == 13) {
+ psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ }
+
+ psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
+
+ memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
+ pwep->KeyMaterial,
+ pwep->KeyLength);
+
+ psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
+
+ set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
+ } else {
+ DBG_88E("wep, set_tx = 0\n");
+
+ /*
+ * Don't update "psecuritypriv->dot11PrivacyAlgrthm" and
+ * "psecuritypriv->dot11PrivacyKeyIndex = keyid", but rtw_set_key()
+ * can to cam.
+ */
+
+ memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
+ pwep->KeyMaterial,
+ pwep->KeyLength);
+
+ psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
+
+ set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
+ }
+
+ goto exit;
+ }
+
+ if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { // Group key.
+ if (param->u.crypt.set_tx == 1) {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ DBG_88E("%s, set group_key, WEP\n", __func__);
+
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len,
+ 16));
+
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+ if (param->u.crypt.key_len == 13)
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ DBG_88E("%s, set group_key, TKIP\n", __func__);
+ psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len,
+ 16));
+ // Set mic key.
+ memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[16]),
+ 8);
+ memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[24]),
+ 8);
+
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ DBG_88E("%s, set group_key, CCMP\n", __func__);
+ psecuritypriv->dot118021XGrpPrivacy = _AES_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ } else {
+ DBG_88E("%s, set group_key, none\n", __func__);
+ psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+ }
+ psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+ psecuritypriv->binstallGrpkey = true;
+ psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
+ set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
+ pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+ if (pbcmc_sta) {
+ pbcmc_sta->ieee8021x_blocked = false;
+ pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; // rx will use bmc_sta's dot118021XPrivacy.
+ }
+ }
+ goto exit;
+ }
+
+ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { // psk/802_1x.
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+ if (param->u.crypt.set_tx == 1) {
+ memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
+
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ DBG_88E("%s, set pairwise key, WEP\n", __func__);
+
+ psta->dot118021XPrivacy = _WEP40_;
+ if (param->u.crypt.key_len == 13)
+ psta->dot118021XPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ DBG_88E("%s, set pairwise key, TKIP\n", __func__);
+
+ psta->dot118021XPrivacy = _TKIP_;
+
+ // Set mic key.
+ memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
+ memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
+
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ DBG_88E("%s, set pairwise key, CCMP\n", __func__);
+
+ psta->dot118021XPrivacy = _AES_;
+ } else {
+ DBG_88E("%s, set pairwise key, none\n", __func__);
+
+ psta->dot118021XPrivacy = _NO_PRIVACY_;
+ }
+
+ set_pairwise_key(padapter, psta);
+
+ psta->ieee8021x_blocked = false;
+ } else { // Group key ?
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+ if (param->u.crypt.key_len == 13)
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+
+ // Set mic key.
+ memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[16]), 8);
+ memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[24]), 8);
+
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ psecuritypriv->dot118021XGrpPrivacy = _AES_;
+
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ } else {
+ psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+ }
+
+ psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+ psecuritypriv->binstallGrpkey = true;
+ psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
+
+ set_group_key(padapter,
+ param->u.crypt.key,
+ psecuritypriv->dot118021XGrpPrivacy,
+ param->u.crypt.idx);
+
+ pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+ if (pbcmc_sta) {
+ pbcmc_sta->ieee8021x_blocked = false;
+ pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; // rx will use bmc_sta's dot118021XPrivacy.
+ }
+ }
+ }
+ }
+
+exit:
+
+ kfree(pwep);
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_get_sta_wpaie_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct sta_info *psta = NULL;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_get_sta_wpaie: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_get_sta_wpaie: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
+ return -EINVAL;
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+ return -EINVAL;
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (psta) {
+ if (psta->wpa_ie[0] == WLAN_EID_RSN ||
+ psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
+ int wpa_ie_len;
+ int copy_len;
+
+ wpa_ie_len = psta->wpa_ie[1];
+ copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
+ param->u.wpa_ie.len = copy_len;
+ memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
+ } else {
+ DBG_88E("sta's wpa_ie is NONE\n");
+ }
+ } else {
+ ret = -1;
+ }
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_set_wps_beacon_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct ieee_param *param = NULL;
+ unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ int len, ie_len;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_set_wps_beacon: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_set_wps_beacon: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return -EINVAL;
+
+ ie_len = len-12-2; // 12 = Param header, 2 = Not packed.
+
+ kfree(pmlmepriv->wps_beacon_ie);
+ pmlmepriv->wps_beacon_ie = NULL;
+
+ if (ie_len > 0) {
+ pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
+ pmlmepriv->wps_beacon_ie_len = ie_len;
+ if (!pmlmepriv->wps_beacon_ie) {
+ DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
+ update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
+
+ pmlmeext->bstart_bss = true;
+ }
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_set_wps_probe_resp_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ int len, ie_len;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_set_wps_probe_resp: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_set_wps_probe_resp: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return -EINVAL;
+
+ ie_len = len-12-2; // 12 = Param header, 2 = Not packed.
+
+ kfree(pmlmepriv->wps_probe_resp_ie);
+ pmlmepriv->wps_probe_resp_ie = NULL;
+
+ if (ie_len > 0) {
+ pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
+ pmlmepriv->wps_probe_resp_ie_len = ie_len;
+ if (!pmlmepriv->wps_probe_resp_ie) {
+ DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
+ }
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_set_wps_assoc_resp_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ int len, ie_len;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_set_wps_assoc_resp: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_set_wps_assoc_resp: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return -EINVAL;
+
+ ie_len = len-12-2; // 12 = Param header, 2 = Not packed.
+
+ kfree(pmlmepriv->wps_assoc_resp_ie);
+ pmlmepriv->wps_assoc_resp_ie = NULL;
+
+ if (ie_len > 0) {
+ pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
+ pmlmepriv->wps_assoc_resp_ie_len = ie_len;
+ if (!pmlmepriv->wps_assoc_resp_ie) {
+ DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
+ }
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_set_hidden_ssid_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ u8 value;
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_set_hidden_ssid: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_set_hidden_ssid: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return -EINVAL;
+
+ if (param->u.wpa_param.name != 0) // Dummy test.
+ DBG_88E("%s name(%u) != 0\n", __func__, param->u.wpa_param.name);
+ value = param->u.wpa_param.value;
+
+ // Use the same definition of hostapd's ignore_broadcast_ssid.
+ if (value != 1 && value != 2)
+ value = 0;
+ DBG_88E("%s value(%u)\n", __func__, value);
+ pmlmeinfo->hidden_ssid_mode = value;
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_ioctl_get_sta_data_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct sta_info *psta = NULL;
+ struct sta_data *psta_data = NULL;
+ struct ieee_param_ex *param_ex = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ param_ex = (struct ieee_param_ex *)rtw_malloc(wrqu->data.length);
+
+ if (!param_ex) {
+ DBG_88E(" rtw_ioctl_get_sta_data: ieee_param_ex allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param_ex);
+
+ if (ret != 0) {
+ kfree(param_ex);
+ DBG_88E(" rtw_ioctl_get_sta_data: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ psta_data = (struct sta_data *)param_ex->data;
+
+ DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
+ return -EINVAL;
+
+ if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
+ param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
+ param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
+ return -EINVAL;
+
+ psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
+ if (psta) {
+ psta_data->aid = (u16)psta->aid;
+ psta_data->capability = psta->capability;
+ psta_data->flags = psta->flags;
+
+ /*
+ nonerp_set : BIT(0)
+ no_short_slot_time_set : BIT(1)
+ no_short_preamble_set : BIT(2)
+ no_ht_gf_set : BIT(3)
+ no_ht_set : BIT(4)
+ ht_20mhz_set : BIT(5)
+ */
+
+ psta_data->sta_set = \
+ ((psta->nonerp_set) |
+ (psta->no_short_slot_time_set << 1) |
+ (psta->no_short_preamble_set << 2) |
+ (psta->no_ht_gf_set << 3) |
+ (psta->no_ht_set << 4) |
+ (psta->ht_20mhz_set << 5));
+ psta_data->tx_supp_rates_len = psta->bssratelen;
+ memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
+ memcpy(&psta_data->ht_cap,
+ &psta->htpriv.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
+ psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
+ psta_data->rx_bytes = psta->sta_stats.rx_bytes;
+ psta_data->rx_drops = psta->sta_stats.rx_drops;
+ psta_data->tx_pkts = psta->sta_stats.tx_pkts;
+ psta_data->tx_bytes = psta->sta_stats.tx_bytes;
+ psta_data->tx_drops = psta->sta_stats.tx_drops;
+ } else {
+ ret = -1;
+ }
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param_ex, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_ioctl_set_macaddr_acl_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_ioctl_set_macaddr_acl: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_ioctl_set_macaddr_acl: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return -EINVAL;
+
+ rtw_set_macaddr_acl(padapter, param->u.mlme.command);
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_ioctl_acl_add_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_ioctl_acl_add_sta: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_ioctl_acl_add_sta: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return -EINVAL;
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+ return -EINVAL;
+
+ ret = rtw_acl_add_sta(padapter, param->sta_addr);
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int rtw_ioctl_acl_remove_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret = 0;
+ struct ieee_param *param = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
+
+ if (!param) {
+ DBG_88E(" rtw_ioctl_acl_remove_sta: ieee_param allocate fail !!!\n");
+
+ return -ENOMEM;
+ }
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+
+ if (ret != 0) {
+ kfree(param);
+ DBG_88E(" rtw_ioctl_acl_remove_sta: ieee_param get fail !!!\n");
+
+ return ret;
+ }
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return -EINVAL;
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+ return -EINVAL;
+
+ ret = rtw_acl_remove_sta(padapter, param->sta_addr);
+
+ if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static iw_handler rtw_handlers_private[] = {
+ NULL, // Empty
+ rtw_hostapd_sta_flush_pvt, // RTL871X_HOSTAPD_FLUSH
+ rtw_add_sta_pvt, // RTL871X_HOSTAPD_ADD_STA
+ rtw_del_sta_pvt, // RTL871X_HOSTAPD_REMOVE_STA
+ rtw_ioctl_get_sta_data_pvt, // RTL871X_HOSTAPD_GET_INFO_STA
+ rtw_get_sta_wpaie_pvt, // RTL871X_HOSTAPD_GET_WPAIE_STA
+ rtw_set_encryption_pvt, // RTL871X_SET_ENCRYPTION
+ NULL, // RTL871X_GET_ENCRYPTION
+ NULL, // RTL871X_HOSTAPD_SET_FLAGS_STA
+ NULL, // RTL871X_HOSTAPD_GET_RID
+ NULL, // RTL871X_HOSTAPD_SET_RID
+ NULL, // RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR
+ NULL, // RTL871X_HOSTAPD_SET_GENERIC_ELEMENT
+ NULL, // RTL871X_HOSTAPD_MLME
+ NULL, // RTL871X_HOSTAPD_SCAN_REQ
+ NULL, // RTL871X_HOSTAPD_STA_CLEAR_STATS
+ rtw_set_beacon_pvt, // RTL871X_HOSTAPD_SET_BEACON
+ rtw_set_wps_beacon_pvt, // RTL871X_HOSTAPD_SET_WPS_BEACON
+ rtw_set_wps_probe_resp_pvt, // RTL871X_HOSTAPD_SET_WPS_PROBE_RESP
+ rtw_set_wps_assoc_resp_pvt, // RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP
+ rtw_set_hidden_ssid_pvt, // RTL871X_HOSTAPD_SET_HIDDEN_SSID
+ rtw_ioctl_set_macaddr_acl_pvt, // RTL871X_HOSTAPD_SET_MACADDR_ACL
+ rtw_ioctl_acl_add_sta_pvt, // RTL871X_HOSTAPD_ACL_ADD_STA
+ rtw_ioctl_acl_remove_sta_pvt, // RTL871X_HOSTAPD_ACL_REMOVE_STA
+};
+
static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
{
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
@@ -3089,6 +4129,8 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
struct iw_handler_def rtw_handlers_def = {
.standard = rtw_handlers,
.num_standard = ARRAY_SIZE(rtw_handlers),
+ .private = rtw_handlers_private,
+ .num_private = ARRAY_SIZE(rtw_handlers_private),
.get_wireless_stats = rtw_get_wireless_stats,
};
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-23 1:29 [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls ishraq.i.ashraf
@ 2017-11-23 13:24 ` Dan Carpenter
2017-11-25 0:52 ` [PATCH 2/2] " ishraq.i.ashraf
` (4 subsequent siblings)
5 siblings, 0 replies; 17+ messages in thread
From: Dan Carpenter @ 2017-11-23 13:24 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: gregkh, devel, insafonov, goudapatilk, linux-kernel,
himanshujha199640, Johannes Berg
On Thu, Nov 23, 2017 at 02:29:06AM +0100, ishraq.i.ashraf@gmail.com wrote:
> From: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
>
> Commit 8bfb36766064 ("wireless: wext: remove ndo_do_ioctl fallback") breaks private WEXT
> IOCTL calls of this driver as these are not invoked through ndo_do_ioctl
> interface anymore. As a result hostapd stops working with this driver. In
> this patch this problem is solved by implementing equivalent private IOCTL
> functions of the existing ones which are accessed via iw_handler_def
> interface.
>
> Signed-off-by: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
It's great to fix this, but new code should be at normal kernel quality.
> ---
> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1042 ++++++++++++++++++++++++
> 1 file changed, 1042 insertions(+)
>
> diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
> index c0664dc..7503751 100644
> --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
> +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
> @@ -3061,6 +3061,1046 @@ static iw_handler rtw_handlers[] = {
> NULL, /*---hole---*/
> };
>
> +static int get_private_handler_ieee_param(struct adapter *padapter,
> + union iwreq_data *wrqu,
> + void *param)
Indent these more.
> +{
> + /*
> + * This function is expected to be called in master mode, which allows no
> + * power saving. So we just check hw_init_completed.
> + */
> +
> + if (!padapter->hw_init_completed)
> + return -EPERM;
> +
> + if (!wrqu->data.pointer)
> + return -EINVAL;
You could leave this out and it will return -EFAULT when copy_from_user()
fails. That's probably the right error code.
> +
> + /*
> + * Since we don't allocate memory for param in this function, we assume
> + * the caller of this function will properly allocate and deallocate memory
> + * for param.
> + */
This is an obvious comment. Remove it.
> + if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> +
> + DBG_88E("%s\n", __func__);
Remove this line.
> +
> + flush_all_cam_entry(padapter); // Clear CAM.
Comment style.
> +
> + return rtw_sta_flush(padapter);
> +}
> +
> +static int rtw_add_sta_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret = 0;
> + struct sta_info *psta = NULL;
> + struct ieee_param *param = NULL;
Don't initialize these to useless values. It turns off the static
checker for finding uninitialized variables.
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> + struct sta_priv *pstapriv = &padapter->stapriv;
> +
> + param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
rtw_malloc() is buggy. It ignores locking. Let's not use it in new
code.
> +
> + if (!param) {
> + DBG_88E(" rtw_add_sta: ieee_param allocate fail !!!\n");
No need to print this debug message.
> +
> + return -ENOMEM;
> + }
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> +
> + if (ret != 0) {
if (ret). "ret" isn't a number zero which can be used for math like
"ret + 2", it's an error code. The != 0 is a double negative which
hurts readability. != 0 is appropriate for numbers and strcmp()
functions.
> + kfree(param);
Free this at the end of the function.
> + DBG_88E(" rtw_add_sta: ieee_param get fail !!!\n");
These messages are so ugly !!!
> +
> + return ret;
> + }
> +
> + DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
> +
> + if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
> + return -EINVAL;
ret = -EINVAL;
goto err_free_param;
> +
> + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
> + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
> + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
> + return -EINVAL;
ret = -EINVAL;
goto err_free_param;
> +
> + psta = rtw_get_stainfo(pstapriv, param->sta_addr);
> + if (psta) {
Always do failure handling. Never do success handling. So this becomes:
if (!psta)
goto err_free_param;
> + int flags = param->u.add_sta.flags;
> + psta->aid = param->u.add_sta.aid; // aid = 1~2007.
> +
> + memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
> +
> + // Check WMM cap.
Comment style
> + if (WLAN_STA_WME&flags)
> + psta->qos_option = 1;
> + else
> + psta->qos_option = 0;
> +
> + if (pmlmepriv->qospriv.qos_option == 0)
> + psta->qos_option = 0;
> +
> + // Check 802.11n HT cap.
> + if (WLAN_STA_HT&flags) {
> + psta->htpriv.ht_option = true;
> + psta->qos_option = 1;
> + memcpy(&psta->htpriv.ht_cap,
> + ¶m->u.add_sta.ht_cap,
> + sizeof(struct ieee80211_ht_cap));
> + } else {
> + psta->htpriv.ht_option = false;
> + }
> +
> + if (pmlmepriv->htpriv.ht_option == false)
> + psta->htpriv.ht_option = false;
> +
> + update_sta_info_apmode(padapter, psta);
> + } else {
> + ret = -ENOMEM;
> + }
> +
> + if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
> + ret = -EFAULT;
We need to free param.
> +
> + return ret;
The end of the function could look like this:
update_sta_info_apmode(padapter, psta);
if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
err_free_param:
kfree(param);
return ret;
> +}
> +
> +static int rtw_del_sta_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret = 0;
> + struct sta_info *psta = NULL;
> + struct ieee_param *param = NULL;
Remove initialization.
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> + struct sta_priv *pstapriv = &padapter->stapriv;
> + int updated = 0;
> +
> + param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
Use kmalloc(); Basically all the same stuff as the previous function.
regards,
dan carpenter
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 2/2] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-23 1:29 [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls ishraq.i.ashraf
2017-11-23 13:24 ` Dan Carpenter
@ 2017-11-25 0:52 ` ishraq.i.ashraf
2017-11-25 4:40 ` Dan Carpenter
2017-11-25 1:29 ` [PATCH v2] " ishraq.i.ashraf
` (3 subsequent siblings)
5 siblings, 1 reply; 17+ messages in thread
From: ishraq.i.ashraf @ 2017-11-25 0:52 UTC (permalink / raw)
To: gregkh
Cc: himanshujha199640, goudapatilk, insafonov, dan.carpenter, devel,
linux-kernel, Ishraq Ibne Ashraf
From: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
Apply changes suggested by Dan Carpenter
---
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1052 ++++++++++++------------
1 file changed, 536 insertions(+), 516 deletions(-)
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index 7503751..e871344 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -3062,25 +3062,16 @@ static iw_handler rtw_handlers[] = {
};
static int get_private_handler_ieee_param(struct adapter *padapter,
- union iwreq_data *wrqu,
- void *param)
+ union iwreq_data *wrqu,
+ void *param)
{
/*
* This function is expected to be called in master mode, which allows no
* power saving. So we just check hw_init_completed.
*/
-
if (!padapter->hw_init_completed)
return -EPERM;
- if (!wrqu->data.pointer)
- return -EINVAL;
-
- /*
- * Since we don't allocate memory for param in this function, we assume
- * the caller of this function will properly allocate and deallocate memory
- * for param.
- */
if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length))
return -EFAULT;
@@ -3088,305 +3079,310 @@ static int get_private_handler_ieee_param(struct adapter *padapter,
}
static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
- DBG_88E("%s\n", __func__);
-
- flush_all_cam_entry(padapter); // Clear CAM.
-
+ flush_all_cam_entry(padapter); /* Clear CAM. */
return rtw_sta_flush(padapter);
}
static int rtw_add_sta_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct sta_info *psta = NULL;
- struct ieee_param *param = NULL;
+ int ret;
+ int flags;
+ struct sta_info *psta;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_add_sta: ieee_param allocate fail !!!\n");
-
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_add_sta: ieee_param get fail !!!\n");
+ DBG_88E("rtw_add_sta(aid =%d) =%pM\n",
+ param->u.add_sta.aid,
+ (param->sta_addr));
- return ret;
+ if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) {
+ ret = -EINVAL;
+ goto err_free_param;
}
- DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
-
- if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
- return -EINVAL;
-
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- return -EINVAL;
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
- if (psta) {
- int flags = param->u.add_sta.flags;
- psta->aid = param->u.add_sta.aid; // aid = 1~2007.
-
- memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
- // Check WMM cap.
- if (WLAN_STA_WME&flags)
- psta->qos_option = 1;
- else
- psta->qos_option = 0;
+ flags = param->u.add_sta.flags;
+ psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */
- if (pmlmepriv->qospriv.qos_option == 0)
- psta->qos_option = 0;
+ memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
- // Check 802.11n HT cap.
- if (WLAN_STA_HT&flags) {
- psta->htpriv.ht_option = true;
- psta->qos_option = 1;
- memcpy(&psta->htpriv.ht_cap,
- ¶m->u.add_sta.ht_cap,
- sizeof(struct ieee80211_ht_cap));
- } else {
- psta->htpriv.ht_option = false;
- }
+ /* Check WMM cap. */
+ if (WLAN_STA_WME&flags)
+ psta->qos_option = 1;
+ else
+ psta->qos_option = 0;
- if (pmlmepriv->htpriv.ht_option == false)
- psta->htpriv.ht_option = false;
+ if (pmlmepriv->qospriv.qos_option == 0)
+ psta->qos_option = 0;
- update_sta_info_apmode(padapter, psta);
+ /* Check 802.11n HT cap. */
+ if (WLAN_STA_HT&flags) {
+ psta->htpriv.ht_option = true;
+ psta->qos_option = 1;
+ memcpy(&psta->htpriv.ht_cap,
+ ¶m->u.add_sta.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
} else {
- ret = -ENOMEM;
+ psta->htpriv.ht_option = false;
}
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ if (pmlmepriv->htpriv.ht_option == false)
+ psta->htpriv.ht_option = false;
+
+ update_sta_info_apmode(padapter, psta);
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param:
+ kfree(param);
+ return ret;
}
static int rtw_del_sta_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct sta_info *psta = NULL;
- struct ieee_param *param = NULL;
+ int ret;
+ int updated;
+ struct sta_info *psta;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct sta_priv *pstapriv = &padapter->stapriv;
- int updated = 0;
-
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_del_sta: ieee_param allocate fail !!!\n");
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
-
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_del_sta: ieee_param get fail !!!\n");
-
- return ret;
- }
+ if (ret)
+ goto err_free_param;
DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
- if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
- return -EINVAL;
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- return -EINVAL;
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
- if (psta) {
- spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!list_empty(&psta->asoc_list)) {
- list_del_init(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
- updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
- associated_clients_update(padapter, updated);
- psta = NULL;
- } else {
+ if (!psta) {
DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ spin_lock_bh(&pstapriv->asoc_list_lock);
+
+ updated = 0;
+
+ if (!list_empty(&psta->asoc_list)) {
+ list_del_init(&psta->asoc_list);
+ pstapriv->asoc_list_cnt--;
+ updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
}
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ spin_unlock_bh(&pstapriv->asoc_list_lock);
+ associated_clients_update(padapter, updated);
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param:
+ kfree(param);
+ return ret;
}
static int rtw_set_beacon_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- int len = 0;
- unsigned char *pbuf = NULL;
- struct ieee_param *param = NULL;
+ int ret;
+ int len;
+ unsigned char *pbuf;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_set_beacon: ieee_param allocate fail !!!\n");
-
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
-
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_set_beacon: ieee_param get fail !!!\n");
-
- return ret;
- }
+ if (ret)
+ goto err_free_param;
len = wrqu->data.length;
pbuf = param->u.bcn_ie.buf;
DBG_88E("%s, len =%d\n", __func__, len);
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
pstapriv->max_num_sta = NUM_STA;
- if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS) // 12 = Param header, 2 = Not packed.
- ret = 0;
- else
+ if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) != _SUCCESS) { /* 12 = Param header, 2 = Not packed. */
ret = -EINVAL;
+ goto err_free_param;
+ }
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param:
+ kfree(param);
+ return ret;
}
static int rtw_set_encryption_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- int param_len = 0;
- struct ieee_param *param = NULL;
- u32 wep_key_idx, wep_key_len, wep_total_len;
- struct ndis_802_11_wep *pwep = NULL;
- struct sta_info *psta = NULL, *pbcmc_sta = NULL;
+ int ret;
+ int param_len;
+ u32 wep_key_idx;
+ u32 wep_key_len;
+ u32 wep_total_len;
+ struct sta_info *psta;
+ struct ieee_param *param;
+ struct sta_info *pbcmc_sta;
+ struct ndis_802_11_wep *pwep;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &(padapter->securitypriv);
struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &(padapter->securitypriv);
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- ret = -ENOMEM;
- DBG_88E(" r871x_set_encryption: ieee_param allocate fail !!!\n");
-
- goto exit;
- }
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
ret = get_private_handler_ieee_param(padapter, wrqu, param);
-
- if (ret != 0) {
- kfree(param);
- DBG_88E(" r871x_set_encryption: ieee_param get fail !!!\n");
-
- goto exit;
- }
+ if (ret)
+ goto err_free_param;
param_len = wrqu->data.length;
-
- DBG_88E("%s\n", __func__);
param->u.crypt.err = 0;
param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+
if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
ret = -EINVAL;
- goto exit;
+ goto err_free_param;
}
+
+ psta = NULL;
+
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
if (param->u.crypt.idx >= WEP_KEYS) {
ret = -EINVAL;
- goto exit;
+ goto err_free_param;
}
} else {
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
if (!psta) {
DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
- goto exit;
+ ret = -ENOMEM;
+ goto err_free_param;
}
}
if (strcmp(param->u.crypt.alg, "none") == 0 && (!psta)) {
- // TODO: Clear default encryption keys.
-
- DBG_88E("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
- goto exit;
+ /* TODO: Clear default encryption keys. */
+ DBG_88E("clear default encryption keys, keyid =%d\n",
+ param->u.crypt.idx);
+ ret = -EINVAL;
+ goto err_free_param;
}
+
+ pwep = NULL;
+
if (strcmp(param->u.crypt.alg, "WEP") == 0 && (!psta)) {
DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
+
wep_key_idx = param->u.crypt.idx;
wep_key_len = param->u.crypt.key_len;
- DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
+
+ DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n",
+ wep_key_idx,
+ wep_key_len);
+
if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
ret = -EINVAL;
- goto exit;
+ goto err_free_param;
}
if (wep_key_len > 0) {
wep_key_len = wep_key_len <= 5 ? 5 : 13;
wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
- pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
+
+ pwep = (struct ndis_802_11_wep *)kmalloc(wep_total_len, GFP_KERNEL);
if (!pwep) {
DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
- goto exit;
+ ret = -ENOMEM;
+ goto err_free_param;
}
memset(pwep, 0, wep_total_len);
-
pwep->KeyLength = wep_key_len;
pwep->Length = wep_total_len;
}
pwep->KeyIndex = wep_key_idx;
-
memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
if (param->u.crypt.set_tx) {
@@ -3402,13 +3398,10 @@ static int rtw_set_encryption_pvt(struct net_device *dev,
}
psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
-
memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
pwep->KeyMaterial,
pwep->KeyLength);
-
psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
-
set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
} else {
DBG_88E("wep, set_tx = 0\n");
@@ -3422,16 +3415,19 @@ static int rtw_set_encryption_pvt(struct net_device *dev,
memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
pwep->KeyMaterial,
pwep->KeyLength);
-
psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
-
set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
}
- goto exit;
+ ret = 0;
+
+ if (pwep)
+ goto err_free_pwep_param;
+ else
+ goto err_free_param;
}
- if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { // Group key.
+ if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* Group key. */
if (param->u.crypt.set_tx == 1) {
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
DBG_88E("%s, set group_key, WEP\n", __func__);
@@ -3440,69 +3436,80 @@ static int rtw_set_encryption_pvt(struct net_device *dev,
param->u.crypt.key,
min_t(u16, param->u.crypt.key_len,
16));
-
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
if (param->u.crypt.key_len == 13)
- psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
DBG_88E("%s, set group_key, TKIP\n", __func__);
+
psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
param->u.crypt.key,
min_t(u16, param->u.crypt.key_len,
16));
- // Set mic key.
+ /* Set mic key. */
memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
&(param->u.crypt.key[16]),
8);
memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
&(param->u.crypt.key[24]),
8);
-
psecuritypriv->busetkipkey = true;
} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
DBG_88E("%s, set group_key, CCMP\n", __func__);
+
psecuritypriv->dot118021XGrpPrivacy = _AES_;
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
param->u.crypt.key,
min_t(u16, param->u.crypt.key_len, 16));
} else {
DBG_88E("%s, set group_key, none\n", __func__);
+
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
}
+
psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
psecuritypriv->binstallGrpkey = true;
psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
+
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
if (pbcmc_sta) {
pbcmc_sta->ieee8021x_blocked = false;
- pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; // rx will use bmc_sta's dot118021XPrivacy.
+ pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy. */
}
}
- goto exit;
+
+ ret = 0;
+
+ if (pwep)
+ goto err_free_pwep_param;
+ else
+ goto err_free_param;
}
- if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { // psk/802_1x.
+ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x. */
if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
if (param->u.crypt.set_tx == 1) {
- memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
+ memcpy(psta->dot118021x_UncstKey.skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
DBG_88E("%s, set pairwise key, WEP\n", __func__);
psta->dot118021XPrivacy = _WEP40_;
+
if (param->u.crypt.key_len == 13)
psta->dot118021XPrivacy = _WEP104_;
} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
DBG_88E("%s, set pairwise key, TKIP\n", __func__);
psta->dot118021XPrivacy = _TKIP_;
-
- // Set mic key.
+ /* Set mic key. */
memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
-
psecuritypriv->busetkipkey = true;
} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
DBG_88E("%s, set pairwise key, CCMP\n", __func__);
@@ -3517,31 +3524,28 @@ static int rtw_set_encryption_pvt(struct net_device *dev,
set_pairwise_key(padapter, psta);
psta->ieee8021x_blocked = false;
- } else { // Group key ?
+ } else { /* Group key ? */
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
param->u.crypt.key,
min_t(u16, param->u.crypt.key_len, 16));
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
if (param->u.crypt.key_len == 13)
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
-
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
param->u.crypt.key,
min_t(u16, param->u.crypt.key_len, 16));
-
- // Set mic key.
+ /* Set mic key. */
memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
&(param->u.crypt.key[16]), 8);
memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
&(param->u.crypt.key[24]), 8);
-
psecuritypriv->busetkipkey = true;
} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
psecuritypriv->dot118021XGrpPrivacy = _AES_;
-
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
param->u.crypt.key,
min_t(u16, param->u.crypt.key_len, 16));
@@ -3552,553 +3556,569 @@ static int rtw_set_encryption_pvt(struct net_device *dev,
psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
psecuritypriv->binstallGrpkey = true;
psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
-
set_group_key(padapter,
- param->u.crypt.key,
- psecuritypriv->dot118021XGrpPrivacy,
- param->u.crypt.idx);
+ param->u.crypt.key,
+ psecuritypriv->dot118021XGrpPrivacy,
+ param->u.crypt.idx);
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
if (pbcmc_sta) {
pbcmc_sta->ieee8021x_blocked = false;
- pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; // rx will use bmc_sta's dot118021XPrivacy.
+ pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy. */
}
}
}
}
-exit:
-
- kfree(pwep);
+ ret = 0;
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ if (pwep)
+ goto err_free_pwep_param;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+
+ err_free_pwep_param:
+ kfree(pwep);
+ kfree(param);
+ return ret;
}
static int rtw_get_sta_wpaie_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct sta_info *psta = NULL;
- struct ieee_param *param = NULL;
+ int ret;
+ struct sta_info *psta;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_get_sta_wpaie: ieee_param allocate fail !!!\n");
-
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
-
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_get_sta_wpaie: ieee_param get fail !!!\n");
-
- return ret;
- }
+ if (!ret)
+ goto err_free_param;
DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr));
- if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
- return -EINVAL;
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- return -EINVAL;
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
- if (psta) {
- if (psta->wpa_ie[0] == WLAN_EID_RSN ||
- psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
- int wpa_ie_len;
- int copy_len;
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
- wpa_ie_len = psta->wpa_ie[1];
- copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
- param->u.wpa_ie.len = copy_len;
- memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
- } else {
- DBG_88E("sta's wpa_ie is NONE\n");
- }
+ if (psta->wpa_ie[0] == WLAN_EID_RSN ||
+ psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
+ int copy_len;
+ int wpa_ie_len;
+
+ wpa_ie_len = psta->wpa_ie[1];
+ copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
+ param->u.wpa_ie.len = copy_len;
+ memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
} else {
- ret = -1;
+ DBG_88E("sta's wpa_ie is NONE\n");
}
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param:
+ kfree(param);
+ return ret;
}
static int rtw_set_wps_beacon_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct ieee_param *param = NULL;
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- int len, ie_len;
-
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_set_wps_beacon: ieee_param allocate fail !!!\n");
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
-
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_set_wps_beacon: ieee_param get fail !!!\n");
-
- return ret;
- }
+ if (ret)
+ goto err_free_param;
len = wrqu->data.length;
DBG_88E("%s, len =%d\n", __func__, len);
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
-
- ie_len = len-12-2; // 12 = Param header, 2 = Not packed.
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
kfree(pmlmepriv->wps_beacon_ie);
pmlmepriv->wps_beacon_ie = NULL;
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
if (ie_len > 0) {
- pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
- pmlmepriv->wps_beacon_ie_len = ie_len;
+ pmlmepriv->wps_beacon_ie = kmalloc(ie_len, GFP_KERNEL);
if (!pmlmepriv->wps_beacon_ie) {
- DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
- return -EINVAL;
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
}
+ pmlmepriv->wps_beacon_ie_len = ie_len;
memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
-
pmlmeext->bstart_bss = true;
}
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ if (pmlmepriv->wps_beacon_ie)
+ goto err_free_param_wps_beacon_ie;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+
+ err_free_param_wps_beacon_ie:
+ kfree(pmlmepriv->wps_beacon_ie);
+ kfree(param);
+ return ret;
+
}
static int rtw_set_wps_probe_resp_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct ieee_param *param = NULL;
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- int len, ie_len;
-
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_set_wps_probe_resp: ieee_param allocate fail !!!\n");
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
-
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_set_wps_probe_resp: ieee_param get fail !!!\n");
-
- return ret;
- }
+ if (ret)
+ goto err_free_param;
len = wrqu->data.length;
DBG_88E("%s, len =%d\n", __func__, len);
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
-
- ie_len = len-12-2; // 12 = Param header, 2 = Not packed.
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
kfree(pmlmepriv->wps_probe_resp_ie);
pmlmepriv->wps_probe_resp_ie = NULL;
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
if (ie_len > 0) {
- pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
- pmlmepriv->wps_probe_resp_ie_len = ie_len;
+ pmlmepriv->wps_probe_resp_ie = kmalloc(ie_len, GFP_KERNEL);
if (!pmlmepriv->wps_probe_resp_ie) {
- DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
- return -EINVAL;
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
}
+
+ pmlmepriv->wps_probe_resp_ie_len = ie_len;
memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
}
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ if (pmlmepriv->wps_probe_resp_ie)
+ goto err_free_param_wps_probe_resp_ie;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+
+ err_free_param_wps_probe_resp_ie:
+ kfree(pmlmepriv->wps_probe_resp_ie);
+ kfree(param);
+ return ret;
}
static int rtw_set_wps_assoc_resp_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct ieee_param *param = NULL;
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- int len, ie_len;
-
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_set_wps_assoc_resp: ieee_param allocate fail !!!\n");
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
-
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_set_wps_assoc_resp: ieee_param get fail !!!\n");
-
- return ret;
- }
+ if (ret)
+ goto err_free_param;
len = wrqu->data.length;
DBG_88E("%s, len =%d\n", __func__, len);
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
-
- ie_len = len-12-2; // 12 = Param header, 2 = Not packed.
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
kfree(pmlmepriv->wps_assoc_resp_ie);
pmlmepriv->wps_assoc_resp_ie = NULL;
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
if (ie_len > 0) {
- pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
- pmlmepriv->wps_assoc_resp_ie_len = ie_len;
+ pmlmepriv->wps_assoc_resp_ie = kmalloc(ie_len, GFP_KERNEL);
if (!pmlmepriv->wps_assoc_resp_ie) {
- DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
- return -EINVAL;
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
}
+ pmlmepriv->wps_assoc_resp_ie_len = ie_len;
memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
}
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ if (pmlmepriv->wps_assoc_resp_ie)
+ goto err_free_param_wps_assoc_resp_ie;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+
+ err_free_param_wps_assoc_resp_ie:
+ kfree(pmlmepriv->wps_assoc_resp_ie);
+ kfree(param);
+ return ret;
}
static int rtw_set_hidden_ssid_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct ieee_param *param = NULL;
+ int ret;
+ u8 value;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- u8 value;
-
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_set_hidden_ssid: ieee_param allocate fail !!!\n");
-
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_set_hidden_ssid: ieee_param get fail !!!\n");
-
- return ret;
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
}
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
-
- if (param->u.wpa_param.name != 0) // Dummy test.
+ if (param->u.wpa_param.name != 0) /* Dummy test. */
DBG_88E("%s name(%u) != 0\n", __func__, param->u.wpa_param.name);
+
value = param->u.wpa_param.value;
- // Use the same definition of hostapd's ignore_broadcast_ssid.
+ /* Use the same definition of hostapd's ignore_broadcast_ssid. */
if (value != 1 && value != 2)
value = 0;
+
DBG_88E("%s value(%u)\n", __func__, value);
+
pmlmeinfo->hidden_ssid_mode = value;
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param:
+ kfree(param);
+ return ret;
}
static int rtw_ioctl_get_sta_data_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct sta_info *psta = NULL;
- struct sta_data *psta_data = NULL;
- struct ieee_param_ex *param_ex = NULL;
+ int ret;
+ struct sta_info *psta;
+ struct sta_data *psta_data;
+ struct ieee_param_ex *param_ex;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct sta_priv *pstapriv = &padapter->stapriv;
- param_ex = (struct ieee_param_ex *)rtw_malloc(wrqu->data.length);
-
- if (!param_ex) {
- DBG_88E(" rtw_ioctl_get_sta_data: ieee_param_ex allocate fail !!!\n");
-
+ param_ex = (struct ieee_param_ex *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param_ex)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param_ex);
-
- if (ret != 0) {
- kfree(param_ex);
- DBG_88E(" rtw_ioctl_get_sta_data: ieee_param get fail !!!\n");
-
- return ret;
- }
+ if (ret)
+ goto err_free_param_ex;
psta_data = (struct sta_data *)param_ex->data;
DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex->sta_addr));
- if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
- return -EINVAL;
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param_ex;
+ }
if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
- param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
- return -EINVAL;
+ param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param_ex;
+ }
psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
- if (psta) {
- psta_data->aid = (u16)psta->aid;
- psta_data->capability = psta->capability;
- psta_data->flags = psta->flags;
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param_ex;
+ }
- /*
- nonerp_set : BIT(0)
- no_short_slot_time_set : BIT(1)
- no_short_preamble_set : BIT(2)
- no_ht_gf_set : BIT(3)
- no_ht_set : BIT(4)
- ht_20mhz_set : BIT(5)
- */
+ psta_data->aid = (u16)psta->aid;
+ psta_data->capability = psta->capability;
+ psta_data->flags = psta->flags;
- psta_data->sta_set = \
- ((psta->nonerp_set) |
- (psta->no_short_slot_time_set << 1) |
- (psta->no_short_preamble_set << 2) |
- (psta->no_ht_gf_set << 3) |
- (psta->no_ht_set << 4) |
- (psta->ht_20mhz_set << 5));
- psta_data->tx_supp_rates_len = psta->bssratelen;
- memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
- memcpy(&psta_data->ht_cap,
- &psta->htpriv.ht_cap,
- sizeof(struct ieee80211_ht_cap));
- psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
- psta_data->rx_bytes = psta->sta_stats.rx_bytes;
- psta_data->rx_drops = psta->sta_stats.rx_drops;
- psta_data->tx_pkts = psta->sta_stats.tx_pkts;
- psta_data->tx_bytes = psta->sta_stats.tx_bytes;
- psta_data->tx_drops = psta->sta_stats.tx_drops;
- } else {
- ret = -1;
- }
+ /*
+ nonerp_set : BIT(0)
+ no_short_slot_time_set : BIT(1)
+ no_short_preamble_set : BIT(2)
+ no_ht_gf_set : BIT(3)
+ no_ht_set : BIT(4)
+ ht_20mhz_set : BIT(5)
+ */
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param_ex, wrqu->data.length)))
+ psta_data->sta_set = \
+ ((psta->nonerp_set) |
+ (psta->no_short_slot_time_set << 1) |
+ (psta->no_short_preamble_set << 2) |
+ (psta->no_ht_gf_set << 3) |
+ (psta->no_ht_set << 4) |
+ (psta->ht_20mhz_set << 5));
+ psta_data->tx_supp_rates_len = psta->bssratelen;
+ memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
+ memcpy(&psta_data->ht_cap,
+ &psta->htpriv.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
+ psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
+ psta_data->rx_bytes = psta->sta_stats.rx_bytes;
+ psta_data->rx_drops = psta->sta_stats.rx_drops;
+ psta_data->tx_pkts = psta->sta_stats.tx_pkts;
+ psta_data->tx_bytes = psta->sta_stats.tx_bytes;
+ psta_data->tx_drops = psta->sta_stats.tx_drops;
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param_ex, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param_ex:
+ kfree(param_ex);
+ return ret;
}
static int rtw_ioctl_set_macaddr_acl_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct ieee_param *param = NULL;
+ int ret;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_ioctl_set_macaddr_acl: ieee_param allocate fail !!!\n");
-
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_ioctl_set_macaddr_acl: ieee_param get fail !!!\n");
-
- return ret;
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
}
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
-
rtw_set_macaddr_acl(padapter, param->u.mlme.command);
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param:
+ kfree(param);
+ return ret;
}
static int rtw_ioctl_acl_add_sta_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct ieee_param *param = NULL;
+ int ret;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_ioctl_acl_add_sta: ieee_param allocate fail !!!\n");
-
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_ioctl_acl_add_sta: ieee_param get fail !!!\n");
-
- return ret;
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
}
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
-
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- return -EINVAL;
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
ret = rtw_acl_add_sta(padapter, param->sta_addr);
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param:
+ kfree(param);
+ return ret;
}
static int rtw_ioctl_acl_remove_sta_pvt(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- int ret = 0;
- struct ieee_param *param = NULL;
+ int ret;
+ struct ieee_param *param;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
-
- if (!param) {
- DBG_88E(" rtw_ioctl_acl_remove_sta: ieee_param allocate fail !!!\n");
-
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
return -ENOMEM;
- }
ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
- if (ret != 0) {
- kfree(param);
- DBG_88E(" rtw_ioctl_acl_remove_sta: ieee_param get fail !!!\n");
-
- return ret;
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
}
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
-
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- return -EINVAL;
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
ret = rtw_acl_remove_sta(padapter, param->sta_addr);
- if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
- return ret;
+ err_free_param:
+ kfree(param);
+ return ret;
}
static iw_handler rtw_handlers_private[] = {
- NULL, // Empty
- rtw_hostapd_sta_flush_pvt, // RTL871X_HOSTAPD_FLUSH
- rtw_add_sta_pvt, // RTL871X_HOSTAPD_ADD_STA
- rtw_del_sta_pvt, // RTL871X_HOSTAPD_REMOVE_STA
- rtw_ioctl_get_sta_data_pvt, // RTL871X_HOSTAPD_GET_INFO_STA
- rtw_get_sta_wpaie_pvt, // RTL871X_HOSTAPD_GET_WPAIE_STA
- rtw_set_encryption_pvt, // RTL871X_SET_ENCRYPTION
- NULL, // RTL871X_GET_ENCRYPTION
- NULL, // RTL871X_HOSTAPD_SET_FLAGS_STA
- NULL, // RTL871X_HOSTAPD_GET_RID
- NULL, // RTL871X_HOSTAPD_SET_RID
- NULL, // RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR
- NULL, // RTL871X_HOSTAPD_SET_GENERIC_ELEMENT
- NULL, // RTL871X_HOSTAPD_MLME
- NULL, // RTL871X_HOSTAPD_SCAN_REQ
- NULL, // RTL871X_HOSTAPD_STA_CLEAR_STATS
- rtw_set_beacon_pvt, // RTL871X_HOSTAPD_SET_BEACON
- rtw_set_wps_beacon_pvt, // RTL871X_HOSTAPD_SET_WPS_BEACON
- rtw_set_wps_probe_resp_pvt, // RTL871X_HOSTAPD_SET_WPS_PROBE_RESP
- rtw_set_wps_assoc_resp_pvt, // RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP
- rtw_set_hidden_ssid_pvt, // RTL871X_HOSTAPD_SET_HIDDEN_SSID
- rtw_ioctl_set_macaddr_acl_pvt, // RTL871X_HOSTAPD_SET_MACADDR_ACL
- rtw_ioctl_acl_add_sta_pvt, // RTL871X_HOSTAPD_ACL_ADD_STA
- rtw_ioctl_acl_remove_sta_pvt, // RTL871X_HOSTAPD_ACL_REMOVE_STA
+ NULL, /* Empty */
+ rtw_hostapd_sta_flush_pvt, /* RTL871X_HOSTAPD_FLUSH */
+ rtw_add_sta_pvt, /* RTL871X_HOSTAPD_ADD_STA */
+ rtw_del_sta_pvt, /* RTL871X_HOSTAPD_REMOVE_STA */
+ rtw_ioctl_get_sta_data_pvt, /* RTL871X_HOSTAPD_GET_INFO_STA */
+ rtw_get_sta_wpaie_pvt, /* RTL871X_HOSTAPD_GET_WPAIE_STA */
+ rtw_set_encryption_pvt, /* RTL871X_SET_ENCRYPTION */
+ NULL, /* RTL871X_GET_ENCRYPTION */
+ NULL, /* RTL871X_HOSTAPD_SET_FLAGS_STA */
+ NULL, /* RTL871X_HOSTAPD_GET_RID */
+ NULL, /* RTL871X_HOSTAPD_SET_RID */
+ NULL, /* RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR */
+ NULL, /* RTL871X_HOSTAPD_SET_GENERIC_ELEMENT */
+ NULL, /* RTL871X_HOSTAPD_MLME */
+ NULL, /* RTL871X_HOSTAPD_SCAN_REQ */
+ NULL, /* RTL871X_HOSTAPD_STA_CLEAR_STATS */
+ rtw_set_beacon_pvt, /* RTL871X_HOSTAPD_SET_BEACON */
+ rtw_set_wps_beacon_pvt, /* RTL871X_HOSTAPD_SET_WPS_BEACON */
+ rtw_set_wps_probe_resp_pvt, /* RTL871X_HOSTAPD_SET_WPS_PROBE_RESP */
+ rtw_set_wps_assoc_resp_pvt, /* RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP */
+ rtw_set_hidden_ssid_pvt, /* RTL871X_HOSTAPD_SET_HIDDEN_SSID */
+ rtw_ioctl_set_macaddr_acl_pvt, /* RTL871X_HOSTAPD_SET_MACADDR_ACL */
+ rtw_ioctl_acl_add_sta_pvt, /* RTL871X_HOSTAPD_ACL_ADD_STA */
+ rtw_ioctl_acl_remove_sta_pvt, /* RTL871X_HOSTAPD_ACL_REMOVE_STA */
};
static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-23 1:29 [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls ishraq.i.ashraf
2017-11-23 13:24 ` Dan Carpenter
2017-11-25 0:52 ` [PATCH 2/2] " ishraq.i.ashraf
@ 2017-11-25 1:29 ` ishraq.i.ashraf
2017-11-25 4:55 ` Dan Carpenter
2017-11-25 18:29 ` [PATCH v3] " ishraq.i.ashraf
` (2 subsequent siblings)
5 siblings, 1 reply; 17+ messages in thread
From: ishraq.i.ashraf @ 2017-11-25 1:29 UTC (permalink / raw)
To: gregkh
Cc: himanshujha199640, goudapatilk, insafonov, dan.carpenter, devel,
linux-kernel, Ishraq Ibne Ashraf
From: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
Commit 8bfb36766064 ("wireless: wext: remove ndo_do_ioctl fallback") breaks private WEXT
IOCTL calls of this driver as these are not invoked through ndo_do_ioctl
interface anymore. As a result hostapd stops working with this driver. In
this patch this problem is solved by implementing equivalent private IOCTL
functions of the existing ones which are accessed via iw_handler_def
interface.
Signed-off-by: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
---
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1062 ++++++++++++++++++++++++
1 file changed, 1062 insertions(+)
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index c0664dc..e871344 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -3061,6 +3061,1066 @@ static iw_handler rtw_handlers[] = {
NULL, /*---hole---*/
};
+static int get_private_handler_ieee_param(struct adapter *padapter,
+ union iwreq_data *wrqu,
+ void *param)
+{
+ /*
+ * This function is expected to be called in master mode, which allows no
+ * power saving. So we just check hw_init_completed.
+ */
+ if (!padapter->hw_init_completed)
+ return -EPERM;
+
+ if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ flush_all_cam_entry(padapter); /* Clear CAM. */
+ return rtw_sta_flush(padapter);
+}
+
+static int rtw_add_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int flags;
+ struct sta_info *psta;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ DBG_88E("rtw_add_sta(aid =%d) =%pM\n",
+ param->u.add_sta.aid,
+ (param->sta_addr));
+
+ if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ flags = param->u.add_sta.flags;
+ psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */
+
+ memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
+
+ /* Check WMM cap. */
+ if (WLAN_STA_WME&flags)
+ psta->qos_option = 1;
+ else
+ psta->qos_option = 0;
+
+ if (pmlmepriv->qospriv.qos_option == 0)
+ psta->qos_option = 0;
+
+ /* Check 802.11n HT cap. */
+ if (WLAN_STA_HT&flags) {
+ psta->htpriv.ht_option = true;
+ psta->qos_option = 1;
+ memcpy(&psta->htpriv.ht_cap,
+ ¶m->u.add_sta.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
+ } else {
+ psta->htpriv.ht_option = false;
+ }
+
+ if (pmlmepriv->htpriv.ht_option == false)
+ psta->htpriv.ht_option = false;
+
+ update_sta_info_apmode(padapter, psta);
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_del_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int updated;
+ struct sta_info *psta;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ spin_lock_bh(&pstapriv->asoc_list_lock);
+
+ updated = 0;
+
+ if (!list_empty(&psta->asoc_list)) {
+ list_del_init(&psta->asoc_list);
+ pstapriv->asoc_list_cnt--;
+ updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
+ }
+
+ spin_unlock_bh(&pstapriv->asoc_list_lock);
+ associated_clients_update(padapter, updated);
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_beacon_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int len;
+ unsigned char *pbuf;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ len = wrqu->data.length;
+ pbuf = param->u.bcn_ie.buf;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
+
+ if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
+ pstapriv->max_num_sta = NUM_STA;
+
+ if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) != _SUCCESS) { /* 12 = Param header, 2 = Not packed. */
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_encryption_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int param_len;
+ u32 wep_key_idx;
+ u32 wep_key_len;
+ u32 wep_total_len;
+ struct sta_info *psta;
+ struct ieee_param *param;
+ struct sta_info *pbcmc_sta;
+ struct ndis_802_11_wep *pwep;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &(padapter->securitypriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ param_len = wrqu->data.length;
+ param->u.crypt.err = 0;
+ param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+
+ if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ psta = NULL;
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ if (param->u.crypt.idx >= WEP_KEYS) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+ } else {
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+ }
+
+ if (strcmp(param->u.crypt.alg, "none") == 0 && (!psta)) {
+ /* TODO: Clear default encryption keys. */
+ DBG_88E("clear default encryption keys, keyid =%d\n",
+ param->u.crypt.idx);
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ pwep = NULL;
+
+ if (strcmp(param->u.crypt.alg, "WEP") == 0 && (!psta)) {
+ DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
+
+ wep_key_idx = param->u.crypt.idx;
+ wep_key_len = param->u.crypt.key_len;
+
+ DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n",
+ wep_key_idx,
+ wep_key_len);
+
+ if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (wep_key_len > 0) {
+ wep_key_len = wep_key_len <= 5 ? 5 : 13;
+ wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
+
+ pwep = (struct ndis_802_11_wep *)kmalloc(wep_total_len, GFP_KERNEL);
+ if (!pwep) {
+ DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ memset(pwep, 0, wep_total_len);
+ pwep->KeyLength = wep_key_len;
+ pwep->Length = wep_total_len;
+ }
+
+ pwep->KeyIndex = wep_key_idx;
+ memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
+
+ if (param->u.crypt.set_tx) {
+ DBG_88E("wep, set_tx = 1\n");
+
+ psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
+ psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
+ if (pwep->KeyLength == 13) {
+ psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ }
+
+ psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
+ memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
+ pwep->KeyMaterial,
+ pwep->KeyLength);
+ psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
+ set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
+ } else {
+ DBG_88E("wep, set_tx = 0\n");
+
+ /*
+ * Don't update "psecuritypriv->dot11PrivacyAlgrthm" and
+ * "psecuritypriv->dot11PrivacyKeyIndex = keyid", but rtw_set_key()
+ * can to cam.
+ */
+
+ memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
+ pwep->KeyMaterial,
+ pwep->KeyLength);
+ psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
+ set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
+ }
+
+ ret = 0;
+
+ if (pwep)
+ goto err_free_pwep_param;
+ else
+ goto err_free_param;
+ }
+
+ if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* Group key. */
+ if (param->u.crypt.set_tx == 1) {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ DBG_88E("%s, set group_key, WEP\n", __func__);
+
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len,
+ 16));
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
+ if (param->u.crypt.key_len == 13)
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ DBG_88E("%s, set group_key, TKIP\n", __func__);
+
+ psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len,
+ 16));
+ /* Set mic key. */
+ memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[16]),
+ 8);
+ memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[24]),
+ 8);
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ DBG_88E("%s, set group_key, CCMP\n", __func__);
+
+ psecuritypriv->dot118021XGrpPrivacy = _AES_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ } else {
+ DBG_88E("%s, set group_key, none\n", __func__);
+
+ psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+ }
+
+ psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+ psecuritypriv->binstallGrpkey = true;
+ psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
+ set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
+
+ pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+ if (pbcmc_sta) {
+ pbcmc_sta->ieee8021x_blocked = false;
+ pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy. */
+ }
+ }
+
+ ret = 0;
+
+ if (pwep)
+ goto err_free_pwep_param;
+ else
+ goto err_free_param;
+ }
+
+ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x. */
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+ if (param->u.crypt.set_tx == 1) {
+ memcpy(psta->dot118021x_UncstKey.skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ DBG_88E("%s, set pairwise key, WEP\n", __func__);
+
+ psta->dot118021XPrivacy = _WEP40_;
+
+ if (param->u.crypt.key_len == 13)
+ psta->dot118021XPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ DBG_88E("%s, set pairwise key, TKIP\n", __func__);
+
+ psta->dot118021XPrivacy = _TKIP_;
+ /* Set mic key. */
+ memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
+ memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ DBG_88E("%s, set pairwise key, CCMP\n", __func__);
+
+ psta->dot118021XPrivacy = _AES_;
+ } else {
+ DBG_88E("%s, set pairwise key, none\n", __func__);
+
+ psta->dot118021XPrivacy = _NO_PRIVACY_;
+ }
+
+ set_pairwise_key(padapter, psta);
+
+ psta->ieee8021x_blocked = false;
+ } else { /* Group key ? */
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
+ if (param->u.crypt.key_len == 13)
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ /* Set mic key. */
+ memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[16]), 8);
+ memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[24]), 8);
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ psecuritypriv->dot118021XGrpPrivacy = _AES_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ } else {
+ psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+ }
+
+ psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+ psecuritypriv->binstallGrpkey = true;
+ psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
+ set_group_key(padapter,
+ param->u.crypt.key,
+ psecuritypriv->dot118021XGrpPrivacy,
+ param->u.crypt.idx);
+
+ pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+ if (pbcmc_sta) {
+ pbcmc_sta->ieee8021x_blocked = false;
+ pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy. */
+ }
+ }
+ }
+ }
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ if (pwep)
+ goto err_free_pwep_param;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+
+ err_free_pwep_param:
+ kfree(pwep);
+ kfree(param);
+ return ret;
+}
+
+static int rtw_get_sta_wpaie_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct sta_info *psta;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (!ret)
+ goto err_free_param;
+
+ DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ if (psta->wpa_ie[0] == WLAN_EID_RSN ||
+ psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
+ int copy_len;
+ int wpa_ie_len;
+
+ wpa_ie_len = psta->wpa_ie[1];
+ copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
+ param->u.wpa_ie.len = copy_len;
+ memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
+ } else {
+ DBG_88E("sta's wpa_ie is NONE\n");
+ }
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_wps_beacon_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
+ unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ kfree(pmlmepriv->wps_beacon_ie);
+ pmlmepriv->wps_beacon_ie = NULL;
+
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
+ if (ie_len > 0) {
+ pmlmepriv->wps_beacon_ie = kmalloc(ie_len, GFP_KERNEL);
+ if (!pmlmepriv->wps_beacon_ie) {
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ pmlmepriv->wps_beacon_ie_len = ie_len;
+ memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
+ update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
+ pmlmeext->bstart_bss = true;
+ }
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ if (pmlmepriv->wps_beacon_ie)
+ goto err_free_param_wps_beacon_ie;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+
+ err_free_param_wps_beacon_ie:
+ kfree(pmlmepriv->wps_beacon_ie);
+ kfree(param);
+ return ret;
+
+}
+
+static int rtw_set_wps_probe_resp_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ kfree(pmlmepriv->wps_probe_resp_ie);
+ pmlmepriv->wps_probe_resp_ie = NULL;
+
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
+ if (ie_len > 0) {
+ pmlmepriv->wps_probe_resp_ie = kmalloc(ie_len, GFP_KERNEL);
+ if (!pmlmepriv->wps_probe_resp_ie) {
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ pmlmepriv->wps_probe_resp_ie_len = ie_len;
+ memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
+ }
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ if (pmlmepriv->wps_probe_resp_ie)
+ goto err_free_param_wps_probe_resp_ie;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+
+ err_free_param_wps_probe_resp_ie:
+ kfree(pmlmepriv->wps_probe_resp_ie);
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_wps_assoc_resp_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ kfree(pmlmepriv->wps_assoc_resp_ie);
+ pmlmepriv->wps_assoc_resp_ie = NULL;
+
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
+ if (ie_len > 0) {
+ pmlmepriv->wps_assoc_resp_ie = kmalloc(ie_len, GFP_KERNEL);
+ if (!pmlmepriv->wps_assoc_resp_ie) {
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ pmlmepriv->wps_assoc_resp_ie_len = ie_len;
+ memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
+ }
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ if (pmlmepriv->wps_assoc_resp_ie)
+ goto err_free_param_wps_assoc_resp_ie;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+
+ err_free_param_wps_assoc_resp_ie:
+ kfree(pmlmepriv->wps_assoc_resp_ie);
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_hidden_ssid_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ u8 value;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->u.wpa_param.name != 0) /* Dummy test. */
+ DBG_88E("%s name(%u) != 0\n", __func__, param->u.wpa_param.name);
+
+ value = param->u.wpa_param.value;
+
+ /* Use the same definition of hostapd's ignore_broadcast_ssid. */
+ if (value != 1 && value != 2)
+ value = 0;
+
+ DBG_88E("%s value(%u)\n", __func__, value);
+
+ pmlmeinfo->hidden_ssid_mode = value;
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_ioctl_get_sta_data_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct sta_info *psta;
+ struct sta_data *psta_data;
+ struct ieee_param_ex *param_ex;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ param_ex = (struct ieee_param_ex *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param_ex)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param_ex);
+ if (ret)
+ goto err_free_param_ex;
+
+ psta_data = (struct sta_data *)param_ex->data;
+
+ DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param_ex;
+ }
+
+ if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
+ param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
+ param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param_ex;
+ }
+
+ psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param_ex;
+ }
+
+ psta_data->aid = (u16)psta->aid;
+ psta_data->capability = psta->capability;
+ psta_data->flags = psta->flags;
+
+ /*
+ nonerp_set : BIT(0)
+ no_short_slot_time_set : BIT(1)
+ no_short_preamble_set : BIT(2)
+ no_ht_gf_set : BIT(3)
+ no_ht_set : BIT(4)
+ ht_20mhz_set : BIT(5)
+ */
+
+ psta_data->sta_set = \
+ ((psta->nonerp_set) |
+ (psta->no_short_slot_time_set << 1) |
+ (psta->no_short_preamble_set << 2) |
+ (psta->no_ht_gf_set << 3) |
+ (psta->no_ht_set << 4) |
+ (psta->ht_20mhz_set << 5));
+ psta_data->tx_supp_rates_len = psta->bssratelen;
+ memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
+ memcpy(&psta_data->ht_cap,
+ &psta->htpriv.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
+ psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
+ psta_data->rx_bytes = psta->sta_stats.rx_bytes;
+ psta_data->rx_drops = psta->sta_stats.rx_drops;
+ psta_data->tx_pkts = psta->sta_stats.tx_pkts;
+ psta_data->tx_bytes = psta->sta_stats.tx_bytes;
+ psta_data->tx_drops = psta->sta_stats.tx_drops;
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param_ex, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param_ex:
+ kfree(param_ex);
+ return ret;
+}
+
+static int rtw_ioctl_set_macaddr_acl_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ rtw_set_macaddr_acl(padapter, param->u.mlme.command);
+
+ ret = 0;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_ioctl_acl_add_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ ret = rtw_acl_add_sta(padapter, param->sta_addr);
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_ioctl_acl_remove_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ ret = rtw_acl_remove_sta(padapter, param->sta_addr);
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
+ ret = -EFAULT;
+
+ err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static iw_handler rtw_handlers_private[] = {
+ NULL, /* Empty */
+ rtw_hostapd_sta_flush_pvt, /* RTL871X_HOSTAPD_FLUSH */
+ rtw_add_sta_pvt, /* RTL871X_HOSTAPD_ADD_STA */
+ rtw_del_sta_pvt, /* RTL871X_HOSTAPD_REMOVE_STA */
+ rtw_ioctl_get_sta_data_pvt, /* RTL871X_HOSTAPD_GET_INFO_STA */
+ rtw_get_sta_wpaie_pvt, /* RTL871X_HOSTAPD_GET_WPAIE_STA */
+ rtw_set_encryption_pvt, /* RTL871X_SET_ENCRYPTION */
+ NULL, /* RTL871X_GET_ENCRYPTION */
+ NULL, /* RTL871X_HOSTAPD_SET_FLAGS_STA */
+ NULL, /* RTL871X_HOSTAPD_GET_RID */
+ NULL, /* RTL871X_HOSTAPD_SET_RID */
+ NULL, /* RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR */
+ NULL, /* RTL871X_HOSTAPD_SET_GENERIC_ELEMENT */
+ NULL, /* RTL871X_HOSTAPD_MLME */
+ NULL, /* RTL871X_HOSTAPD_SCAN_REQ */
+ NULL, /* RTL871X_HOSTAPD_STA_CLEAR_STATS */
+ rtw_set_beacon_pvt, /* RTL871X_HOSTAPD_SET_BEACON */
+ rtw_set_wps_beacon_pvt, /* RTL871X_HOSTAPD_SET_WPS_BEACON */
+ rtw_set_wps_probe_resp_pvt, /* RTL871X_HOSTAPD_SET_WPS_PROBE_RESP */
+ rtw_set_wps_assoc_resp_pvt, /* RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP */
+ rtw_set_hidden_ssid_pvt, /* RTL871X_HOSTAPD_SET_HIDDEN_SSID */
+ rtw_ioctl_set_macaddr_acl_pvt, /* RTL871X_HOSTAPD_SET_MACADDR_ACL */
+ rtw_ioctl_acl_add_sta_pvt, /* RTL871X_HOSTAPD_ACL_ADD_STA */
+ rtw_ioctl_acl_remove_sta_pvt, /* RTL871X_HOSTAPD_ACL_REMOVE_STA */
+};
+
static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
{
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
@@ -3089,6 +4149,8 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
struct iw_handler_def rtw_handlers_def = {
.standard = rtw_handlers,
.num_standard = ARRAY_SIZE(rtw_handlers),
+ .private = rtw_handlers_private,
+ .num_private = ARRAY_SIZE(rtw_handlers_private),
.get_wireless_stats = rtw_get_wireless_stats,
};
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-25 0:52 ` [PATCH 2/2] " ishraq.i.ashraf
@ 2017-11-25 4:40 ` Dan Carpenter
2017-11-25 18:12 ` Ishraq Ibne Ashraf
2017-11-26 0:45 ` Ishraq Ibne Ashraf
0 siblings, 2 replies; 17+ messages in thread
From: Dan Carpenter @ 2017-11-25 4:40 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: gregkh, himanshujha199640, goudapatilk, insafonov, devel,
linux-kernel, Johannes Berg
Thanks for doing this.
This needs to be folded in with the earlier patch you send and then
resend it as a V2 patch.
https://kernelnewbies.org/FirstKernelPatch#head-5c81b3c517a1d0bbc24f92594cb734e155fcbbcb
I added Johannes to the CC list again because this is sort of his
fault... To be honest, I'm a little bit puzzled. I would have thought
Johannes's change would have made some code unused and that we could
delete it now. I haven't looked at this.
>
> - if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
> + if (pmlmepriv->htpriv.ht_option == false)
> + psta->htpriv.ht_option = false;
> +
> + update_sta_info_apmode(padapter, psta);
> +
> + ret = 0;
> +
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
> ret = -EFAULT;
>
> - return ret;
> + err_free_param:
> + kfree(param);
> + return ret;
> }
Please keep the success path and failure paths separate like I did in
the example code that I wrote in my email. Don't indent the labels. It
should look like this:
update_sta_info_apmode(padapter, psta);
if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
ret = -EFAULT;
goto err_free_param;
}
kfree(param);
return 0;
err_free_param:
kfree(param);
return ret;
regards,
dan carpenter
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-25 1:29 ` [PATCH v2] " ishraq.i.ashraf
@ 2017-11-25 4:55 ` Dan Carpenter
0 siblings, 0 replies; 17+ messages in thread
From: Dan Carpenter @ 2017-11-25 4:55 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: gregkh, devel, insafonov, goudapatilk, linux-kernel, himanshujha199640
On Sat, Nov 25, 2017 at 02:29:36AM +0100, ishraq.i.ashraf@gmail.com wrote:
> +
> + ret = 0;
> +
Sorry, I wasn't clear before. When I said don't initialize "ret" to
zero, I just meant that in that specific case we initialized "ret" and
then immediately reassigned it with:
ret = some_function();
if (ret)
return ret;
In this case it's fine to set "ret = 0" at the start so that we don't
have to do it later.
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
> + ret = -EFAULT;
> +
> + if (pwep)
> + goto err_free_pwep_param;
> +
> + err_free_param:
> + kfree(param);
> + return ret;
> +
> + err_free_pwep_param:
> + kfree(pwep);
> + kfree(param);
> + return ret;
> +}
Hm... I said before that it's better to keep the error paths and
success path separate but in this case it's probabaly simpler to merge
them.
This one could look like this:
if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))
ret = -EFAULT;
free_pwep:
kfree(pwep);
free_param:
kfree(param);
return ret;
There is no need for the if (pwep) conditions, because kfree() can
take a NULL pointer. Some people would just use one label but I hate
that. It looks like this:
free:
kfree(pwep);
kfree(param);
return ret;
The reason, I hate it is because I don't like freeing things which have
not been allocated yet. If you do it the normal kernel way then you
just have to keep track of the most recently allocated thing.
regards,
dan carpenter
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-25 4:40 ` Dan Carpenter
@ 2017-11-25 18:12 ` Ishraq Ibne Ashraf
2017-11-26 0:45 ` Ishraq Ibne Ashraf
1 sibling, 0 replies; 17+ messages in thread
From: Ishraq Ibne Ashraf @ 2017-11-25 18:12 UTC (permalink / raw)
To: Dan Carpenter
Cc: gregkh, himanshujha199640, goudapatilk, insafonov, devel,
linux-kernel, Johannes Berg
Hi,
What was broken was private/device specific IOCTL calls implemented by this driver. The standard IOCTL calls worked and the driver worked as it was in client mode.
But in AP mode with hostapd (https://w1.fi/hostapd/) the rtl871xdrv driver of hostapd (which is required for using devices that use this driver in AP mode) invokes private/device specific IOCTL calls and in the existing driver they could only be invoked through the ndo_do_ioctl interface of the driver. Support for which was removed in the mentioned commit by Johannes Berg. Hence the driver stopped working in AP mode with hostapd using rtl871xdrv driver.
The solution was to implement equivalent versions of the existing private/device specific IOCTLs which will be invoked by the iw_handler_def interface.
Cheers,
Ishraq
On 11/25/2017 05:40 AM, Dan Carpenter wrote:
> I added Johannes to the CC list again because this is sort of his
> fault... To be honest, I'm a little bit puzzled. I would have thought
> Johannes's change would have made some code unused and that we could
> delete it now. I haven't looked at this.
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-23 1:29 [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls ishraq.i.ashraf
` (2 preceding siblings ...)
2017-11-25 1:29 ` [PATCH v2] " ishraq.i.ashraf
@ 2017-11-25 18:29 ` ishraq.i.ashraf
2017-11-25 21:25 ` Dan Carpenter
` (4 more replies)
2017-11-26 20:45 ` [PATCH] " kbuild test robot
2017-11-26 23:20 ` kbuild test robot
5 siblings, 5 replies; 17+ messages in thread
From: ishraq.i.ashraf @ 2017-11-25 18:29 UTC (permalink / raw)
To: gregkh
Cc: himanshujha199640, goudapatilk, insafonov, dan.carpenter, devel,
linux-kernel, johannes, Ishraq Ibne Ashraf
From: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
Commit 8bfb36766064 ("wireless: wext: remove ndo_do_ioctl fallback") breaks private WEXT
IOCTL calls of this driver as these are not invoked through ndo_do_ioctl
interface anymore. As a result hostapd stops working with this driver. In
this patch this problem is solved by implementing equivalent private IOCTL
functions of the existing ones which are accessed via iw_handler_def
interface.
Signed-off-by: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
---
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1077 ++++++++++++++++++++++++
1 file changed, 1077 insertions(+)
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index c0664dc..8d99f99 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -3061,6 +3061,1081 @@ static iw_handler rtw_handlers[] = {
NULL, /*---hole---*/
};
+static int get_private_handler_ieee_param(struct adapter *padapter,
+ union iwreq_data *wrqu,
+ void *param)
+{
+ /*
+ * This function is expected to be called in master mode, which allows no
+ * power saving. So we just check hw_init_completed.
+ */
+ if (!padapter->hw_init_completed)
+ return -EPERM;
+
+ if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ flush_all_cam_entry(padapter); /* Clear CAM. */
+ return rtw_sta_flush(padapter);
+}
+
+static int rtw_add_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int flags;
+ struct sta_info *psta;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ DBG_88E("rtw_add_sta(aid =%d) =%pM\n",
+ param->u.add_sta.aid,
+ (param->sta_addr));
+
+ if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ flags = param->u.add_sta.flags;
+ psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */
+
+ memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
+
+ /* Check WMM cap. */
+ if (WLAN_STA_WME&flags)
+ psta->qos_option = 1;
+ else
+ psta->qos_option = 0;
+
+ if (pmlmepriv->qospriv.qos_option == 0)
+ psta->qos_option = 0;
+
+ /* Check 802.11n HT cap. */
+ if (WLAN_STA_HT&flags) {
+ psta->htpriv.ht_option = true;
+ psta->qos_option = 1;
+ memcpy(&psta->htpriv.ht_cap,
+ ¶m->u.add_sta.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
+ } else {
+ psta->htpriv.ht_option = false;
+ }
+
+ if (pmlmepriv->htpriv.ht_option == false)
+ psta->htpriv.ht_option = false;
+
+ update_sta_info_apmode(padapter, psta);
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_del_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int updated;
+ struct sta_info *psta;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ spin_lock_bh(&pstapriv->asoc_list_lock);
+
+ updated = 0;
+
+ if (!list_empty(&psta->asoc_list)) {
+ list_del_init(&psta->asoc_list);
+ pstapriv->asoc_list_cnt--;
+ updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
+ }
+
+ spin_unlock_bh(&pstapriv->asoc_list_lock);
+ associated_clients_update(padapter, updated);
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_beacon_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int len;
+ unsigned char *pbuf;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ len = wrqu->data.length;
+ pbuf = param->u.bcn_ie.buf;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
+
+ if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
+ pstapriv->max_num_sta = NUM_STA;
+
+ if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) != _SUCCESS) { /* 12 = Param header, 2 = Not packed. */
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_encryption_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int param_len;
+ u32 wep_key_idx;
+ u32 wep_key_len;
+ u32 wep_total_len;
+ struct ieee_param *param;
+ struct sta_info *pbcmc_sta;
+ struct ndis_802_11_wep *pwep;
+ struct sta_info *psta = NULL;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &(padapter->securitypriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ param_len = wrqu->data.length;
+ param->u.crypt.err = 0;
+ param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+
+ if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ if (param->u.crypt.idx >= WEP_KEYS) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+ } else {
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+ }
+
+ if (strcmp(param->u.crypt.alg, "none") == 0 && (!psta)) {
+ /* TODO: Clear default encryption keys. */
+ DBG_88E("clear default encryption keys, keyid =%d\n",
+ param->u.crypt.idx);
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (strcmp(param->u.crypt.alg, "WEP") == 0 && (!psta)) {
+ DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
+
+ pwep = NULL;
+ wep_key_idx = param->u.crypt.idx;
+ wep_key_len = param->u.crypt.key_len;
+
+ DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n",
+ wep_key_idx,
+ wep_key_len);
+
+ if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (wep_key_len > 0) {
+ wep_key_len = wep_key_len <= 5 ? 5 : 13;
+ wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
+
+ pwep = (struct ndis_802_11_wep *)kmalloc(wep_total_len, GFP_KERNEL);
+ if (!pwep) {
+ DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ memset(pwep, 0, wep_total_len);
+ pwep->KeyLength = wep_key_len;
+ pwep->Length = wep_total_len;
+ }
+
+ pwep->KeyIndex = wep_key_idx;
+ memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
+
+ if (param->u.crypt.set_tx) {
+ DBG_88E("wep, set_tx = 1\n");
+
+ psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
+ psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
+ if (pwep->KeyLength == 13) {
+ psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ }
+
+ psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
+ memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
+ pwep->KeyMaterial,
+ pwep->KeyLength);
+ psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
+ set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
+ } else {
+ DBG_88E("wep, set_tx = 0\n");
+
+ /*
+ * Don't update "psecuritypriv->dot11PrivacyAlgrthm" and
+ * "psecuritypriv->dot11PrivacyKeyIndex = keyid", but rtw_set_key()
+ * can to cam.
+ */
+
+ memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
+ pwep->KeyMaterial,
+ pwep->KeyLength);
+ psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
+ set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
+ }
+
+ kfree(pwep);
+ goto free_param;
+ }
+
+ if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* Group key. */
+ if (param->u.crypt.set_tx == 1) {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ DBG_88E("%s, set group_key, WEP\n", __func__);
+
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len,
+ 16));
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
+ if (param->u.crypt.key_len == 13)
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ DBG_88E("%s, set group_key, TKIP\n", __func__);
+
+ psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len,
+ 16));
+ /* Set mic key. */
+ memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[16]),
+ 8);
+ memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[24]),
+ 8);
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ DBG_88E("%s, set group_key, CCMP\n", __func__);
+
+ psecuritypriv->dot118021XGrpPrivacy = _AES_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ } else {
+ DBG_88E("%s, set group_key, none\n", __func__);
+
+ psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+ }
+
+ psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+ psecuritypriv->binstallGrpkey = true;
+ psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
+ set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
+
+ pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+ if (pbcmc_sta) {
+ pbcmc_sta->ieee8021x_blocked = false;
+ pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy. */
+ }
+ }
+
+ goto free_param;
+ }
+
+ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x. */
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+ if (param->u.crypt.set_tx == 1) {
+ memcpy(psta->dot118021x_UncstKey.skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ DBG_88E("%s, set pairwise key, WEP\n", __func__);
+
+ psta->dot118021XPrivacy = _WEP40_;
+
+ if (param->u.crypt.key_len == 13)
+ psta->dot118021XPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ DBG_88E("%s, set pairwise key, TKIP\n", __func__);
+
+ psta->dot118021XPrivacy = _TKIP_;
+ /* Set mic key. */
+ memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
+ memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ DBG_88E("%s, set pairwise key, CCMP\n", __func__);
+
+ psta->dot118021XPrivacy = _AES_;
+ } else {
+ DBG_88E("%s, set pairwise key, none\n", __func__);
+
+ psta->dot118021XPrivacy = _NO_PRIVACY_;
+ }
+
+ set_pairwise_key(padapter, psta);
+
+ psta->ieee8021x_blocked = false;
+ } else { /* Group key ? */
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+
+ if (param->u.crypt.key_len == 13)
+ psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ /* Set mic key. */
+ memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[16]), 8);
+ memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
+ &(param->u.crypt.key[24]), 8);
+ psecuritypriv->busetkipkey = true;
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+ psecuritypriv->dot118021XGrpPrivacy = _AES_;
+ memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
+ param->u.crypt.key,
+ min_t(u16, param->u.crypt.key_len, 16));
+ } else {
+ psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+ }
+
+ psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+ psecuritypriv->binstallGrpkey = true;
+ psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
+ set_group_key(padapter,
+ param->u.crypt.key,
+ psecuritypriv->dot118021XGrpPrivacy,
+ param->u.crypt.idx);
+
+ pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+ if (pbcmc_sta) {
+ pbcmc_sta->ieee8021x_blocked = false;
+ pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy. */
+ }
+ }
+ }
+ }
+
+free_param:
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_get_sta_wpaie_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct sta_info *psta;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (!ret)
+ goto err_free_param;
+
+ DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param;
+ }
+
+ if (psta->wpa_ie[0] == WLAN_EID_RSN ||
+ psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
+ int copy_len;
+ int wpa_ie_len;
+
+ wpa_ie_len = psta->wpa_ie[1];
+ copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
+ param->u.wpa_ie.len = copy_len;
+ memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
+ } else {
+ DBG_88E("sta's wpa_ie is NONE\n");
+ }
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_wps_beacon_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
+ unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ kfree(pmlmepriv->wps_beacon_ie);
+ pmlmepriv->wps_beacon_ie = NULL;
+
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
+ if (ie_len > 0) {
+ pmlmepriv->wps_beacon_ie = kmalloc(ie_len, GFP_KERNEL);
+ if (!pmlmepriv->wps_beacon_ie) {
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ pmlmepriv->wps_beacon_ie_len = ie_len;
+ memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
+ update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
+ pmlmeext->bstart_bss = true;
+ }
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_wps_beacon_ie;
+ }
+
+ kfree(pmlmepriv->wps_beacon_ie);
+ kfree(param);
+ return 0;
+
+err_free_wps_beacon_ie:
+ kfree(pmlmepriv->wps_beacon_ie);
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_wps_probe_resp_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ kfree(pmlmepriv->wps_probe_resp_ie);
+ pmlmepriv->wps_probe_resp_ie = NULL;
+
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
+ if (ie_len > 0) {
+ pmlmepriv->wps_probe_resp_ie = kmalloc(ie_len, GFP_KERNEL);
+ if (!pmlmepriv->wps_probe_resp_ie) {
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ pmlmepriv->wps_probe_resp_ie_len = ie_len;
+ memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
+ }
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_wps_probe_resp_ie;
+ }
+
+ kfree(pmlmepriv->wps_probe_resp_ie);
+ kfree(param);
+ return 0;
+
+err_free_wps_probe_resp_ie:
+ kfree(pmlmepriv->wps_probe_resp_ie);
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_wps_assoc_resp_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ int len;
+ int ie_len;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ len = wrqu->data.length;
+
+ DBG_88E("%s, len =%d\n", __func__, len);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ kfree(pmlmepriv->wps_assoc_resp_ie);
+ pmlmepriv->wps_assoc_resp_ie = NULL;
+
+ ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
+ if (ie_len > 0) {
+ pmlmepriv->wps_assoc_resp_ie = kmalloc(ie_len, GFP_KERNEL);
+ if (!pmlmepriv->wps_assoc_resp_ie) {
+ DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ pmlmepriv->wps_assoc_resp_ie_len = ie_len;
+ memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
+ }
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_wps_assoc_resp_ie;
+ }
+
+ kfree(pmlmepriv->wps_assoc_resp_ie);
+ kfree(param);
+ return 0;
+
+err_free_wps_assoc_resp_ie:
+ kfree(pmlmepriv->wps_assoc_resp_ie);
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_set_hidden_ssid_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ u8 value;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->u.wpa_param.name != 0) /* Dummy test. */
+ DBG_88E("%s name(%u) != 0\n", __func__, param->u.wpa_param.name);
+
+ value = param->u.wpa_param.value;
+
+ /* Use the same definition of hostapd's ignore_broadcast_ssid. */
+ if (value != 1 && value != 2)
+ value = 0;
+
+ DBG_88E("%s value(%u)\n", __func__, value);
+
+ pmlmeinfo->hidden_ssid_mode = value;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_ioctl_get_sta_data_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct sta_info *psta;
+ struct sta_data *psta_data;
+ struct ieee_param_ex *param_ex;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ param_ex = (struct ieee_param_ex *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param_ex)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param_ex);
+ if (ret)
+ goto err_free_param_ex;
+
+ psta_data = (struct sta_data *)param_ex->data;
+
+ DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex->sta_addr));
+
+ if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
+ ret = -EINVAL;
+ goto err_free_param_ex;
+ }
+
+ if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
+ param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
+ param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param_ex;
+ }
+
+ psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
+ if (!psta) {
+ ret = -ENOMEM;
+ goto err_free_param_ex;
+ }
+
+ psta_data->aid = (u16)psta->aid;
+ psta_data->capability = psta->capability;
+ psta_data->flags = psta->flags;
+
+ /*
+ nonerp_set : BIT(0)
+ no_short_slot_time_set : BIT(1)
+ no_short_preamble_set : BIT(2)
+ no_ht_gf_set : BIT(3)
+ no_ht_set : BIT(4)
+ ht_20mhz_set : BIT(5)
+ */
+
+ psta_data->sta_set = \
+ ((psta->nonerp_set) |
+ (psta->no_short_slot_time_set << 1) |
+ (psta->no_short_preamble_set << 2) |
+ (psta->no_ht_gf_set << 3) |
+ (psta->no_ht_set << 4) |
+ (psta->ht_20mhz_set << 5));
+ psta_data->tx_supp_rates_len = psta->bssratelen;
+ memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
+ memcpy(&psta_data->ht_cap,
+ &psta->htpriv.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
+ psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
+ psta_data->rx_bytes = psta->sta_stats.rx_bytes;
+ psta_data->rx_drops = psta->sta_stats.rx_drops;
+ psta_data->tx_pkts = psta->sta_stats.tx_pkts;
+ psta_data->tx_bytes = psta->sta_stats.tx_bytes;
+ psta_data->tx_drops = psta->sta_stats.tx_drops;
+
+ if (copy_to_user(wrqu->data.pointer, param_ex, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param_ex;
+ }
+
+ kfree(param_ex);
+ return 0;
+
+err_free_param_ex:
+ kfree(param_ex);
+ return ret;
+}
+
+static int rtw_ioctl_set_macaddr_acl_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ rtw_set_macaddr_acl(padapter, param->u.mlme.command);
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_ioctl_acl_add_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ ret = rtw_acl_add_sta(padapter, param->sta_addr);
+ if (ret)
+ goto err_free_param;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static int rtw_ioctl_acl_remove_sta_pvt(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ret;
+ struct ieee_param *param;
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ ret = get_private_handler_ieee_param(padapter, wrqu, param);
+ if (ret)
+ goto err_free_param;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ ret = -EINVAL;
+ goto err_free_param;
+ }
+
+ ret = rtw_acl_remove_sta(padapter, param->sta_addr);
+ if (ret)
+ goto err_free_param;
+
+ if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
+ ret = -EFAULT;
+ goto err_free_param;
+ }
+
+ kfree(param);
+ return 0;
+
+err_free_param:
+ kfree(param);
+ return ret;
+}
+
+static iw_handler rtw_handlers_private[] = {
+ NULL, /* Empty */
+ rtw_hostapd_sta_flush_pvt, /* RTL871X_HOSTAPD_FLUSH */
+ rtw_add_sta_pvt, /* RTL871X_HOSTAPD_ADD_STA */
+ rtw_del_sta_pvt, /* RTL871X_HOSTAPD_REMOVE_STA */
+ rtw_ioctl_get_sta_data_pvt, /* RTL871X_HOSTAPD_GET_INFO_STA */
+ rtw_get_sta_wpaie_pvt, /* RTL871X_HOSTAPD_GET_WPAIE_STA */
+ rtw_set_encryption_pvt, /* RTL871X_SET_ENCRYPTION */
+ NULL, /* RTL871X_GET_ENCRYPTION */
+ NULL, /* RTL871X_HOSTAPD_SET_FLAGS_STA */
+ NULL, /* RTL871X_HOSTAPD_GET_RID */
+ NULL, /* RTL871X_HOSTAPD_SET_RID */
+ NULL, /* RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR */
+ NULL, /* RTL871X_HOSTAPD_SET_GENERIC_ELEMENT */
+ NULL, /* RTL871X_HOSTAPD_MLME */
+ NULL, /* RTL871X_HOSTAPD_SCAN_REQ */
+ NULL, /* RTL871X_HOSTAPD_STA_CLEAR_STATS */
+ rtw_set_beacon_pvt, /* RTL871X_HOSTAPD_SET_BEACON */
+ rtw_set_wps_beacon_pvt, /* RTL871X_HOSTAPD_SET_WPS_BEACON */
+ rtw_set_wps_probe_resp_pvt, /* RTL871X_HOSTAPD_SET_WPS_PROBE_RESP */
+ rtw_set_wps_assoc_resp_pvt, /* RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP */
+ rtw_set_hidden_ssid_pvt, /* RTL871X_HOSTAPD_SET_HIDDEN_SSID */
+ rtw_ioctl_set_macaddr_acl_pvt, /* RTL871X_HOSTAPD_SET_MACADDR_ACL */
+ rtw_ioctl_acl_add_sta_pvt, /* RTL871X_HOSTAPD_ACL_ADD_STA */
+ rtw_ioctl_acl_remove_sta_pvt, /* RTL871X_HOSTAPD_ACL_REMOVE_STA */
+};
+
static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
{
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
@@ -3089,6 +4164,8 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
struct iw_handler_def rtw_handlers_def = {
.standard = rtw_handlers,
.num_standard = ARRAY_SIZE(rtw_handlers),
+ .private = rtw_handlers_private,
+ .num_private = ARRAY_SIZE(rtw_handlers_private),
.get_wireless_stats = rtw_get_wireless_stats,
};
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-25 18:29 ` [PATCH v3] " ishraq.i.ashraf
@ 2017-11-25 21:25 ` Dan Carpenter
2017-11-27 11:24 ` Johannes Berg
` (3 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: Dan Carpenter @ 2017-11-25 21:25 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: gregkh, devel, insafonov, goudapatilk, linux-kernel,
himanshujha199640, johannes
Thanks. This is looking *much* better...
On Sat, Nov 25, 2017 at 07:29:41PM +0100, ishraq.i.ashraf@gmail.com wrote:
> From: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
>
> Commit 8bfb36766064 ("wireless: wext: remove ndo_do_ioctl fallback") breaks private WEXT
> IOCTL calls of this driver as these are not invoked through ndo_do_ioctl
> interface anymore. As a result hostapd stops working with this driver. In
> this patch this problem is solved by implementing equivalent private IOCTL
> functions of the existing ones which are accessed via iw_handler_def
> interface.
>
> Signed-off-by: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
> ---
> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1077 ++++++++++++++++++++++++
> 1 file changed, 1077 insertions(+)
>
> diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
> index c0664dc..8d99f99 100644
> --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
> +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
> @@ -3061,6 +3061,1081 @@ static iw_handler rtw_handlers[] = {
> NULL, /*---hole---*/
> };
>
> +static int get_private_handler_ieee_param(struct adapter *padapter,
> + union iwreq_data *wrqu,
> + void *param)
> +{
> + /*
> + * This function is expected to be called in master mode, which allows no
> + * power saving. So we just check hw_init_completed.
> + */
> + if (!padapter->hw_init_completed)
> + return -EPERM;
This check doesn't belong here. ->hw_init_completed is set to true in
rtw_hal_init() and false in rtw_hal_deinit(). Can it ever be false
here? I really doubt it and if I'm wrong then we are pretty screwed
already... Anyway, move the check or delete it. Then this function and
the kmalloc() can be replaced with memdup_user().
> +
> + if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
Add a blank line after declarations.
> + flush_all_cam_entry(padapter); /* Clear CAM. */
> + return rtw_sta_flush(padapter);
> +}
> +
> +static int rtw_add_sta_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret;
> + int flags;
> + struct sta_info *psta;
> + struct ieee_param *param;
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct sta_priv *pstapriv = &padapter->stapriv;
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> +
> + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
> + if (!param)
> + return -ENOMEM;
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> + if (ret)
> + goto err_free_param;
Then these lines become:
param = memdup_user(wrqu->data.pointer, wrqu->data.length);
if (IS_ERR(param))
return PTR_ERR(param);
> +
> + DBG_88E("rtw_add_sta(aid =%d) =%pM\n",
> + param->u.add_sta.aid,
> + (param->sta_addr));
> +
> + if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
> + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
> + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + psta = rtw_get_stainfo(pstapriv, param->sta_addr);
> + if (!psta) {
> + ret = -ENOMEM;
> + goto err_free_param;
> + }
> +
> + flags = param->u.add_sta.flags;
> + psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */
> +
> + memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
> +
> + /* Check WMM cap. */
> + if (WLAN_STA_WME&flags)
Add spaces around the & and reverse the order.
if (flags & WLAN_STA_HT) {
> + psta->qos_option = 1;
> + else
> + psta->qos_option = 0;
> +
> + if (pmlmepriv->qospriv.qos_option == 0)
> + psta->qos_option = 0;
> +
> + /* Check 802.11n HT cap. */
> + if (WLAN_STA_HT&flags) {
Add spaces and reverse.
> + psta->htpriv.ht_option = true;
> + psta->qos_option = 1;
> + memcpy(&psta->htpriv.ht_cap,
> + ¶m->u.add_sta.ht_cap,
> + sizeof(struct ieee80211_ht_cap));
> + } else {
> + psta->htpriv.ht_option = false;
> + }
> +
> + if (pmlmepriv->htpriv.ht_option == false)
> + psta->htpriv.ht_option = false;
> +
> + update_sta_info_apmode(padapter, psta);
> +
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
> + ret = -EFAULT;
> + goto err_free_param;
> + }
> +
> + kfree(param);
> + return 0;
> +
> +err_free_param:
> + kfree(param);
> + return ret;
> +}
> +
> +static int rtw_del_sta_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret;
> + int updated;
> + struct sta_info *psta;
> + struct ieee_param *param;
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct sta_priv *pstapriv = &padapter->stapriv;
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> +
> + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
> + if (!param)
> + return -ENOMEM;
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> + if (ret)
> + goto err_free_param;
memdup_user();
> +
> + DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
> +
> + if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
> + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
> + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + psta = rtw_get_stainfo(pstapriv, param->sta_addr);
> + if (!psta) {
> + DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
> + ret = -ENOMEM;
> + goto err_free_param;
> + }
> +
> + spin_lock_bh(&pstapriv->asoc_list_lock);
> +
> + updated = 0;
> +
> + if (!list_empty(&psta->asoc_list)) {
> + list_del_init(&psta->asoc_list);
> + pstapriv->asoc_list_cnt--;
> + updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
> + }
> +
> + spin_unlock_bh(&pstapriv->asoc_list_lock);
> + associated_clients_update(padapter, updated);
> +
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
> + ret = -EFAULT;
> + goto err_free_param;
> + }
> +
> + kfree(param);
> + return 0;
> +
> +err_free_param:
> + kfree(param);
> + return ret;
> +}
> +
> +static int rtw_set_beacon_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret;
> + int len;
> + unsigned char *pbuf;
> + struct ieee_param *param;
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct sta_priv *pstapriv = &padapter->stapriv;
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> +
> + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
> + if (!param)
> + return -ENOMEM;
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> + if (ret)
> + goto err_free_param;
> +
> + len = wrqu->data.length;
> + pbuf = param->u.bcn_ie.buf;
> +
> + DBG_88E("%s, len =%d\n", __func__, len);
> +
> + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
It's concerning to me that we are using reserved memory... Reserved
means we it is saved for the future and we aren't supposed to use it.
Maybe the name needs changed. Use a sizeof() instead of a 2.
> +
> + if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
> + pstapriv->max_num_sta = NUM_STA;
> +
> + if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) != _SUCCESS) { /* 12 = Param header, 2 = Not packed. */
The white space isn't right here. There are two spaces after the comma.
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
> + ret = -EFAULT;
> + goto err_free_param;
> + }
> +
> + kfree(param);
> + return 0;
> +
> +err_free_param:
> + kfree(param);
> + return ret;
> +}
> +
> +static int rtw_set_encryption_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret;
> + int param_len;
> + u32 wep_key_idx;
> + u32 wep_key_len;
> + u32 wep_total_len;
> + struct ieee_param *param;
> + struct sta_info *pbcmc_sta;
> + struct ndis_802_11_wep *pwep;
> + struct sta_info *psta = NULL;
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct sta_priv *pstapriv = &padapter->stapriv;
> + struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
> + struct security_priv *psecuritypriv = &(padapter->securitypriv);
> +
> + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
> + if (!param)
> + return -ENOMEM;
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> + if (ret)
> + goto err_free_param;
> +
> + param_len = wrqu->data.length;
> + param->u.crypt.err = 0;
> + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
This is problematica because how do we know that wrqu->data.length is
large enough to hold a ieee_param struct? There should probably be a
check like:
if (wrqu->data.length < sizeof(*param))
return -EINVAL;
Probably all the functions should have this.
> +
> + if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
We're checking here but we have already written a NUL terminator
possibly beyond the end of the buffer. There are two spaces after the
!=.
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
> + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
> + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
> + if (param->u.crypt.idx >= WEP_KEYS) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> + } else {
> + psta = rtw_get_stainfo(pstapriv, param->sta_addr);
> + if (!psta) {
> + DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
> + ret = -ENOMEM;
> + goto err_free_param;
> + }
> + }
> +
> + if (strcmp(param->u.crypt.alg, "none") == 0 && (!psta)) {
^ ^
Remove the extra parens.
> + /* TODO: Clear default encryption keys. */
> + DBG_88E("clear default encryption keys, keyid =%d\n",
> + param->u.crypt.idx);
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + if (strcmp(param->u.crypt.alg, "WEP") == 0 && (!psta)) {
^ ^
Extra parens.
> + DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
> +
> + pwep = NULL;
> + wep_key_idx = param->u.crypt.idx;
> + wep_key_len = param->u.crypt.key_len;
> +
> + DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n",
> + wep_key_idx,
> + wep_key_len);
> +
> + if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
^ ^ ^ ^
Remove the extra parens. wep_key_len is unsigned so it can't be less
than zero.
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + if (wep_key_len > 0) {
No need to check this because we just checked on the line before.
> + wep_key_len = wep_key_len <= 5 ? 5 : 13;
> + wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
> +
> + pwep = (struct ndis_802_11_wep *)kmalloc(wep_total_len, GFP_KERNEL);
> + if (!pwep) {
> + DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
Remove space at the start of printk
> + ret = -ENOMEM;
> + goto err_free_param;
> + }
> +
> + memset(pwep, 0, wep_total_len);
> + pwep->KeyLength = wep_key_len;
> + pwep->Length = wep_total_len;
> + }
> +
> + pwep->KeyIndex = wep_key_idx;
> + memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
Extra space after comma
> +
> + if (param->u.crypt.set_tx) {
> + DBG_88E("wep, set_tx = 1\n");
> +
> + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
> + psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
> + psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
> +
> + if (pwep->KeyLength == 13) {
> + psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
> + psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
> + }
> +
> + psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
> + memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
^ ^
Remove the extra parens
> + pwep->KeyMaterial,
> + pwep->KeyLength);
> + psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
> + set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
> + } else {
> + DBG_88E("wep, set_tx = 0\n");
> +
> + /*
> + * Don't update "psecuritypriv->dot11PrivacyAlgrthm" and
> + * "psecuritypriv->dot11PrivacyKeyIndex = keyid", but rtw_set_key()
> + * can to cam.
> + */
> +
> + memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]),
^ ^
Extra parens
> + pwep->KeyMaterial,
> + pwep->KeyLength);
> + psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
> + set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
> + }
> +
> + kfree(pwep);
> + goto free_param;
> + }
> +
> + if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* Group key. */
> + if (param->u.crypt.set_tx == 1) {
> + if (strcmp(param->u.crypt.alg, "WEP") == 0) {
> + DBG_88E("%s, set group_key, WEP\n", __func__);
> +
> + memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
> + param->u.crypt.key,
> + min_t(u16, param->u.crypt.key_len,
> + 16));
> + psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
> +
> + if (param->u.crypt.key_len == 13)
> + psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
> + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
> + DBG_88E("%s, set group_key, TKIP\n", __func__);
> +
> + psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
> + memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
> + param->u.crypt.key,
> + min_t(u16, param->u.crypt.key_len,
> + 16));
> + /* Set mic key. */
> + memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
> + &(param->u.crypt.key[16]),
> + 8);
> + memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
> + &(param->u.crypt.key[24]),
> + 8);
> + psecuritypriv->busetkipkey = true;
> + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
> + DBG_88E("%s, set group_key, CCMP\n", __func__);
> +
> + psecuritypriv->dot118021XGrpPrivacy = _AES_;
> + memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
> + param->u.crypt.key,
> + min_t(u16, param->u.crypt.key_len, 16));
> + } else {
> + DBG_88E("%s, set group_key, none\n", __func__);
> +
> + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
> + }
> +
> + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
> + psecuritypriv->binstallGrpkey = true;
> + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
> + set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
> +
> + pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
> + if (pbcmc_sta) {
> + pbcmc_sta->ieee8021x_blocked = false;
> + pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy. */
> + }
> + }
> +
> + goto free_param;
> + }
> +
> + if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x. */
> + if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
> + if (param->u.crypt.set_tx == 1) {
> + memcpy(psta->dot118021x_UncstKey.skey,
> + param->u.crypt.key,
> + min_t(u16, param->u.crypt.key_len, 16));
> +
> + if (strcmp(param->u.crypt.alg, "WEP") == 0) {
> + DBG_88E("%s, set pairwise key, WEP\n", __func__);
> +
> + psta->dot118021XPrivacy = _WEP40_;
> +
> + if (param->u.crypt.key_len == 13)
> + psta->dot118021XPrivacy = _WEP104_;
> + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
> + DBG_88E("%s, set pairwise key, TKIP\n", __func__);
> +
> + psta->dot118021XPrivacy = _TKIP_;
> + /* Set mic key. */
> + memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
> + memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
> + psecuritypriv->busetkipkey = true;
> + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
> + DBG_88E("%s, set pairwise key, CCMP\n", __func__);
> +
> + psta->dot118021XPrivacy = _AES_;
> + } else {
> + DBG_88E("%s, set pairwise key, none\n", __func__);
> +
> + psta->dot118021XPrivacy = _NO_PRIVACY_;
> + }
> +
> + set_pairwise_key(padapter, psta);
> +
> + psta->ieee8021x_blocked = false;
> + } else { /* Group key ? */
> + if (strcmp(param->u.crypt.alg, "WEP") == 0) {
> + memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
> + param->u.crypt.key,
> + min_t(u16, param->u.crypt.key_len, 16));
> + psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
> +
> + if (param->u.crypt.key_len == 13)
> + psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
> + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
> + psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
> + memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
> + param->u.crypt.key,
> + min_t(u16, param->u.crypt.key_len, 16));
> + /* Set mic key. */
> + memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey,
> + &(param->u.crypt.key[16]), 8);
^ ^
Extra parens
> + memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey,
> + &(param->u.crypt.key[24]), 8);
^ ^
Extra parens
> + psecuritypriv->busetkipkey = true;
> + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
> + psecuritypriv->dot118021XGrpPrivacy = _AES_;
> + memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
> + param->u.crypt.key,
> + min_t(u16, param->u.crypt.key_len, 16));
> + } else {
> + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
> + }
> +
> + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
> + psecuritypriv->binstallGrpkey = true;
> + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
> + set_group_key(padapter,
> + param->u.crypt.key,
> + psecuritypriv->dot118021XGrpPrivacy,
> + param->u.crypt.idx);
> +
> + pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
> + if (pbcmc_sta) {
> + pbcmc_sta->ieee8021x_blocked = false;
> + pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy. */
> + }
> + }
> + }
> + }
> +
> +free_param:
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
> + ret = -EFAULT;
> + goto err_free_param;
> + }
> +
> + kfree(param);
> + return 0;
> +
> +err_free_param:
> + kfree(param);
> + return ret;
> +}
> +
> +static int rtw_get_sta_wpaie_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret;
> + struct sta_info *psta;
> + struct ieee_param *param;
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct sta_priv *pstapriv = &padapter->stapriv;
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> +
> + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
> + if (!param)
> + return -ENOMEM;
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> + if (!ret)
> + goto err_free_param;
memdup_user()
> +
> + DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr));
> +
> + if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
> + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
> + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + psta = rtw_get_stainfo(pstapriv, param->sta_addr);
> + if (!psta) {
> + ret = -ENOMEM;
> + goto err_free_param;
> + }
> +
> + if (psta->wpa_ie[0] == WLAN_EID_RSN ||
> + psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
> + int copy_len;
> + int wpa_ie_len;
> +
> + wpa_ie_len = psta->wpa_ie[1];
> + copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
> + param->u.wpa_ie.len = copy_len;
> + memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
> + } else {
> + DBG_88E("sta's wpa_ie is NONE\n");
> + }
> +
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
> + ret = -EFAULT;
> + goto err_free_param;
> + }
> +
> + kfree(param);
> + return 0;
> +
> +err_free_param:
> + kfree(param);
> + return ret;
> +}
> +
> +static int rtw_set_wps_beacon_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret;
> + int len;
> + int ie_len;
> + struct ieee_param *param;
> + unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
> +
> + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
> + if (!param)
> + return -ENOMEM;
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> + if (ret)
> + goto err_free_param;
memdup_user()
> +
> + len = wrqu->data.length;
> +
> + DBG_88E("%s, len =%d\n", __func__, len);
> +
> + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + kfree(pmlmepriv->wps_beacon_ie);
> + pmlmepriv->wps_beacon_ie = NULL;
> +
> + ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
Add spaces around opperators:
ie_len = len - 12 - 2;
> + if (ie_len > 0) {
> + pmlmepriv->wps_beacon_ie = kmalloc(ie_len, GFP_KERNEL);
> + if (!pmlmepriv->wps_beacon_ie) {
> + DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
Delete this printk after a kmalloc(). Kmalloc() already has a stack
trace built-in.
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + pmlmepriv->wps_beacon_ie_len = ie_len;
> + memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
> + update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
> + pmlmeext->bstart_bss = true;
> + }
> +
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
> + ret = -EFAULT;
> + goto err_free_wps_beacon_ie;
> + }
> +
> + kfree(pmlmepriv->wps_beacon_ie);
> + kfree(param);
> + return 0;
> +
> +err_free_wps_beacon_ie:
> + kfree(pmlmepriv->wps_beacon_ie);
> +
> +err_free_param:
> + kfree(param);
> + return ret;
> +}
> +
> +static int rtw_set_wps_probe_resp_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret;
> + int len;
> + int ie_len;
> + struct ieee_param *param;
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> +
> + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
> + if (!param)
> + return -ENOMEM;
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> + if (ret)
> + goto err_free_param;
> +
memdup_user()
> + len = wrqu->data.length;
> +
> + DBG_88E("%s, len =%d\n", __func__, len);
> +
> + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + kfree(pmlmepriv->wps_probe_resp_ie);
> + pmlmepriv->wps_probe_resp_ie = NULL;
We should have a local variable instead of using
pmlmepriv->wps_probe_resp_ie. The problem with a shared variable is
that there is no locking and it could have a race and use after free and
it's possibly a security issue. Also it looks like it could buffer
overflow as well because we're re-allocating it with different sizes.
> +
> + ie_len = len-12-2; /* 12 = Param header, 2 = Not packed. */
Add spaces
> + if (ie_len > 0) {
Say ie_len is <= 0, isn't that -EINVAL?
> + pmlmepriv->wps_probe_resp_ie = kmalloc(ie_len, GFP_KERNEL);
> + if (!pmlmepriv->wps_probe_resp_ie) {
> + DBG_88E("%s()-%d: kmalloc() ERROR!\n", __func__, __LINE__);
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + pmlmepriv->wps_probe_resp_ie_len = ie_len;
> + memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
> + }
> +
> + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
> + ret = -EFAULT;
> + goto err_free_wps_probe_resp_ie;
> + }
> +
> + kfree(pmlmepriv->wps_probe_resp_ie);
> + kfree(param);
> + return 0;
> +
> +err_free_wps_probe_resp_ie:
> + kfree(pmlmepriv->wps_probe_resp_ie);
> +
> +err_free_param:
> + kfree(param);
> + return ret;
> +}
> +
> +static int rtw_set_wps_assoc_resp_pvt(struct net_device *dev,
> + struct iw_request_info *info,
> + union iwreq_data *wrqu,
> + char *extra)
> +{
> + int ret;
> + int len;
> + int ie_len;
> + struct ieee_param *param;
> + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
> + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
> +
> + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
> + if (!param)
> + return -ENOMEM;
> +
> + ret = get_private_handler_ieee_param(padapter, wrqu, param);
> + if (ret)
> + goto err_free_param;
memdup_user()
> +
> + len = wrqu->data.length;
> +
> + DBG_88E("%s, len =%d\n", __func__, len);
> +
> + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
> + ret = -EINVAL;
> + goto err_free_param;
> + }
> +
> + kfree(pmlmepriv->wps_assoc_resp_ie);
> + pmlmepriv->wps_assoc_resp_ie = NULL;
Use local variable
I have to go to sleep now, but I can't stress enough how much better
this version is than v1 and v2. Thanks very much.
regards,
dan carpenter
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-25 4:40 ` Dan Carpenter
2017-11-25 18:12 ` Ishraq Ibne Ashraf
@ 2017-11-26 0:45 ` Ishraq Ibne Ashraf
2017-11-27 11:33 ` Johannes Berg
1 sibling, 1 reply; 17+ messages in thread
From: Ishraq Ibne Ashraf @ 2017-11-26 0:45 UTC (permalink / raw)
To: Dan Carpenter
Cc: gregkh, himanshujha199640, goudapatilk, insafonov, devel,
linux-kernel, Johannes Berg
Hi,
What was broken was private/device specific IOCTL calls implemented by this driver. The standard IOCTL calls worked and the driver worked as it was in client mode.
But in AP mode with hostapd (https://w1.fi/hostapd/) the rtl871xdrv driver of hostapd (which is required for using devices that use this driver in AP mode) invokes private/device specific IOCTL calls and in the existing driver they could only be invoked through the ndo_do_ioctl interface of the driver. Support for which was removed in the mentioned commit by Johannes Berg. Hence the driver stopped working in AP mode with hostapd using rtl871xdrv driver.
The solution was to implement equivalent versions of the existing private/device specific IOCTLs which will be invoked by the iw_handler_def interface.
Cheers,
Ishraq
On 11/25/2017 05:40 AM, Dan Carpenter wrote:
> I added Johannes to the CC list again because this is sort of his
> fault... To be honest, I'm a little bit puzzled. I would have thought
> Johannes's change would have made some code unused and that we could
> delete it now. I haven't looked at this.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-23 1:29 [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls ishraq.i.ashraf
` (3 preceding siblings ...)
2017-11-25 18:29 ` [PATCH v3] " ishraq.i.ashraf
@ 2017-11-26 20:45 ` kbuild test robot
2017-11-26 23:20 ` kbuild test robot
5 siblings, 0 replies; 17+ messages in thread
From: kbuild test robot @ 2017-11-26 20:45 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: kbuild-all, gregkh, himanshujha199640, goudapatilk, insafonov,
devel, linux-kernel, Ishraq Ibne Ashraf
[-- Attachment #1: Type: text/plain, Size: 18486 bytes --]
Hi Ishraq,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on staging/staging-testing]
[also build test ERROR on v4.14 next-20171124]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/ishraq-i-ashraf-gmail-com/staging-rtl8188eu-Fix-private-WEXT-IOCTL-calls/20171126-052554
config: x86_64-randconfig-n0-11270329 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All error/warnings (new ones prefixed by >>):
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_hostapd_sta_flush_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3101:9: error: implicit declaration of function 'rtw_sta_flush'; did you mean 'rtw_set_auth'? [-Werror=implicit-function-declaration]
return rtw_sta_flush(padapter);
^~~~~~~~~~~~~
rtw_set_auth
In file included from include/linux/kernel.h:14:0,
from include/linux/skbuff.h:17,
from include/linux/if_ether.h:23,
from include/linux/ieee80211.h:21,
from drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:17:
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_add_sta_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3133:49: error: 'union <anonymous>' has no member named 'add_sta'
DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
^
include/linux/printk.h:310:34: note: in definition of macro 'pr_info'
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~~~
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3133:2: note: in expansion of macro 'DBG_88E'
DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
^~~~~~~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3145:23: error: 'union <anonymous>' has no member named 'add_sta'
int flags = param->u.add_sta.flags;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3146:23: error: 'union <anonymous>' has no member named 'add_sta'
psta->aid = param->u.add_sta.aid; // aid = 1~2007.
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3148:36: error: 'union <anonymous>' has no member named 'add_sta'
memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3151:7: error: 'WLAN_STA_WME' undeclared (first use in this function); did you mean 'SCAN_STATE'?
if (WLAN_STA_WME&flags)
^~~~~~~~~~~~
SCAN_STATE
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3151:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3160:7: error: 'WLAN_STA_HT' undeclared (first use in this function); did you mean 'WLAN_STA_WME'?
if (WLAN_STA_HT&flags) {
^~~~~~~~~~~
WLAN_STA_WME
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3164:20: error: 'union <anonymous>' has no member named 'add_sta'
¶m->u.add_sta.ht_cap,
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3173:3: error: implicit declaration of function 'update_sta_info_apmode'; did you mean 'update_sta_info'? [-Werror=implicit-function-declaration]
update_sta_info_apmode(padapter, psta);
^~~~~~~~~~~~~~~~~~~~~~
update_sta_info
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_del_sta_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3229:14: error: 'struct sta_priv' has no member named 'asoc_list_cnt'; did you mean 'asoc_list_lock'?
pstapriv->asoc_list_cnt--;
^~~~~~~~~~~~~
asoc_list_lock
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3230:14: error: implicit declaration of function 'ap_free_sta'; did you mean '__kfree_skb'? [-Werror=implicit-function-declaration]
updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
^~~~~~~~~~~
__kfree_skb
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3233:3: error: implicit declaration of function 'associated_clients_update' [-Werror=implicit-function-declaration]
associated_clients_update(padapter, updated);
^~~~~~~~~~~~~~~~~~~~~~~~~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_beacon_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3276:18: error: 'union <anonymous>' has no member named 'bcn_ie'; did you mean 'wpa_ie'?
pbuf = param->u.bcn_ie.buf;
^~~~~~
wpa_ie
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3283:18: error: 'struct sta_priv' has no member named 'max_num_sta'
memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
^~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3283:42: error: 'union <anonymous>' has no member named 'bcn_ie'; did you mean 'wpa_ie'?
memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
^~~~~~
wpa_ie
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3285:15: error: 'struct sta_priv' has no member named 'max_num_sta'
if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
^~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3285:52: error: 'struct sta_priv' has no member named 'max_num_sta'
if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
^~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3286:11: error: 'struct sta_priv' has no member named 'max_num_sta'
pstapriv->max_num_sta = NUM_STA;
^~
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3288:6: error: implicit declaration of function 'rtw_check_beacon_data'; did you mean 'rtw_set_beacon_pvt'? [-Werror=implicit-function-declaration]
if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS) // 12 = Param header, 2 = Not packed.
^~~~~~~~~~~~~~~~~~~~~
rtw_set_beacon_pvt
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_encryption_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3412:4: error: implicit declaration of function 'set_wep_key'; did you mean 'rtw_set_key'? [-Werror=implicit-function-declaration]
set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
^~~~~~~~~~~
rtw_set_key
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3476:4: error: implicit declaration of function 'set_group_key'; did you mean 'set_groups'? [-Werror=implicit-function-declaration]
set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
^~~~~~~~~~~~~
set_groups
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3517:5: error: implicit declaration of function 'set_pairwise_key'; did you mean 'set_dma_reserve'? [-Werror=implicit-function-declaration]
set_pairwise_key(padapter, psta);
^~~~~~~~~~~~~~~~
set_dma_reserve
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_get_sta_wpaie_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3621:11: error: 'struct sta_info' has no member named 'wpa_ie'
if (psta->wpa_ie[0] == WLAN_EID_RSN ||
^~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3622:11: error: 'struct sta_info' has no member named 'wpa_ie'
psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
^~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3626:26: error: 'struct sta_info' has no member named 'wpa_ie'
wpa_ie_len = psta->wpa_ie[1];
^~
In file included from include/linux/skbuff.h:17:0,
from include/linux/if_ether.h:23,
from include/linux/ieee80211.h:21,
from drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:17:
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3627:58: error: 'struct sta_info' has no member named 'wpa_ie'
copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
^
include/linux/kernel.h:790:13: note: in definition of macro '__min'
t2 min2 = (y); \
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3627:20: note: in expansion of macro 'min_t'
copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
^~~~~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3629:46: error: 'struct sta_info' has no member named 'wpa_ie'
memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
^~
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_wps_beacon_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3682:19: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'; did you mean 'wps_probe_req_ie'?
kfree(pmlmepriv->wps_beacon_ie);
^~~~~~~~~~~~~
wps_probe_req_ie
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3683:13: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'; did you mean 'wps_probe_req_ie'?
pmlmepriv->wps_beacon_ie = NULL;
^~~~~~~~~~~~~
wps_probe_req_ie
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3686:14: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'; did you mean 'wps_probe_req_ie'?
pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
^~~~~~~~~~~~~
wps_probe_req_ie
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3687:14: error: 'struct mlme_priv' has no member named 'wps_beacon_ie_len'; did you mean 'wps_probe_req_ie_len'?
pmlmepriv->wps_beacon_ie_len = ie_len;
^~~~~~~~~~~~~~~~~
wps_probe_req_ie_len
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3688:19: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'; did you mean 'wps_probe_req_ie'?
if (!pmlmepriv->wps_beacon_ie) {
^~~~~~~~~~~~~
wps_probe_req_ie
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3693:21: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'; did you mean 'wps_probe_req_ie'?
memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
^~~~~~~~~~~~~
wps_probe_req_ie
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3693:45: error: 'union <anonymous>' has no member named 'bcn_ie'; did you mean 'wpa_ie'?
memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
^~~~~~
wpa_ie
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3694:3: error: implicit declaration of function 'update_beacon'; did you mean 'update_beacon_info'? [-Werror=implicit-function-declaration]
update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
^~~~~~~~~~~~~
update_beacon_info
vim +3101 drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
3089
3090 static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
3091 struct iw_request_info *info,
3092 union iwreq_data *wrqu,
3093 char *extra)
3094 {
3095 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3096
3097 DBG_88E("%s\n", __func__);
3098
3099 flush_all_cam_entry(padapter); // Clear CAM.
3100
> 3101 return rtw_sta_flush(padapter);
3102 }
3103
3104 static int rtw_add_sta_pvt(struct net_device *dev,
3105 struct iw_request_info *info,
3106 union iwreq_data *wrqu,
3107 char *extra)
3108 {
3109 int ret = 0;
3110 struct sta_info *psta = NULL;
3111 struct ieee_param *param = NULL;
3112 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3113 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3114 struct sta_priv *pstapriv = &padapter->stapriv;
3115
3116 param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
3117
3118 if (!param) {
3119 DBG_88E(" rtw_add_sta: ieee_param allocate fail !!!\n");
3120
3121 return -ENOMEM;
3122 }
3123
3124 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3125
3126 if (ret != 0) {
3127 kfree(param);
3128 DBG_88E(" rtw_add_sta: ieee_param get fail !!!\n");
3129
3130 return ret;
3131 }
3132
> 3133 DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
3134
3135 if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
3136 return -EINVAL;
3137
3138 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3139 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3140 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
3141 return -EINVAL;
3142
3143 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3144 if (psta) {
> 3145 int flags = param->u.add_sta.flags;
3146 psta->aid = param->u.add_sta.aid; // aid = 1~2007.
3147
> 3148 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
3149
3150 // Check WMM cap.
> 3151 if (WLAN_STA_WME&flags)
3152 psta->qos_option = 1;
3153 else
3154 psta->qos_option = 0;
3155
3156 if (pmlmepriv->qospriv.qos_option == 0)
3157 psta->qos_option = 0;
3158
3159 // Check 802.11n HT cap.
> 3160 if (WLAN_STA_HT&flags) {
3161 psta->htpriv.ht_option = true;
3162 psta->qos_option = 1;
3163 memcpy(&psta->htpriv.ht_cap,
> 3164 ¶m->u.add_sta.ht_cap,
3165 sizeof(struct ieee80211_ht_cap));
3166 } else {
3167 psta->htpriv.ht_option = false;
3168 }
3169
3170 if (pmlmepriv->htpriv.ht_option == false)
3171 psta->htpriv.ht_option = false;
3172
> 3173 update_sta_info_apmode(padapter, psta);
3174 } else {
3175 ret = -ENOMEM;
3176 }
3177
3178 if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
3179 ret = -EFAULT;
3180
3181 return ret;
3182 }
3183
3184 static int rtw_del_sta_pvt(struct net_device *dev,
3185 struct iw_request_info *info,
3186 union iwreq_data *wrqu,
3187 char *extra)
3188 {
3189 int ret = 0;
3190 struct sta_info *psta = NULL;
3191 struct ieee_param *param = NULL;
3192 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3193 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3194 struct sta_priv *pstapriv = &padapter->stapriv;
3195 int updated = 0;
3196
3197 param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
3198
3199 if (!param) {
3200 DBG_88E(" rtw_del_sta: ieee_param allocate fail !!!\n");
3201
3202 return -ENOMEM;
3203 }
3204
3205 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3206
3207 if (ret != 0) {
3208 kfree(param);
3209 DBG_88E(" rtw_del_sta: ieee_param get fail !!!\n");
3210
3211 return ret;
3212 }
3213
3214 DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
3215
3216 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3217 return -EINVAL;
3218
3219 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3220 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3221 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
3222 return -EINVAL;
3223
3224 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3225 if (psta) {
3226 spin_lock_bh(&pstapriv->asoc_list_lock);
3227 if (!list_empty(&psta->asoc_list)) {
3228 list_del_init(&psta->asoc_list);
> 3229 pstapriv->asoc_list_cnt--;
> 3230 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
3231 }
3232 spin_unlock_bh(&pstapriv->asoc_list_lock);
> 3233 associated_clients_update(padapter, updated);
3234 psta = NULL;
3235 } else {
3236 DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
3237 }
3238
3239 if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
3240 ret = -EFAULT;
3241
3242 return ret;
3243 }
3244
3245 static int rtw_set_beacon_pvt(struct net_device *dev,
3246 struct iw_request_info *info,
3247 union iwreq_data *wrqu,
3248 char *extra)
3249 {
3250 int ret = 0;
3251 int len = 0;
3252 unsigned char *pbuf = NULL;
3253 struct ieee_param *param = NULL;
3254 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3255 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3256 struct sta_priv *pstapriv = &padapter->stapriv;
3257
3258 param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
3259
3260 if (!param) {
3261 DBG_88E(" rtw_set_beacon: ieee_param allocate fail !!!\n");
3262
3263 return -ENOMEM;
3264 }
3265
3266 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3267
3268 if (ret != 0) {
3269 kfree(param);
3270 DBG_88E(" rtw_set_beacon: ieee_param get fail !!!\n");
3271
3272 return ret;
3273 }
3274
3275 len = wrqu->data.length;
> 3276 pbuf = param->u.bcn_ie.buf;
3277
3278 DBG_88E("%s, len =%d\n", __func__, len);
3279
3280 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3281 return -EINVAL;
3282
> 3283 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3284
> 3285 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
> 3286 pstapriv->max_num_sta = NUM_STA;
3287
> 3288 if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS) // 12 = Param header, 2 = Not packed.
3289 ret = 0;
3290 else
3291 ret = -EINVAL;
3292
3293 if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
3294 ret = -EFAULT;
3295
3296 return ret;
3297 }
3298
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32003 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-23 1:29 [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls ishraq.i.ashraf
` (4 preceding siblings ...)
2017-11-26 20:45 ` [PATCH] " kbuild test robot
@ 2017-11-26 23:20 ` kbuild test robot
5 siblings, 0 replies; 17+ messages in thread
From: kbuild test robot @ 2017-11-26 23:20 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: kbuild-all, gregkh, himanshujha199640, goudapatilk, insafonov,
devel, linux-kernel, Ishraq Ibne Ashraf
[-- Attachment #1: Type: text/plain, Size: 22781 bytes --]
Hi Ishraq,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on staging/staging-testing]
[also build test ERROR on v4.14 next-20171124]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/ishraq-i-ashraf-gmail-com/staging-rtl8188eu-Fix-private-WEXT-IOCTL-calls/20171126-052554
config: x86_64-randconfig-u0-11270543 (attached as .config)
compiler: gcc-5 (Debian 5.5.0-3) 5.4.1 20171010
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_hostapd_sta_flush_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3101:9: error: implicit declaration of function 'rtw_sta_flush' [-Werror=implicit-function-declaration]
return rtw_sta_flush(padapter);
^
In file included from include/linux/kernel.h:14:0,
from include/linux/skbuff.h:17,
from include/linux/if_ether.h:23,
from include/linux/ieee80211.h:21,
from drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:17:
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_add_sta_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3133:49: error: 'union <anonymous>' has no member named 'add_sta'
DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
^
include/linux/printk.h:310:34: note: in definition of macro 'pr_info'
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3133:2: note: in expansion of macro 'DBG_88E'
DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3145:23: error: 'union <anonymous>' has no member named 'add_sta'
int flags = param->u.add_sta.flags;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3146:23: error: 'union <anonymous>' has no member named 'add_sta'
psta->aid = param->u.add_sta.aid; // aid = 1~2007.
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3148:36: error: 'union <anonymous>' has no member named 'add_sta'
memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3151:7: error: 'WLAN_STA_WME' undeclared (first use in this function)
if (WLAN_STA_WME&flags)
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3151:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3160:7: error: 'WLAN_STA_HT' undeclared (first use in this function)
if (WLAN_STA_HT&flags) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3164:20: error: 'union <anonymous>' has no member named 'add_sta'
¶m->u.add_sta.ht_cap,
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3173:3: error: implicit declaration of function 'update_sta_info_apmode' [-Werror=implicit-function-declaration]
update_sta_info_apmode(padapter, psta);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_del_sta_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3229:12: error: 'struct sta_priv' has no member named 'asoc_list_cnt'
pstapriv->asoc_list_cnt--;
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3230:14: error: implicit declaration of function 'ap_free_sta' [-Werror=implicit-function-declaration]
updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3233:3: error: implicit declaration of function 'associated_clients_update' [-Werror=implicit-function-declaration]
associated_clients_update(padapter, updated);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_beacon_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3276:17: error: 'union <anonymous>' has no member named 'bcn_ie'
pbuf = param->u.bcn_ie.buf;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3283:18: error: 'struct sta_priv' has no member named 'max_num_sta'
memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3283:41: error: 'union <anonymous>' has no member named 'bcn_ie'
memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3285:15: error: 'struct sta_priv' has no member named 'max_num_sta'
if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3285:52: error: 'struct sta_priv' has no member named 'max_num_sta'
if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3286:11: error: 'struct sta_priv' has no member named 'max_num_sta'
pstapriv->max_num_sta = NUM_STA;
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3288:6: error: implicit declaration of function 'rtw_check_beacon_data' [-Werror=implicit-function-declaration]
if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS) // 12 = Param header, 2 = Not packed.
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_encryption_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3412:4: error: implicit declaration of function 'set_wep_key' [-Werror=implicit-function-declaration]
set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3476:4: error: implicit declaration of function 'set_group_key' [-Werror=implicit-function-declaration]
set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3517:5: error: implicit declaration of function 'set_pairwise_key' [-Werror=implicit-function-declaration]
set_pairwise_key(padapter, psta);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_get_sta_wpaie_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3621:11: error: 'struct sta_info' has no member named 'wpa_ie'
if (psta->wpa_ie[0] == WLAN_EID_RSN ||
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3622:11: error: 'struct sta_info' has no member named 'wpa_ie'
psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3626:26: error: 'struct sta_info' has no member named 'wpa_ie'
wpa_ie_len = psta->wpa_ie[1];
^
In file included from include/linux/skbuff.h:17:0,
from include/linux/if_ether.h:23,
from include/linux/ieee80211.h:21,
from drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:17:
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3627:58: error: 'struct sta_info' has no member named 'wpa_ie'
copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
^
include/linux/kernel.h:790:13: note: in definition of macro '__min'
t2 min2 = (y); \
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3627:20: note: in expansion of macro 'min_t'
copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3629:46: error: 'struct sta_info' has no member named 'wpa_ie'
memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_wps_beacon_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3682:17: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
kfree(pmlmepriv->wps_beacon_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3683:11: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
pmlmepriv->wps_beacon_ie = NULL;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3686:12: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3687:12: error: 'struct mlme_priv' has no member named 'wps_beacon_ie_len'
pmlmepriv->wps_beacon_ie_len = ie_len;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3688:17: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
if (!pmlmepriv->wps_beacon_ie) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3693:19: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3693:44: error: 'union <anonymous>' has no member named 'bcn_ie'
memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3694:3: error: implicit declaration of function 'update_beacon' [-Werror=implicit-function-declaration]
update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3696:11: error: 'struct mlme_ext_priv' has no member named 'bstart_bss'
pmlmeext->bstart_bss = true;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_wps_probe_resp_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3742:17: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
kfree(pmlmepriv->wps_probe_resp_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3743:11: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
pmlmepriv->wps_probe_resp_ie = NULL;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3746:12: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3747:12: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie_len'
pmlmepriv->wps_probe_resp_ie_len = ie_len;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3748:17: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
if (!pmlmepriv->wps_probe_resp_ie) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3752:19: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3752:48: error: 'union <anonymous>' has no member named 'bcn_ie'
memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_wps_assoc_resp_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3798:17: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
kfree(pmlmepriv->wps_assoc_resp_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3799:11: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
pmlmepriv->wps_assoc_resp_ie = NULL;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3802:12: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3803:12: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie_len'
pmlmepriv->wps_assoc_resp_ie_len = ie_len;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3804:17: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
if (!pmlmepriv->wps_assoc_resp_ie) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3809:19: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3809:48: error: 'union <anonymous>' has no member named 'bcn_ie'
memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_ioctl_get_sta_data_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3898:41: error: dereferencing pointer to incomplete type 'struct ieee_param_ex'
psta_data = (struct sta_data *)param_ex->data;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3912:12: error: dereferencing pointer to incomplete type 'struct sta_data'
psta_data->aid = (u16)psta->aid;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3913:31: error: 'struct sta_info' has no member named 'capability'
psta_data->capability = psta->capability;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3914:26: error: 'struct sta_info' has no member named 'flags'
psta_data->flags = psta->flags;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3926:10: error: 'struct sta_info' has no member named 'nonerp_set'
((psta->nonerp_set) |
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3927:9: error: 'struct sta_info' has no member named 'no_short_slot_time_set'
(psta->no_short_slot_time_set << 1) |
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3928:9: error: 'struct sta_info' has no member named 'no_short_preamble_set'
(psta->no_short_preamble_set << 2) |
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3929:9: error: 'struct sta_info' has no member named 'no_ht_gf_set'
(psta->no_ht_gf_set << 3) |
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3930:9: error: 'struct sta_info' has no member named 'no_ht_set'
(psta->no_ht_set << 4) |
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3931:9: error: 'struct sta_info' has no member named 'ht_20mhz_set'
(psta->ht_20mhz_set << 5));
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_ioctl_set_macaddr_acl_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3983:2: error: implicit declaration of function 'rtw_set_macaddr_acl' [-Werror=implicit-function-declaration]
rtw_set_macaddr_acl(padapter, param->u.mlme.command);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_ioctl_acl_add_sta_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:4026:8: error: implicit declaration of function 'rtw_acl_add_sta' [-Werror=implicit-function-declaration]
ret = rtw_acl_add_sta(padapter, param->sta_addr);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_ioctl_acl_remove_sta_pvt':
vim +/rtw_sta_flush +3101 drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
3089
3090 static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
3091 struct iw_request_info *info,
3092 union iwreq_data *wrqu,
3093 char *extra)
3094 {
3095 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3096
3097 DBG_88E("%s\n", __func__);
3098
3099 flush_all_cam_entry(padapter); // Clear CAM.
3100
> 3101 return rtw_sta_flush(padapter);
3102 }
3103
3104 static int rtw_add_sta_pvt(struct net_device *dev,
3105 struct iw_request_info *info,
3106 union iwreq_data *wrqu,
3107 char *extra)
3108 {
3109 int ret = 0;
3110 struct sta_info *psta = NULL;
3111 struct ieee_param *param = NULL;
3112 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3113 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3114 struct sta_priv *pstapriv = &padapter->stapriv;
3115
3116 param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
3117
3118 if (!param) {
3119 DBG_88E(" rtw_add_sta: ieee_param allocate fail !!!\n");
3120
3121 return -ENOMEM;
3122 }
3123
3124 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3125
3126 if (ret != 0) {
3127 kfree(param);
3128 DBG_88E(" rtw_add_sta: ieee_param get fail !!!\n");
3129
3130 return ret;
3131 }
3132
3133 DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
3134
3135 if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
3136 return -EINVAL;
3137
3138 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3139 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3140 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
3141 return -EINVAL;
3142
3143 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3144 if (psta) {
> 3145 int flags = param->u.add_sta.flags;
3146 psta->aid = param->u.add_sta.aid; // aid = 1~2007.
3147
> 3148 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
3149
3150 // Check WMM cap.
> 3151 if (WLAN_STA_WME&flags)
3152 psta->qos_option = 1;
3153 else
3154 psta->qos_option = 0;
3155
3156 if (pmlmepriv->qospriv.qos_option == 0)
3157 psta->qos_option = 0;
3158
3159 // Check 802.11n HT cap.
> 3160 if (WLAN_STA_HT&flags) {
3161 psta->htpriv.ht_option = true;
3162 psta->qos_option = 1;
3163 memcpy(&psta->htpriv.ht_cap,
> 3164 ¶m->u.add_sta.ht_cap,
3165 sizeof(struct ieee80211_ht_cap));
3166 } else {
3167 psta->htpriv.ht_option = false;
3168 }
3169
3170 if (pmlmepriv->htpriv.ht_option == false)
3171 psta->htpriv.ht_option = false;
3172
> 3173 update_sta_info_apmode(padapter, psta);
3174 } else {
3175 ret = -ENOMEM;
3176 }
3177
3178 if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
3179 ret = -EFAULT;
3180
3181 return ret;
3182 }
3183
3184 static int rtw_del_sta_pvt(struct net_device *dev,
3185 struct iw_request_info *info,
3186 union iwreq_data *wrqu,
3187 char *extra)
3188 {
3189 int ret = 0;
3190 struct sta_info *psta = NULL;
3191 struct ieee_param *param = NULL;
3192 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3193 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3194 struct sta_priv *pstapriv = &padapter->stapriv;
3195 int updated = 0;
3196
3197 param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
3198
3199 if (!param) {
3200 DBG_88E(" rtw_del_sta: ieee_param allocate fail !!!\n");
3201
3202 return -ENOMEM;
3203 }
3204
3205 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3206
3207 if (ret != 0) {
3208 kfree(param);
3209 DBG_88E(" rtw_del_sta: ieee_param get fail !!!\n");
3210
3211 return ret;
3212 }
3213
3214 DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
3215
3216 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3217 return -EINVAL;
3218
3219 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3220 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3221 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
3222 return -EINVAL;
3223
3224 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3225 if (psta) {
3226 spin_lock_bh(&pstapriv->asoc_list_lock);
3227 if (!list_empty(&psta->asoc_list)) {
3228 list_del_init(&psta->asoc_list);
> 3229 pstapriv->asoc_list_cnt--;
> 3230 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
3231 }
3232 spin_unlock_bh(&pstapriv->asoc_list_lock);
3233 associated_clients_update(padapter, updated);
3234 psta = NULL;
3235 } else {
3236 DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
3237 }
3238
3239 if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
3240 ret = -EFAULT;
3241
3242 return ret;
3243 }
3244
3245 static int rtw_set_beacon_pvt(struct net_device *dev,
3246 struct iw_request_info *info,
3247 union iwreq_data *wrqu,
3248 char *extra)
3249 {
3250 int ret = 0;
3251 int len = 0;
3252 unsigned char *pbuf = NULL;
3253 struct ieee_param *param = NULL;
3254 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3255 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3256 struct sta_priv *pstapriv = &padapter->stapriv;
3257
3258 param = (struct ieee_param *)rtw_malloc(wrqu->data.length);
3259
3260 if (!param) {
3261 DBG_88E(" rtw_set_beacon: ieee_param allocate fail !!!\n");
3262
3263 return -ENOMEM;
3264 }
3265
3266 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3267
3268 if (ret != 0) {
3269 kfree(param);
3270 DBG_88E(" rtw_set_beacon: ieee_param get fail !!!\n");
3271
3272 return ret;
3273 }
3274
3275 len = wrqu->data.length;
> 3276 pbuf = param->u.bcn_ie.buf;
3277
3278 DBG_88E("%s, len =%d\n", __func__, len);
3279
3280 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3281 return -EINVAL;
3282
3283 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3284
> 3285 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
> 3286 pstapriv->max_num_sta = NUM_STA;
3287
> 3288 if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS) // 12 = Param header, 2 = Not packed.
3289 ret = 0;
3290 else
3291 ret = -EINVAL;
3292
3293 if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)))
3294 ret = -EFAULT;
3295
3296 return ret;
3297 }
3298
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 41780 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-25 18:29 ` [PATCH v3] " ishraq.i.ashraf
2017-11-25 21:25 ` Dan Carpenter
@ 2017-11-27 11:24 ` Johannes Berg
2017-11-28 8:00 ` [PATCH] staging: rtl8188eu: fix kzalloc-simple.cocci warnings kbuild test robot
` (2 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: Johannes Berg @ 2017-11-27 11:24 UTC (permalink / raw)
To: ishraq.i.ashraf, gregkh
Cc: himanshujha199640, goudapatilk, insafonov, dan.carpenter, devel,
linux-kernel
In addition to what Dan said,
> +static iw_handler rtw_handlers_private[] = {
> + NULL, /* Empty */
> + rtw_hostapd_sta_flush_pvt, /* RTL871X_HOSTAPD_FLUSH */
> + rtw_add_sta_pvt, /* RTL871X_HOSTAPD_ADD_STA */
> + rtw_del_sta_pvt, /* RTL871X_HOSTAPD_REMOVE_STA */
> + rtw_ioctl_get_sta_data_pvt, /* RTL871X_HOSTAPD_GET_INFO_STA */
> + rtw_get_sta_wpaie_pvt, /* RTL871X_HOSTAPD_GET_WPAIE_STA */
> + rtw_set_encryption_pvt, /* RTL871X_SET_ENCRYPTION */
> + NULL, /* RTL871X_GET_ENCRYPTION */
> + NULL, /* RTL871X_HOSTAPD_SET_FLAGS_STA */
> + NULL, /* RTL871X_HOSTAPD_GET_RID */
> + NULL, /* RTL871X_HOSTAPD_SET_RID */
> + NULL, /* RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR */
> + NULL, /* RTL871X_HOSTAPD_SET_GENERIC_ELEMENT */
> + NULL, /* RTL871X_HOSTAPD_MLME */
> + NULL, /* RTL871X_HOSTAPD_SCAN_REQ */
> + NULL, /* RTL871X_HOSTAPD_STA_CLEAR_STATS */
> + rtw_set_beacon_pvt, /* RTL871X_HOSTAPD_SET_BEACON */
> + rtw_set_wps_beacon_pvt, /* RTL871X_HOSTAPD_SET_WPS_BEACON */
> + rtw_set_wps_probe_resp_pvt, /* RTL871X_HOSTAPD_SET_WPS_PROBE_RESP */
> + rtw_set_wps_assoc_resp_pvt, /* RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP */
> + rtw_set_hidden_ssid_pvt, /* RTL871X_HOSTAPD_SET_HIDDEN_SSID */
> + rtw_ioctl_set_macaddr_acl_pvt, /* RTL871X_HOSTAPD_SET_MACADDR_ACL */
> + rtw_ioctl_acl_add_sta_pvt, /* RTL871X_HOSTAPD_ACL_ADD_STA */
> + rtw_ioctl_acl_remove_sta_pvt, /* RTL871X_HOSTAPD_ACL_REMOVE_STA */
> +};
>
You should probably use array element initializers:
static ... [] = {
[RTL871X_HOSTAPD_FLUSH] = rtw_hostapd_sta_flush_pvt,
...
};
johannes
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-26 0:45 ` Ishraq Ibne Ashraf
@ 2017-11-27 11:33 ` Johannes Berg
0 siblings, 0 replies; 17+ messages in thread
From: Johannes Berg @ 2017-11-27 11:33 UTC (permalink / raw)
To: Ishraq Ibne Ashraf, Dan Carpenter
Cc: gregkh, himanshujha199640, goudapatilk, insafonov, devel, linux-kernel
Hi,
So I removed those call-through place because private wext operations
are a really bad idea and should just die. We don't want drivers to
require specially patched hostapd versions to work right, like here.
I suppose in staging you might want to work around that like here, but
that really means you see no future in mainline for this code, or
otherwise you should fix it the proper way.
johannes
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-25 18:29 ` [PATCH v3] " ishraq.i.ashraf
` (2 preceding siblings ...)
2017-11-28 8:00 ` [PATCH] staging: rtl8188eu: fix kzalloc-simple.cocci warnings kbuild test robot
@ 2017-11-28 8:00 ` kbuild test robot
2017-12-04 15:20 ` kbuild test robot
4 siblings, 0 replies; 17+ messages in thread
From: kbuild test robot @ 2017-11-28 8:00 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: kbuild-all, gregkh, himanshujha199640, goudapatilk, insafonov,
dan.carpenter, devel, linux-kernel, johannes, Ishraq Ibne Ashraf
Hi Ishraq,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on staging/staging-testing]
[also build test WARNING on v4.15-rc1 next-20171127]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/ishraq-i-ashraf-gmail-com/staging-rtl8188eu-Fix-private-WEXT-IOCTL-calls/20171128-130403
coccinelle warnings: (new ones prefixed by >>)
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3379:36-43: WARNING: kzalloc should be used for pwep, instead of kmalloc/memset
Please review and possibly fold the followup patch.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH] staging: rtl8188eu: fix kzalloc-simple.cocci warnings
2017-11-25 18:29 ` [PATCH v3] " ishraq.i.ashraf
2017-11-25 21:25 ` Dan Carpenter
2017-11-27 11:24 ` Johannes Berg
@ 2017-11-28 8:00 ` kbuild test robot
2017-11-28 8:00 ` [PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls kbuild test robot
2017-12-04 15:20 ` kbuild test robot
4 siblings, 0 replies; 17+ messages in thread
From: kbuild test robot @ 2017-11-28 8:00 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: kbuild-all, gregkh, himanshujha199640, goudapatilk, insafonov,
dan.carpenter, devel, linux-kernel, johannes, Ishraq Ibne Ashraf
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3379:36-43: WARNING: kzalloc should be used for pwep, instead of kmalloc/memset
Use kzalloc rather than kmalloc followed by memset with 0
This considers some simple cases that are common and easy to validate
Note in particular that there are no ...s in the rule, so all of the
matched code has to be contiguous
Generated by: scripts/coccinelle/api/alloc/kzalloc-simple.cocci
Fixes: f1ac2c75e0c6 ("staging: rtl8188eu: Fix private WEXT IOCTL calls")
CC: Ishraq Ibne Ashraf <ishraq.i.ashraf@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---
ioctl_linux.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -3376,14 +3376,13 @@ static int rtw_set_encryption_pvt(struct
wep_key_len = wep_key_len <= 5 ? 5 : 13;
wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
- pwep = (struct ndis_802_11_wep *)kmalloc(wep_total_len, GFP_KERNEL);
+ pwep = kzalloc(wep_total_len, GFP_KERNEL);
if (!pwep) {
DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
ret = -ENOMEM;
goto err_free_param;
}
- memset(pwep, 0, wep_total_len);
pwep->KeyLength = wep_key_len;
pwep->Length = wep_total_len;
}
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls
2017-11-25 18:29 ` [PATCH v3] " ishraq.i.ashraf
` (3 preceding siblings ...)
2017-11-28 8:00 ` [PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls kbuild test robot
@ 2017-12-04 15:20 ` kbuild test robot
4 siblings, 0 replies; 17+ messages in thread
From: kbuild test robot @ 2017-12-04 15:20 UTC (permalink / raw)
To: ishraq.i.ashraf
Cc: kbuild-all, gregkh, himanshujha199640, goudapatilk, insafonov,
dan.carpenter, devel, linux-kernel, johannes, Ishraq Ibne Ashraf
[-- Attachment #1: Type: text/plain, Size: 24010 bytes --]
Hi Ishraq,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on staging/staging-testing]
[also build test ERROR on v4.15-rc2 next-20171204]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/ishraq-i-ashraf-gmail-com/staging-rtl8188eu-Fix-private-WEXT-IOCTL-calls/20171128-130403
config: x86_64-randconfig-u0-12042048 (attached as .config)
compiler: gcc-5 (Debian 5.5.0-3) 5.4.1 20171010
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_hostapd_sta_flush_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3088:9: error: implicit declaration of function 'rtw_sta_flush' [-Werror=implicit-function-declaration]
return rtw_sta_flush(padapter);
^
In file included from include/linux/kernel.h:14:0,
from include/linux/skbuff.h:17,
from include/linux/if_ether.h:23,
from include/linux/ieee80211.h:21,
from drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:17:
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_add_sta_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3113:11: error: 'union <anonymous>' has no member named 'add_sta'
param->u.add_sta.aid,
^
include/linux/printk.h:308:34: note: in definition of macro 'pr_info'
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3112:2: note: in expansion of macro 'DBG_88E'
DBG_88E("rtw_add_sta(aid =%d) =%pM\n",
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3134:18: error: 'union <anonymous>' has no member named 'add_sta'
flags = param->u.add_sta.flags;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3135:22: error: 'union <anonymous>' has no member named 'add_sta'
psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3137:35: error: 'union <anonymous>' has no member named 'add_sta'
memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3140:6: error: 'WLAN_STA_WME' undeclared (first use in this function)
if (WLAN_STA_WME&flags)
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3140:6: note: each undeclared identifier is reported only once for each function it appears in
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3149:6: error: 'WLAN_STA_HT' undeclared (first use in this function)
if (WLAN_STA_HT&flags) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3153:19: error: 'union <anonymous>' has no member named 'add_sta'
¶m->u.add_sta.ht_cap,
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3162:2: error: implicit declaration of function 'update_sta_info_apmode' [-Werror=implicit-function-declaration]
update_sta_info_apmode(padapter, psta);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_del_sta_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3225:11: error: 'struct sta_priv' has no member named 'asoc_list_cnt'
pstapriv->asoc_list_cnt--;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3226:13: error: implicit declaration of function 'ap_free_sta' [-Werror=implicit-function-declaration]
updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3230:2: error: implicit declaration of function 'associated_clients_update' [-Werror=implicit-function-declaration]
associated_clients_update(padapter, updated);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_beacon_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3267:17: error: 'union <anonymous>' has no member named 'bcn_ie'
pbuf = param->u.bcn_ie.buf;
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3276:18: error: 'struct sta_priv' has no member named 'max_num_sta'
memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3276:41: error: 'union <anonymous>' has no member named 'bcn_ie'
memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3278:15: error: 'struct sta_priv' has no member named 'max_num_sta'
if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3278:52: error: 'struct sta_priv' has no member named 'max_num_sta'
if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3279:11: error: 'struct sta_priv' has no member named 'max_num_sta'
pstapriv->max_num_sta = NUM_STA;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3281:6: error: implicit declaration of function 'rtw_check_beacon_data' [-Werror=implicit-function-declaration]
if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) != _SUCCESS) { /* 12 = Param header, 2 = Not packed. */
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_encryption_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3411:4: error: implicit declaration of function 'set_wep_key' [-Werror=implicit-function-declaration]
set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3477:4: error: implicit declaration of function 'set_group_key' [-Werror=implicit-function-declaration]
set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3521:5: error: implicit declaration of function 'set_pairwise_key' [-Werror=implicit-function-declaration]
set_pairwise_key(padapter, psta);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_get_sta_wpaie_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3624:10: error: 'struct sta_info' has no member named 'wpa_ie'
if (psta->wpa_ie[0] == WLAN_EID_RSN ||
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3625:10: error: 'struct sta_info' has no member named 'wpa_ie'
psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3629:20: error: 'struct sta_info' has no member named 'wpa_ie'
wpa_ie_len = psta->wpa_ie[1];
^
In file included from include/linux/skbuff.h:17:0,
from include/linux/if_ether.h:23,
from include/linux/ieee80211.h:21,
from drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:17:
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3630:52: error: 'struct sta_info' has no member named 'wpa_ie'
copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
^
include/linux/kernel.h:791:13: note: in definition of macro '__min'
t2 min2 = (y); \
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3630:14: note: in expansion of macro 'min_t'
copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3632:40: error: 'struct sta_info' has no member named 'wpa_ie'
memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_wps_beacon_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3681:17: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
kfree(pmlmepriv->wps_beacon_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3682:11: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
pmlmepriv->wps_beacon_ie = NULL;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3686:12: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
pmlmepriv->wps_beacon_ie = kmalloc(ie_len, GFP_KERNEL);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3687:17: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
if (!pmlmepriv->wps_beacon_ie) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3693:12: error: 'struct mlme_priv' has no member named 'wps_beacon_ie_len'
pmlmepriv->wps_beacon_ie_len = ie_len;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3694:19: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3694:44: error: 'union <anonymous>' has no member named 'bcn_ie'
memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3695:3: error: implicit declaration of function 'update_beacon' [-Werror=implicit-function-declaration]
update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3696:11: error: 'struct mlme_ext_priv' has no member named 'bstart_bss'
pmlmeext->bstart_bss = true;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3704:17: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
kfree(pmlmepriv->wps_beacon_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3709:17: error: 'struct mlme_priv' has no member named 'wps_beacon_ie'
kfree(pmlmepriv->wps_beacon_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_wps_probe_resp_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3745:17: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
kfree(pmlmepriv->wps_probe_resp_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3746:11: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
pmlmepriv->wps_probe_resp_ie = NULL;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3750:12: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
pmlmepriv->wps_probe_resp_ie = kmalloc(ie_len, GFP_KERNEL);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3751:17: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
if (!pmlmepriv->wps_probe_resp_ie) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3757:12: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie_len'
pmlmepriv->wps_probe_resp_ie_len = ie_len;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3758:19: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3758:48: error: 'union <anonymous>' has no member named 'bcn_ie'
memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3766:17: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
kfree(pmlmepriv->wps_probe_resp_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3771:17: error: 'struct mlme_priv' has no member named 'wps_probe_resp_ie'
kfree(pmlmepriv->wps_probe_resp_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_set_wps_assoc_resp_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3807:17: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
kfree(pmlmepriv->wps_assoc_resp_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3808:11: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
pmlmepriv->wps_assoc_resp_ie = NULL;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3812:12: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
pmlmepriv->wps_assoc_resp_ie = kmalloc(ie_len, GFP_KERNEL);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3813:17: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
if (!pmlmepriv->wps_assoc_resp_ie) {
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3819:12: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie_len'
pmlmepriv->wps_assoc_resp_ie_len = ie_len;
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3820:19: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3820:48: error: 'union <anonymous>' has no member named 'bcn_ie'
memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3828:17: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
kfree(pmlmepriv->wps_assoc_resp_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3833:17: error: 'struct mlme_priv' has no member named 'wps_assoc_resp_ie'
kfree(pmlmepriv->wps_assoc_resp_ie);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_ioctl_get_sta_data_pvt':
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3913:41: error: dereferencing pointer to incomplete type 'struct ieee_param_ex'
psta_data = (struct sta_data *)param_ex->data;
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3935:11: error: dereferencing pointer to incomplete type 'struct sta_data'
psta_data->aid = (u16)psta->aid;
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3936:30: error: 'struct sta_info' has no member named 'capability'
psta_data->capability = psta->capability;
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3937:25: error: 'struct sta_info' has no member named 'flags'
psta_data->flags = psta->flags;
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3949:9: error: 'struct sta_info' has no member named 'nonerp_set'
((psta->nonerp_set) |
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3950:8: error: 'struct sta_info' has no member named 'no_short_slot_time_set'
(psta->no_short_slot_time_set << 1) |
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3951:8: error: 'struct sta_info' has no member named 'no_short_preamble_set'
(psta->no_short_preamble_set << 2) |
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3952:8: error: 'struct sta_info' has no member named 'no_ht_gf_set'
(psta->no_ht_gf_set << 3) |
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3953:8: error: 'struct sta_info' has no member named 'no_ht_set'
(psta->no_ht_set << 4) |
^
>> drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3954:8: error: 'struct sta_info' has no member named 'ht_20mhz_set'
(psta->ht_20mhz_set << 5));
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_ioctl_set_macaddr_acl_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:4003:2: error: implicit declaration of function 'rtw_set_macaddr_acl' [-Werror=implicit-function-declaration]
rtw_set_macaddr_acl(padapter, param->u.mlme.command);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_ioctl_acl_add_sta_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:4048:8: error: implicit declaration of function 'rtw_acl_add_sta' [-Werror=implicit-function-declaration]
ret = rtw_acl_add_sta(padapter, param->sta_addr);
^
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c: In function 'rtw_ioctl_acl_remove_sta_pvt':
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:4095:8: error: implicit declaration of function 'rtw_acl_remove_sta' [-Werror=implicit-function-declaration]
ret = rtw_acl_remove_sta(padapter, param->sta_addr);
^
cc1: some warnings being treated as errors
vim +3113 drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
3080
3081 static int rtw_hostapd_sta_flush_pvt(struct net_device *dev,
3082 struct iw_request_info *info,
3083 union iwreq_data *wrqu,
3084 char *extra)
3085 {
3086 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3087 flush_all_cam_entry(padapter); /* Clear CAM. */
> 3088 return rtw_sta_flush(padapter);
3089 }
3090
3091 static int rtw_add_sta_pvt(struct net_device *dev,
3092 struct iw_request_info *info,
3093 union iwreq_data *wrqu,
3094 char *extra)
3095 {
3096 int ret;
3097 int flags;
3098 struct sta_info *psta;
3099 struct ieee_param *param;
3100 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3101 struct sta_priv *pstapriv = &padapter->stapriv;
3102 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3103
3104 param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
3105 if (!param)
3106 return -ENOMEM;
3107
3108 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3109 if (ret)
3110 goto err_free_param;
3111
3112 DBG_88E("rtw_add_sta(aid =%d) =%pM\n",
> 3113 param->u.add_sta.aid,
3114 (param->sta_addr));
3115
3116 if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) {
3117 ret = -EINVAL;
3118 goto err_free_param;
3119 }
3120
3121 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3122 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3123 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3124 ret = -EINVAL;
3125 goto err_free_param;
3126 }
3127
3128 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3129 if (!psta) {
3130 ret = -ENOMEM;
3131 goto err_free_param;
3132 }
3133
3134 flags = param->u.add_sta.flags;
3135 psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */
3136
3137 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
3138
3139 /* Check WMM cap. */
3140 if (WLAN_STA_WME&flags)
3141 psta->qos_option = 1;
3142 else
3143 psta->qos_option = 0;
3144
3145 if (pmlmepriv->qospriv.qos_option == 0)
3146 psta->qos_option = 0;
3147
3148 /* Check 802.11n HT cap. */
3149 if (WLAN_STA_HT&flags) {
3150 psta->htpriv.ht_option = true;
3151 psta->qos_option = 1;
3152 memcpy(&psta->htpriv.ht_cap,
3153 ¶m->u.add_sta.ht_cap,
3154 sizeof(struct ieee80211_ht_cap));
3155 } else {
3156 psta->htpriv.ht_option = false;
3157 }
3158
3159 if (pmlmepriv->htpriv.ht_option == false)
3160 psta->htpriv.ht_option = false;
3161
3162 update_sta_info_apmode(padapter, psta);
3163
3164 if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
3165 ret = -EFAULT;
3166 goto err_free_param;
3167 }
3168
3169 kfree(param);
3170 return 0;
3171
3172 err_free_param:
3173 kfree(param);
3174 return ret;
3175 }
3176
3177 static int rtw_del_sta_pvt(struct net_device *dev,
3178 struct iw_request_info *info,
3179 union iwreq_data *wrqu,
3180 char *extra)
3181 {
3182 int ret;
3183 int updated;
3184 struct sta_info *psta;
3185 struct ieee_param *param;
3186 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3187 struct sta_priv *pstapriv = &padapter->stapriv;
3188 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3189
3190 param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
3191 if (!param)
3192 return -ENOMEM;
3193
3194 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3195 if (ret)
3196 goto err_free_param;
3197
3198 DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
3199
3200 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) {
3201 ret = -EINVAL;
3202 goto err_free_param;
3203 }
3204
3205 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3206 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3207 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3208 ret = -EINVAL;
3209 goto err_free_param;
3210 }
3211
3212 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3213 if (!psta) {
3214 DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
3215 ret = -ENOMEM;
3216 goto err_free_param;
3217 }
3218
3219 spin_lock_bh(&pstapriv->asoc_list_lock);
3220
3221 updated = 0;
3222
3223 if (!list_empty(&psta->asoc_list)) {
3224 list_del_init(&psta->asoc_list);
> 3225 pstapriv->asoc_list_cnt--;
3226 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
3227 }
3228
3229 spin_unlock_bh(&pstapriv->asoc_list_lock);
> 3230 associated_clients_update(padapter, updated);
3231
3232 if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
3233 ret = -EFAULT;
3234 goto err_free_param;
3235 }
3236
3237 kfree(param);
3238 return 0;
3239
3240 err_free_param:
3241 kfree(param);
3242 return ret;
3243 }
3244
3245 static int rtw_set_beacon_pvt(struct net_device *dev,
3246 struct iw_request_info *info,
3247 union iwreq_data *wrqu,
3248 char *extra)
3249 {
3250 int ret;
3251 int len;
3252 unsigned char *pbuf;
3253 struct ieee_param *param;
3254 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3255 struct sta_priv *pstapriv = &padapter->stapriv;
3256 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3257
3258 param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL);
3259 if (!param)
3260 return -ENOMEM;
3261
3262 ret = get_private_handler_ieee_param(padapter, wrqu, param);
3263 if (ret)
3264 goto err_free_param;
3265
3266 len = wrqu->data.length;
3267 pbuf = param->u.bcn_ie.buf;
3268
3269 DBG_88E("%s, len =%d\n", __func__, len);
3270
3271 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
3272 ret = -EINVAL;
3273 goto err_free_param;
3274 }
3275
> 3276 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3277
3278 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
3279 pstapriv->max_num_sta = NUM_STA;
3280
3281 if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) != _SUCCESS) { /* 12 = Param header, 2 = Not packed. */
3282 ret = -EINVAL;
3283 goto err_free_param;
3284 }
3285
3286 if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) {
3287 ret = -EFAULT;
3288 goto err_free_param;
3289 }
3290
3291 kfree(param);
3292 return 0;
3293
3294 err_free_param:
3295 kfree(param);
3296 return ret;
3297 }
3298
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 31164 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2017-12-04 15:20 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-23 1:29 [PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls ishraq.i.ashraf
2017-11-23 13:24 ` Dan Carpenter
2017-11-25 0:52 ` [PATCH 2/2] " ishraq.i.ashraf
2017-11-25 4:40 ` Dan Carpenter
2017-11-25 18:12 ` Ishraq Ibne Ashraf
2017-11-26 0:45 ` Ishraq Ibne Ashraf
2017-11-27 11:33 ` Johannes Berg
2017-11-25 1:29 ` [PATCH v2] " ishraq.i.ashraf
2017-11-25 4:55 ` Dan Carpenter
2017-11-25 18:29 ` [PATCH v3] " ishraq.i.ashraf
2017-11-25 21:25 ` Dan Carpenter
2017-11-27 11:24 ` Johannes Berg
2017-11-28 8:00 ` [PATCH] staging: rtl8188eu: fix kzalloc-simple.cocci warnings kbuild test robot
2017-11-28 8:00 ` [PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls kbuild test robot
2017-12-04 15:20 ` kbuild test robot
2017-11-26 20:45 ` [PATCH] " kbuild test robot
2017-11-26 23:20 ` kbuild test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).