mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
1, Fix wps memory leak.
2, Add a queue to save wps rx eapol frame. 3, Add data lock protect wpa2_sig_cnt. 4, Add a queue to save wpa2 rx rapol frame.
This commit is contained in:
parent
577d2c5e2b
commit
6c865a84ff
@ -48,6 +48,11 @@
|
|||||||
|
|
||||||
#define WPA2_VERSION "v2.0"
|
#define WPA2_VERSION "v2.0"
|
||||||
|
|
||||||
|
#define DATA_MUTEX_TAKE() xSemaphoreTakeRecursive(s_wpa2_data_lock,portMAX_DELAY)
|
||||||
|
#define DATA_MUTEX_GIVE() xSemaphoreGiveRecursive(s_wpa2_data_lock)
|
||||||
|
|
||||||
|
static void *s_wpa2_data_lock = NULL;
|
||||||
|
|
||||||
static struct eap_sm *gEapSm = NULL;
|
static struct eap_sm *gEapSm = NULL;
|
||||||
|
|
||||||
static int eap_peer_sm_init(void);
|
static int eap_peer_sm_init(void);
|
||||||
@ -134,7 +139,48 @@ struct wpa2_rx_param {
|
|||||||
u8 sa[WPA_ADDR_LEN];
|
u8 sa[WPA_ADDR_LEN];
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
int len;
|
int len;
|
||||||
|
STAILQ_ENTRY(wpa2_rx_param) bqentry;
|
||||||
};
|
};
|
||||||
|
static STAILQ_HEAD(, wpa2_rx_param) s_wpa2_rxq;
|
||||||
|
|
||||||
|
static void wpa2_rxq_init(void)
|
||||||
|
{
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
STAILQ_INIT(&s_wpa2_rxq);
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wpa2_rxq_enqueue(struct wpa2_rx_param *param)
|
||||||
|
{
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
STAILQ_INSERT_TAIL(&s_wpa2_rxq,param, bqentry);
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wpa2_rx_param * wpa2_rxq_dequeue(void)
|
||||||
|
{
|
||||||
|
struct wpa2_rx_param *param = NULL;
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
if ((param = STAILQ_FIRST(&s_wpa2_rxq)) != NULL) {
|
||||||
|
STAILQ_REMOVE_HEAD(&s_wpa2_rxq, bqentry);
|
||||||
|
STAILQ_NEXT(param,bqentry) = NULL;
|
||||||
|
}
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wpa2_rxq_deinit(void)
|
||||||
|
{
|
||||||
|
struct wpa2_rx_param *param = NULL;
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
while ((param = STAILQ_FIRST(&s_wpa2_rxq)) != NULL) {
|
||||||
|
STAILQ_REMOVE_HEAD(&s_wpa2_rxq, bqentry);
|
||||||
|
STAILQ_NEXT(param,bqentry) = NULL;
|
||||||
|
os_free(param->buf);
|
||||||
|
os_free(param);
|
||||||
|
}
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
}
|
||||||
|
|
||||||
void wpa2_task(void *pvParameters )
|
void wpa2_task(void *pvParameters )
|
||||||
{
|
{
|
||||||
@ -150,20 +196,26 @@ void wpa2_task(void *pvParameters )
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if ( pdPASS == xQueueReceive(s_wpa2_queue, &e, portMAX_DELAY) ) {
|
if ( pdPASS == xQueueReceive(s_wpa2_queue, &e, portMAX_DELAY) ) {
|
||||||
sig = e->sig;
|
sig = e->sig;
|
||||||
|
if (e->sig < SIG_WPA2_MAX) {
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
if(sm->wpa2_sig_cnt[e->sig]) {
|
||||||
|
sm->wpa2_sig_cnt[e->sig]--;
|
||||||
|
} else {
|
||||||
|
wpa_printf(MSG_ERROR, "wpa2_task: invalid sig cnt, sig=%d cnt=%d", e->sig, sm->wpa2_sig_cnt[e->sig]);
|
||||||
|
}
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
}
|
||||||
switch (e->sig) {
|
switch (e->sig) {
|
||||||
case SIG_WPA2_TASK_DEL:
|
case SIG_WPA2_TASK_DEL:
|
||||||
task_del = true;
|
task_del = true;
|
||||||
break;
|
break;
|
||||||
case SIG_WPA2_START:
|
case SIG_WPA2_START:
|
||||||
sm->wpa2_sig_cnt[e->sig]--;
|
|
||||||
wpa2_start_eapol_internal();
|
wpa2_start_eapol_internal();
|
||||||
break;
|
break;
|
||||||
case SIG_WPA2_RX: {
|
case SIG_WPA2_RX: {
|
||||||
struct wpa2_rx_param *param;
|
struct wpa2_rx_param *param = NULL;
|
||||||
|
|
||||||
sm->wpa2_sig_cnt[e->sig]--;
|
while ((param = wpa2_rxq_dequeue()) != NULL){
|
||||||
param = (struct wpa2_rx_param *)(e->par);
|
|
||||||
if (param) {
|
|
||||||
wpa2_sm_rx_eapol_internal(param->sa, param->buf, param->len, param->bssid);
|
wpa2_sm_rx_eapol_internal(param->sa, param->buf, param->len, param->bssid);
|
||||||
os_free(param->buf);
|
os_free(param->buf);
|
||||||
os_free(param);
|
os_free(param);
|
||||||
@ -211,15 +263,19 @@ int wpa2_post(uint32_t sig, uint32_t par)
|
|||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
if (sm->wpa2_sig_cnt[sig]) {
|
if (sm->wpa2_sig_cnt[sig]) {
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
} else {
|
} else {
|
||||||
ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent));
|
ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent));
|
||||||
if (evt == NULL) {
|
if (evt == NULL) {
|
||||||
wpa_printf(MSG_ERROR, "WPA2: E N M\n");
|
wpa_printf(MSG_ERROR, "WPA2: E N M\n");
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
sm->wpa2_sig_cnt[sig]++;
|
sm->wpa2_sig_cnt[sig]++;
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
evt->sig = sig;
|
evt->sig = sig;
|
||||||
evt->par = par;
|
evt->par = par;
|
||||||
if ( xQueueSend(s_wpa2_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) {
|
if ( xQueueSend(s_wpa2_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) {
|
||||||
@ -302,8 +358,8 @@ void wpa2_sm_free_eapol(u8 *buffer)
|
|||||||
{
|
{
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
buffer = buffer - sizeof(struct l2_ethhdr);
|
buffer = buffer - sizeof(struct l2_ethhdr);
|
||||||
|
os_free(buffer);
|
||||||
}
|
}
|
||||||
os_free(buffer);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,7 +536,8 @@ static int wpa2_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid)
|
|||||||
param->len = len;
|
param->len = len;
|
||||||
memcpy(param->sa, src_addr, WPA_ADDR_LEN);
|
memcpy(param->sa, src_addr, WPA_ADDR_LEN);
|
||||||
|
|
||||||
return wpa2_post(SIG_WPA2_RX, (uint32_t)param);
|
wpa2_rxq_enqueue(param);
|
||||||
|
return wpa2_post(SIG_WPA2_RX, 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -656,6 +713,12 @@ static int eap_peer_sm_init(void)
|
|||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s_wpa2_data_lock = xSemaphoreCreateRecursiveMutex();
|
||||||
|
if (!s_wpa2_data_lock) {
|
||||||
|
wpa_printf(MSG_ERROR, "wpa2 eap_peer_sm_init: failed to alloc data lock");
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_NOT_START);
|
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_NOT_START);
|
||||||
sm->current_identifier = 0xff;
|
sm->current_identifier = 0xff;
|
||||||
esp_wifi_get_macaddr_internal(WIFI_IF_STA, sm->ownaddr);
|
esp_wifi_get_macaddr_internal(WIFI_IF_STA, sm->ownaddr);
|
||||||
@ -684,6 +747,7 @@ static int eap_peer_sm_init(void)
|
|||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa2_rxq_init();
|
||||||
|
|
||||||
gEapSm = sm;
|
gEapSm = sm;
|
||||||
#ifdef USE_WPA2_TASK
|
#ifdef USE_WPA2_TASK
|
||||||
@ -724,11 +788,22 @@ static void eap_peer_sm_deinit(void)
|
|||||||
#ifdef USE_WPA2_TASK
|
#ifdef USE_WPA2_TASK
|
||||||
wpa2_task_delete(0);
|
wpa2_task_delete(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (STAILQ_FIRST((&s_wpa2_rxq)) != NULL) {
|
||||||
|
wpa2_rxq_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
if (s_wifi_wpa2_sync_sem) {
|
if (s_wifi_wpa2_sync_sem) {
|
||||||
vSemaphoreDelete(s_wifi_wpa2_sync_sem);
|
vSemaphoreDelete(s_wifi_wpa2_sync_sem);
|
||||||
}
|
}
|
||||||
s_wifi_wpa2_sync_sem = NULL;
|
s_wifi_wpa2_sync_sem = NULL;
|
||||||
|
|
||||||
|
if (s_wpa2_data_lock) {
|
||||||
|
vSemaphoreDelete(s_wpa2_data_lock);
|
||||||
|
s_wpa2_data_lock = NULL;
|
||||||
|
wpa_printf(MSG_DEBUG, "wpa2 eap_peer_sm_deinit: free data lock");
|
||||||
|
}
|
||||||
|
|
||||||
os_free(sm);
|
os_free(sm);
|
||||||
gEapSm = NULL;
|
gEapSm = NULL;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,9 @@ struct wps_rx_param {
|
|||||||
u8 sa[WPS_ADDR_LEN];
|
u8 sa[WPS_ADDR_LEN];
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
int len;
|
int len;
|
||||||
|
STAILQ_ENTRY(wps_rx_param) bqentry;
|
||||||
};
|
};
|
||||||
|
static STAILQ_HEAD(,wps_rx_param) s_wps_rxq;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *arg;
|
void *arg;
|
||||||
@ -111,6 +113,45 @@ int wps_set_status(uint32_t status)
|
|||||||
return esp_wifi_set_wps_status_internal(status);
|
return esp_wifi_set_wps_status_internal(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wps_rxq_init(void)
|
||||||
|
{
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
STAILQ_INIT(&s_wps_rxq);
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wps_rxq_enqueue(struct wps_rx_param *param)
|
||||||
|
{
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
STAILQ_INSERT_TAIL(&s_wps_rxq,param, bqentry);
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wps_rx_param * wps_rxq_dequeue(void)
|
||||||
|
{
|
||||||
|
struct wps_rx_param *param = NULL;
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
if ((param = STAILQ_FIRST(&s_wps_rxq)) != NULL) {
|
||||||
|
STAILQ_REMOVE_HEAD(&s_wps_rxq, bqentry);
|
||||||
|
STAILQ_NEXT(param,bqentry) = NULL;
|
||||||
|
}
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wps_rxq_deinit(void)
|
||||||
|
{
|
||||||
|
struct wps_rx_param *param = NULL;
|
||||||
|
DATA_MUTEX_TAKE();
|
||||||
|
while ((param = STAILQ_FIRST(&s_wps_rxq)) != NULL) {
|
||||||
|
STAILQ_REMOVE_HEAD(&s_wps_rxq, bqentry);
|
||||||
|
STAILQ_NEXT(param,bqentry) = NULL;
|
||||||
|
os_free(param->buf);
|
||||||
|
os_free(param);
|
||||||
|
}
|
||||||
|
DATA_MUTEX_GIVE();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_WPS_TASK
|
#ifdef USE_WPS_TASK
|
||||||
void wps_task(void *pvParameters )
|
void wps_task(void *pvParameters )
|
||||||
{
|
{
|
||||||
@ -161,10 +202,8 @@ void wps_task(void *pvParameters )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SIG_WPS_RX: {
|
case SIG_WPS_RX: {
|
||||||
struct wps_rx_param *param;
|
struct wps_rx_param *param = NULL;
|
||||||
|
while ((param = wps_rxq_dequeue()) != NULL) {
|
||||||
param = (struct wps_rx_param *)(e->par);
|
|
||||||
if (param) {
|
|
||||||
wps_sm_rx_eapol_internal(param->sa, param->buf, param->len);
|
wps_sm_rx_eapol_internal(param->sa, param->buf, param->len);
|
||||||
os_free(param->buf);
|
os_free(param->buf);
|
||||||
os_free(param);
|
os_free(param);
|
||||||
@ -311,9 +350,10 @@ u8 *wps_sm_alloc_eapol(struct wps_sm *sm, u8 type,
|
|||||||
|
|
||||||
void wps_sm_free_eapol(u8 *buffer)
|
void wps_sm_free_eapol(u8 *buffer)
|
||||||
{
|
{
|
||||||
buffer = buffer - sizeof(struct l2_ethhdr);
|
if (buffer != NULL) {
|
||||||
os_free(buffer);
|
buffer = buffer - sizeof(struct l2_ethhdr);
|
||||||
|
os_free(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -658,6 +698,7 @@ int wps_send_frag_ack(u8 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
|
ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
|
||||||
|
wps_sm_free_eapol(buf);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = ESP_ERR_NO_MEM;
|
ret = ESP_ERR_NO_MEM;
|
||||||
goto _err;
|
goto _err;
|
||||||
@ -835,6 +876,7 @@ int wps_send_wps_mX_rsp(u8 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
|
ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
|
||||||
|
wps_sm_free_eapol(buf);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _err;
|
goto _err;
|
||||||
@ -1055,7 +1097,8 @@ int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len)
|
|||||||
param->len = len;
|
param->len = len;
|
||||||
memcpy(param->sa, src_addr, WPS_ADDR_LEN);
|
memcpy(param->sa, src_addr, WPS_ADDR_LEN);
|
||||||
|
|
||||||
return wps_post(SIG_WPS_RX, (uint32_t)param);
|
wps_rxq_enqueue(param);
|
||||||
|
return wps_post(SIG_WPS_RX, 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return wps_sm_rx_eapol_internal(src_addr, buf, len);
|
return wps_sm_rx_eapol_internal(src_addr, buf, len);
|
||||||
@ -1828,12 +1871,6 @@ int wps_task_deinit(void)
|
|||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "wps task deinit");
|
wpa_printf(MSG_DEBUG, "wps task deinit");
|
||||||
|
|
||||||
if (s_wps_data_lock) {
|
|
||||||
vSemaphoreDelete(s_wps_data_lock);
|
|
||||||
s_wps_data_lock = NULL;
|
|
||||||
wpa_printf(MSG_DEBUG, "wps task deinit: free data lock");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_wps_api_sem) {
|
if (s_wps_api_sem) {
|
||||||
vSemaphoreDelete(s_wps_api_sem);
|
vSemaphoreDelete(s_wps_api_sem);
|
||||||
s_wps_api_sem = NULL;
|
s_wps_api_sem = NULL;
|
||||||
@ -1858,6 +1895,16 @@ int wps_task_deinit(void)
|
|||||||
wpa_printf(MSG_DEBUG, "wps task deinit: free task");
|
wpa_printf(MSG_DEBUG, "wps task deinit: free task");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (STAILQ_FIRST(&s_wps_rxq) != NULL){
|
||||||
|
wps_rxq_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_wps_data_lock) {
|
||||||
|
vSemaphoreDelete(s_wps_data_lock);
|
||||||
|
s_wps_data_lock = NULL;
|
||||||
|
wpa_printf(MSG_DEBUG, "wps task deinit: free data lock");
|
||||||
|
}
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1894,6 +1941,8 @@ int wps_task_init(void)
|
|||||||
goto _wps_no_mem;
|
goto _wps_no_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wps_rxq_init();
|
||||||
|
|
||||||
ret = xTaskCreate(wps_task, "wpsT", WPS_TASK_STACK_SIZE, NULL, 2, &s_wps_task_hdl);
|
ret = xTaskCreate(wps_task, "wpsT", WPS_TASK_STACK_SIZE, NULL, 2, &s_wps_task_hdl);
|
||||||
if (pdPASS != ret) {
|
if (pdPASS != ret) {
|
||||||
wpa_printf(MSG_ERROR, "wps enable: failed to create task");
|
wpa_printf(MSG_ERROR, "wps enable: failed to create task");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user