wcn36xx: Fix WEP encryption
authorLoic Poulain <loic.poulain@linaro.org>
Wed, 20 Jun 2018 07:58:00 +0000 (09:58 +0200)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 29 Jun 2018 11:59:17 +0000 (14:59 +0300)
In case of WEP encryption, driver has to configure shared key for
associated station(s). Note that sta pointer is NULL in case of non
pairwise key, causing NULL pointer dereference with existing code
(sta_priv->is_data_encrypted). Fix this by using associated sta list
instead. This enables WEP support as client, WEP AP is non-functional.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/wcn36xx/main.c
drivers/net/wireless/ath/wcn36xx/smd.c

index 6fd0bf66da5d110ded48d6b5b1c0c7ccbc1f8f84..e38443ecaab450502c1caa9c1d789f458a1b207d 100644 (file)
@@ -493,7 +493,7 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 {
        struct wcn36xx *wcn = hw->priv;
        struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
-       struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta);
+       struct wcn36xx_sta *sta_priv = sta ? wcn36xx_sta_to_priv(sta) : NULL;
        int ret = 0;
        u8 key[WLAN_MAX_KEY_LEN];
 
@@ -570,13 +570,16 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
                        if ((WLAN_CIPHER_SUITE_WEP40 == key_conf->cipher) ||
                            (WLAN_CIPHER_SUITE_WEP104 == key_conf->cipher)) {
-                               sta_priv->is_data_encrypted = true;
-                               wcn36xx_smd_set_stakey(wcn,
-                                       vif_priv->encrypt_type,
-                                       key_conf->keyidx,
-                                       key_conf->keylen,
-                                       key,
-                                       get_sta_index(vif, sta_priv));
+                               list_for_each_entry(sta_priv,
+                                                   &vif_priv->sta_list, list) {
+                                       sta_priv->is_data_encrypted = true;
+                                       wcn36xx_smd_set_stakey(wcn,
+                                               vif_priv->encrypt_type,
+                                               key_conf->keyidx,
+                                               key_conf->keylen,
+                                               key,
+                                               get_sta_index(vif, sta_priv));
+                               }
                        }
                }
                break;
index b4dadf75d565eb4172551f952fa5a6368a79e65d..304a86c7dcd29f805f88c8c1762db7af63ddb01b 100644 (file)
@@ -1708,12 +1708,20 @@ int wcn36xx_smd_set_stakey(struct wcn36xx *wcn,
        msg_body.set_sta_key_params.sta_index = sta_index;
        msg_body.set_sta_key_params.enc_type = enc_type;
 
-       msg_body.set_sta_key_params.key[0].id = keyidx;
-       msg_body.set_sta_key_params.key[0].unicast = 1;
-       msg_body.set_sta_key_params.key[0].direction = WCN36XX_HAL_TX_RX;
-       msg_body.set_sta_key_params.key[0].pae_role = 0;
-       msg_body.set_sta_key_params.key[0].length = keylen;
-       memcpy(msg_body.set_sta_key_params.key[0].key, key, keylen);
+       if (enc_type == WCN36XX_HAL_ED_WEP104 ||
+           enc_type == WCN36XX_HAL_ED_WEP40) {
+               /* Use bss key for wep (static) */
+               msg_body.set_sta_key_params.def_wep_idx = keyidx;
+               msg_body.set_sta_key_params.wep_type = 0;
+       } else {
+               msg_body.set_sta_key_params.key[0].id = keyidx;
+               msg_body.set_sta_key_params.key[0].unicast = 1;
+               msg_body.set_sta_key_params.key[0].direction = WCN36XX_HAL_TX_RX;
+               msg_body.set_sta_key_params.key[0].pae_role = 0;
+               msg_body.set_sta_key_params.key[0].length = keylen;
+               memcpy(msg_body.set_sta_key_params.key[0].key, key, keylen);
+       }
+
        msg_body.set_sta_key_params.single_tid_rc = 1;
 
        PREPARE_HAL_BUF(wcn->hal_buf, msg_body);