wpa_auth: Make struct wpa_auth_callbacks const

Instead of copying the struct wpa_auth_callbacks, just keep a pointer to
it, keep the context pointer separate, and let the user just provide a
static const structure. This reduces the attack surface of heap
overwrites, since the function pointers move elsewhere.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
master
Johannes Berg 8 years ago committed by Jouni Malinen
parent 30eddf3529
commit cef8fac04b

@ -75,8 +75,8 @@ static const int dot11RSNAConfigSATimeout = 60;
static inline int wpa_auth_mic_failure_report(
struct wpa_authenticator *wpa_auth, const u8 *addr)
{
if (wpa_auth->cb.mic_failure_report)
return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);
if (wpa_auth->cb->mic_failure_report)
return wpa_auth->cb->mic_failure_report(wpa_auth->cb_ctx, addr);
return 0;
}
@ -84,8 +84,8 @@ static inline int wpa_auth_mic_failure_report(
static inline void wpa_auth_psk_failure_report(
struct wpa_authenticator *wpa_auth, const u8 *addr)
{
if (wpa_auth->cb.psk_failure_report)
wpa_auth->cb.psk_failure_report(wpa_auth->cb.ctx, addr);
if (wpa_auth->cb->psk_failure_report)
wpa_auth->cb->psk_failure_report(wpa_auth->cb_ctx, addr);
}
@ -93,17 +93,17 @@ static inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth,
const u8 *addr, wpa_eapol_variable var,
int value)
{
if (wpa_auth->cb.set_eapol)
wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value);
if (wpa_auth->cb->set_eapol)
wpa_auth->cb->set_eapol(wpa_auth->cb_ctx, addr, var, value);
}
static inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth,
const u8 *addr, wpa_eapol_variable var)
{
if (wpa_auth->cb.get_eapol == NULL)
if (wpa_auth->cb->get_eapol == NULL)
return -1;
return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var);
return wpa_auth->cb->get_eapol(wpa_auth->cb_ctx, addr, var);
}
@ -112,19 +112,19 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
const u8 *p2p_dev_addr,
const u8 *prev_psk)
{
if (wpa_auth->cb.get_psk == NULL)
if (wpa_auth->cb->get_psk == NULL)
return NULL;
return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, p2p_dev_addr,
prev_psk);
return wpa_auth->cb->get_psk(wpa_auth->cb_ctx, addr, p2p_dev_addr,
prev_psk);
}
static inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth,
const u8 *addr, u8 *msk, size_t *len)
{
if (wpa_auth->cb.get_msk == NULL)
if (wpa_auth->cb->get_msk == NULL)
return -1;
return wpa_auth->cb.get_msk(wpa_auth->cb.ctx, addr, msk, len);
return wpa_auth->cb->get_msk(wpa_auth->cb_ctx, addr, msk, len);
}
@ -133,19 +133,19 @@ static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
enum wpa_alg alg, const u8 *addr, int idx,
u8 *key, size_t key_len)
{
if (wpa_auth->cb.set_key == NULL)
if (wpa_auth->cb->set_key == NULL)
return -1;
return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx,
key, key_len);
return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
key, key_len);
}
static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
const u8 *addr, int idx, u8 *seq)
{
if (wpa_auth->cb.get_seqnum == NULL)
if (wpa_auth->cb->get_seqnum == NULL)
return -1;
return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq);
return wpa_auth->cb->get_seqnum(wpa_auth->cb_ctx, addr, idx, seq);
}
@ -153,10 +153,10 @@ static inline int
wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,
const u8 *data, size_t data_len, int encrypt)
{
if (wpa_auth->cb.send_eapol == NULL)
if (wpa_auth->cb->send_eapol == NULL)
return -1;
return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len,
encrypt);
return wpa_auth->cb->send_eapol(wpa_auth->cb_ctx, addr, data, data_len,
encrypt);
}
@ -164,9 +164,9 @@ wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,
static inline int wpa_auth_start_ampe(struct wpa_authenticator *wpa_auth,
const u8 *addr)
{
if (wpa_auth->cb.start_ampe == NULL)
if (wpa_auth->cb->start_ampe == NULL)
return -1;
return wpa_auth->cb.start_ampe(wpa_auth->cb.ctx, addr);
return wpa_auth->cb->start_ampe(wpa_auth->cb_ctx, addr);
}
#endif /* CONFIG_MESH */
@ -175,9 +175,9 @@ int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth,
int (*cb)(struct wpa_state_machine *sm, void *ctx),
void *cb_ctx)
{
if (wpa_auth->cb.for_each_sta == NULL)
if (wpa_auth->cb->for_each_sta == NULL)
return 0;
return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx);
return wpa_auth->cb->for_each_sta(wpa_auth->cb_ctx, cb, cb_ctx);
}
@ -185,18 +185,18 @@ int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,
int (*cb)(struct wpa_authenticator *a, void *ctx),
void *cb_ctx)
{
if (wpa_auth->cb.for_each_auth == NULL)
if (wpa_auth->cb->for_each_auth == NULL)
return 0;
return wpa_auth->cb.for_each_auth(wpa_auth->cb.ctx, cb, cb_ctx);
return wpa_auth->cb->for_each_auth(wpa_auth->cb_ctx, cb, cb_ctx);
}
void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr,
logger_level level, const char *txt)
{
if (wpa_auth->cb.logger == NULL)
if (wpa_auth->cb->logger == NULL)
return;
wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt);
wpa_auth->cb->logger(wpa_auth->cb_ctx, addr, level, txt);
}
@ -207,7 +207,7 @@ void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr,
int maxlen;
va_list ap;
if (wpa_auth->cb.logger == NULL)
if (wpa_auth->cb->logger == NULL)
return;
maxlen = os_strlen(fmt) + 100;
@ -228,11 +228,11 @@ void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr,
static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,
const u8 *addr)
{
if (wpa_auth->cb.disconnect == NULL)
if (wpa_auth->cb->disconnect == NULL)
return;
wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr));
wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr,
WLAN_REASON_PREV_AUTH_NOT_VALID);
wpa_auth->cb->disconnect(wpa_auth->cb_ctx, addr,
WLAN_REASON_PREV_AUTH_NOT_VALID);
}
@ -416,7 +416,8 @@ static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
*/
struct wpa_authenticator * wpa_init(const u8 *addr,
struct wpa_auth_config *conf,
struct wpa_auth_callbacks *cb)
const struct wpa_auth_callbacks *cb,
void *cb_ctx)
{
struct wpa_authenticator *wpa_auth;
@ -425,7 +426,8 @@ struct wpa_authenticator * wpa_init(const u8 *addr,
return NULL;
os_memcpy(wpa_auth->addr, addr, ETH_ALEN);
os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
os_memcpy(&wpa_auth->cb, cb, sizeof(*cb));
wpa_auth->cb = cb;
wpa_auth->cb_ctx = cb_ctx;
if (wpa_auth_gen_wpa_ie(wpa_auth)) {
wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
@ -1949,7 +1951,7 @@ SM_STATE(WPA_PTK, INITPMK)
#endif /* CONFIG_IEEE80211R_AP */
} else {
wpa_printf(MSG_DEBUG, "WPA: Could not get PMK, get_msk: %p",
sm->wpa_auth->cb.get_msk);
sm->wpa_auth->cb->get_msk);
sm->Disconnect = TRUE;
return;
}

@ -198,7 +198,6 @@ typedef enum {
} wpa_eapol_variable;
struct wpa_auth_callbacks {
void *ctx;
void (*logger)(void *ctx, const u8 *addr, logger_level level,
const char *txt);
void (*disconnect)(void *ctx, const u8 *addr, u16 reason);
@ -235,7 +234,8 @@ struct wpa_auth_callbacks {
struct wpa_authenticator * wpa_init(const u8 *addr,
struct wpa_auth_config *conf,
struct wpa_auth_callbacks *cb);
const struct wpa_auth_callbacks *cb,
void *cb_ctx);
int wpa_init_keys(struct wpa_authenticator *wpa_auth);
void wpa_deinit(struct wpa_authenticator *wpa_auth);
int wpa_reconfig(struct wpa_authenticator *wpa_auth,

@ -33,21 +33,21 @@ static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm,
static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst,
const u8 *data, size_t data_len)
{
if (wpa_auth->cb.send_ether == NULL)
if (wpa_auth->cb->send_ether == NULL)
return -1;
wpa_printf(MSG_DEBUG, "FT: RRB send to " MACSTR, MAC2STR(dst));
return wpa_auth->cb.send_ether(wpa_auth->cb.ctx, dst, ETH_P_RRB,
data, data_len);
return wpa_auth->cb->send_ether(wpa_auth->cb_ctx, dst, ETH_P_RRB,
data, data_len);
}
static int wpa_ft_action_send(struct wpa_authenticator *wpa_auth,
const u8 *dst, const u8 *data, size_t data_len)
{
if (wpa_auth->cb.send_ft_action == NULL)
if (wpa_auth->cb->send_ft_action == NULL)
return -1;
return wpa_auth->cb.send_ft_action(wpa_auth->cb.ctx, dst,
data, data_len);
return wpa_auth->cb->send_ft_action(wpa_auth->cb_ctx, dst,
data, data_len);
}
@ -55,19 +55,19 @@ static const u8 * wpa_ft_get_psk(struct wpa_authenticator *wpa_auth,
const u8 *addr, const u8 *p2p_dev_addr,
const u8 *prev_psk)
{
if (wpa_auth->cb.get_psk == NULL)
if (wpa_auth->cb->get_psk == NULL)
return NULL;
return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, p2p_dev_addr,
prev_psk);
return wpa_auth->cb->get_psk(wpa_auth->cb_ctx, addr, p2p_dev_addr,
prev_psk);
}
static struct wpa_state_machine *
wpa_ft_add_sta(struct wpa_authenticator *wpa_auth, const u8 *sta_addr)
{
if (wpa_auth->cb.add_sta == NULL)
if (wpa_auth->cb->add_sta == NULL)
return NULL;
return wpa_auth->cb.add_sta(wpa_auth->cb.ctx, sta_addr);
return wpa_auth->cb->add_sta(wpa_auth->cb_ctx, sta_addr);
}
@ -75,12 +75,12 @@ static int wpa_ft_add_tspec(struct wpa_authenticator *wpa_auth,
const u8 *sta_addr,
u8 *tspec_ie, size_t tspec_ielen)
{
if (wpa_auth->cb.add_tspec == NULL) {
if (wpa_auth->cb->add_tspec == NULL) {
wpa_printf(MSG_DEBUG, "FT: add_tspec is not initialized");
return -1;
}
return wpa_auth->cb.add_tspec(wpa_auth->cb.ctx, sta_addr, tspec_ie,
tspec_ielen);
return wpa_auth->cb->add_tspec(wpa_auth->cb_ctx, sta_addr, tspec_ie,
tspec_ielen);
}
@ -418,9 +418,9 @@ int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
const u8 *addr, int idx, u8 *seq)
{
if (wpa_auth->cb.get_seqnum == NULL)
if (wpa_auth->cb->get_seqnum == NULL)
return -1;
return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq);
return wpa_auth->cb->get_seqnum(wpa_auth->cb_ctx, addr, idx, seq);
}
@ -773,10 +773,10 @@ static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
enum wpa_alg alg, const u8 *addr, int idx,
u8 *key, size_t key_len)
{
if (wpa_auth->cb.set_key == NULL)
if (wpa_auth->cb->set_key == NULL)
return -1;
return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx,
key, key_len);
return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
key, key_len);
}

@ -595,7 +595,27 @@ static int hostapd_wpa_auth_add_tspec(void *ctx, const u8 *sta_addr,
int hostapd_setup_wpa(struct hostapd_data *hapd)
{
struct wpa_auth_config _conf;
struct wpa_auth_callbacks cb;
static const struct wpa_auth_callbacks cb = {
.logger = hostapd_wpa_auth_logger,
.disconnect = hostapd_wpa_auth_disconnect,
.mic_failure_report = hostapd_wpa_auth_mic_failure_report,
.psk_failure_report = hostapd_wpa_auth_psk_failure_report,
.set_eapol = hostapd_wpa_auth_set_eapol,
.get_eapol = hostapd_wpa_auth_get_eapol,
.get_psk = hostapd_wpa_auth_get_psk,
.get_msk = hostapd_wpa_auth_get_msk,
.set_key = hostapd_wpa_auth_set_key,
.get_seqnum = hostapd_wpa_auth_get_seqnum,
.send_eapol = hostapd_wpa_auth_send_eapol,
.for_each_sta = hostapd_wpa_auth_for_each_sta,
.for_each_auth = hostapd_wpa_auth_for_each_auth,
.send_ether = hostapd_wpa_auth_send_ether,
#ifdef CONFIG_IEEE80211R_AP
.send_ft_action = hostapd_wpa_auth_send_ft_action,
.add_sta = hostapd_wpa_auth_add_sta,
.add_tspec = hostapd_wpa_auth_add_tspec,
#endif /* CONFIG_IEEE80211R_AP */
};
const u8 *wpa_ie;
size_t wpa_ie_len;
@ -604,28 +624,7 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
_conf.tx_status = 1;
if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_MLME)
_conf.ap_mlme = 1;
os_memset(&cb, 0, sizeof(cb));
cb.ctx = hapd;
cb.logger = hostapd_wpa_auth_logger;
cb.disconnect = hostapd_wpa_auth_disconnect;
cb.mic_failure_report = hostapd_wpa_auth_mic_failure_report;
cb.psk_failure_report = hostapd_wpa_auth_psk_failure_report;
cb.set_eapol = hostapd_wpa_auth_set_eapol;
cb.get_eapol = hostapd_wpa_auth_get_eapol;
cb.get_psk = hostapd_wpa_auth_get_psk;
cb.get_msk = hostapd_wpa_auth_get_msk;
cb.set_key = hostapd_wpa_auth_set_key;
cb.get_seqnum = hostapd_wpa_auth_get_seqnum;
cb.send_eapol = hostapd_wpa_auth_send_eapol;
cb.for_each_sta = hostapd_wpa_auth_for_each_sta;
cb.for_each_auth = hostapd_wpa_auth_for_each_auth;
cb.send_ether = hostapd_wpa_auth_send_ether;
#ifdef CONFIG_IEEE80211R_AP
cb.send_ft_action = hostapd_wpa_auth_send_ft_action;
cb.add_sta = hostapd_wpa_auth_add_sta;
cb.add_tspec = hostapd_wpa_auth_add_tspec;
#endif /* CONFIG_IEEE80211R_AP */
hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb);
hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd);
if (hapd->wpa_auth == NULL) {
wpa_printf(MSG_ERROR, "WPA initialization failed.");
return -1;

@ -203,7 +203,8 @@ struct wpa_authenticator {
struct wpa_stsl_negotiation *stsl_negotiations;
struct wpa_auth_config conf;
struct wpa_auth_callbacks cb;
const struct wpa_auth_callbacks *cb;
void *cb_ctx;
u8 *wpa_ie;
size_t wpa_ie_len;

@ -408,7 +408,15 @@ static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
const u8 *own_addr, struct wpa_ssid *ssid)
{
struct wpa_auth_config conf;
struct wpa_auth_callbacks cb;
static const struct wpa_auth_callbacks cb = {
.logger = auth_logger,
.set_eapol = auth_set_eapol,
.send_eapol = auth_send_eapol,
.get_psk = auth_get_psk,
.set_key = auth_set_key,
.for_each_sta = auth_for_each_sta,
.disconnect = ibss_rsn_disconnect,
};
wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");
@ -421,17 +429,7 @@ static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
conf.eapol_version = 2;
conf.wpa_group_rekey = ssid->group_rekey ? ssid->group_rekey : 600;
os_memset(&cb, 0, sizeof(cb));
cb.ctx = ibss_rsn;
cb.logger = auth_logger;
cb.set_eapol = auth_set_eapol;
cb.send_eapol = auth_send_eapol;
cb.get_psk = auth_get_psk;
cb.set_key = auth_set_key;
cb.for_each_sta = auth_for_each_sta;
cb.disconnect = ibss_rsn_disconnect;
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb, ibss_rsn);
if (ibss_rsn->auth_group == NULL) {
wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
return -1;

@ -140,7 +140,12 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
enum mfp_options ieee80211w)
{
struct wpa_auth_config conf;
struct wpa_auth_callbacks cb;
static const struct wpa_auth_callbacks cb = {
.logger = auth_logger,
.get_psk = auth_get_psk,
.set_key = auth_set_key,
.start_ampe = auth_start_ampe,
};
u8 seq[6] = {};
wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");
@ -159,14 +164,7 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
conf.group_mgmt_cipher = rsn->mgmt_group_cipher;
#endif /* CONFIG_IEEE80211W */
os_memset(&cb, 0, sizeof(cb));
cb.ctx = rsn;
cb.logger = auth_logger;
cb.get_psk = auth_get_psk;
cb.set_key = auth_set_key;
cb.start_ampe = auth_start_ampe;
rsn->auth = wpa_init(addr, &conf, &cb);
rsn->auth = wpa_init(addr, &conf, &cb, rsn);
if (rsn->auth == NULL) {
wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
return -1;

Loading…
Cancel
Save