@ -281,6 +281,22 @@ static int no_seq_check(struct nl_msg *msg, void *arg)
}
static void nl80211_nlmsg_clear ( struct nl_msg * msg )
{
/*
* Clear nlmsg data , e . g . , to make sure key material is not left in
* heap memory for unnecessarily long time .
*/
if ( msg ) {
struct nlmsghdr * hdr = nlmsg_hdr ( msg ) ;
void * data = nlmsg_data ( hdr ) ;
int len = nlmsg_datalen ( hdr ) ;
os_memset ( data , 0 , len ) ;
}
}
static int send_and_recv ( struct nl80211_global * global ,
struct nl_handle * nl_handle , struct nl_msg * msg ,
int ( * valid_handler ) ( struct nl_msg * , void * ) ,
@ -320,6 +336,8 @@ static int send_and_recv(struct nl80211_global *global,
}
out :
nl_cb_put ( cb ) ;
if ( ! valid_handler & & valid_data = = ( void * ) - 1 )
nl80211_nlmsg_clear ( msg ) ;
nlmsg_free ( msg ) ;
return err ;
}
@ -2331,10 +2349,11 @@ static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv,
nla_put_u32 ( msg , NL80211_ATTR_VENDOR_SUBCMD ,
QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY ) | |
nla_put ( msg , NL80211_ATTR_VENDOR_DATA , key_len , key ) ) {
nl80211_nlmsg_clear ( msg ) ;
nlmsg_free ( msg ) ;
return - 1 ;
}
ret = send_and_recv_msgs ( drv , msg , NULL , NULL ) ;
ret = send_and_recv_msgs ( drv , msg , NULL , ( void * ) - 1 ) ;
if ( ret ) {
wpa_printf ( MSG_DEBUG ,
" nl80211: Key management set key failed: ret=%d (%s) " ,
@ -2426,7 +2445,7 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
if ( nla_put_u8 ( msg , NL80211_ATTR_KEY_IDX , key_idx ) )
goto fail ;
ret = send_and_recv_msgs ( drv , msg , NULL , NULL ) ;
ret = send_and_recv_msgs ( drv , msg , NULL , key ? ( void * ) - 1 : NULL ) ;
if ( ( ret = = - ENOENT | | ret = = - ENOLINK ) & & alg = = WPA_ALG_NONE )
ret = 0 ;
if ( ret )
@ -2477,6 +2496,7 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
return ret ;
fail :
nl80211_nlmsg_clear ( msg ) ;
nlmsg_free ( msg ) ;
return - ENOBUFS ;
}
@ -6717,13 +6737,14 @@ static void nl80211_set_rekey_info(void *priv, const u8 *kek, const u8 *kck,
nla_put ( msg , NL80211_REKEY_DATA_KCK , NL80211_KCK_LEN , kck ) | |
nla_put ( msg , NL80211_REKEY_DATA_REPLAY_CTR , NL80211_REPLAY_CTR_LEN ,
replay_ctr ) ) {
nl80211_nlmsg_clear ( msg ) ;
nlmsg_free ( msg ) ;
return ;
}
nla_nest_end ( msg , replay_nested ) ;
send_and_recv_msgs ( drv , msg , NULL , NULL ) ;
send_and_recv_msgs ( drv , msg , NULL , ( void * ) - 1 ) ;
}