[PATCH] wpa_auth: make struct wpa_auth_callbacks const
Johannes Berg
johannes at sipsolutions.net
Thu Jan 26 07:24:06 PST 2017
From: Johannes Berg <johannes.berg at intel.com>
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 at intel.com>
---
src/ap/wpa_auth.c | 74 ++++++++++++++++++++++++-----------------------
src/ap/wpa_auth.h | 4 +--
src/ap/wpa_auth_ft.c | 38 ++++++++++++------------
src/ap/wpa_auth_glue.c | 45 ++++++++++++++--------------
src/ap/wpa_auth_i.h | 3 +-
wpa_supplicant/ibss_rsn.c | 22 +++++++-------
wpa_supplicant/mesh_rsn.c | 16 +++++-----
7 files changed, 100 insertions(+), 102 deletions(-)
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 4d4b23748120..69e3a5ded1b3 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -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;
}
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index f383ab0a0adc..a44b030b7902 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -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,
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 7ab371f90733..1fe3c2b4c49a 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -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);
}
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index aabac36376db..22518a1f1303 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -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;
diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
index 0c5a457aba25..065a624ad4f5 100644
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -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;
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index c29d8d3e37f5..521a692ba24a 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -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;
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index 065fa0814134..33040f30baa8 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -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;
--
2.9.3
More information about the Hostap
mailing list