From 603100a10904ad69e81e9d422dee470f8dacf23c Mon Sep 17 00:00:00 2001 From: sam Date: Sat, 3 Sep 2005 17:45:54 +0000 Subject: [PATCH] MFC 1.8: correct alignment of addresses passed to ether_ntoa to fix segfaults on amd64 Approved by: re (scottl) --- usr.sbin/wpa/wpa_supplicant/driver_freebsd.c | 82 ++++++++++++++++---- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c index 65cf0f385cf6..e69dcd5544a6 100644 --- a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c +++ b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -41,6 +42,9 @@ struct wpa_driver_bsd_data { char ifname[IFNAMSIZ+1]; /* interface name */ unsigned int ifindex; /* interface index */ void *ctx; + int prev_roaming; /* roaming state to restore on deinit */ + int prev_privacy; /* privacy state to restore on deinit */ + int prev_wpa; /* wpa state to restore on deinit */ }; static int @@ -99,6 +103,24 @@ set80211param(struct wpa_driver_bsd_data *drv, int op, int arg) return 0; } +static int +get80211param(struct wpa_driver_bsd_data *drv, int op) +{ + struct ieee80211req ireq; + + memset(&ireq, 0, sizeof(ireq)); + strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); + ireq.i_type = op; + + if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { + perror("ioctl[SIOCG80211]"); + fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n", + op, strerror(errno)); + return -1; + } + return ireq.i_val; +} + static int getifflags(struct wpa_driver_bsd_data *drv, int *flags) { @@ -175,23 +197,32 @@ wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv, } static int -wpa_driver_bsd_set_wpa(void *priv, int enabled) +wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy) { struct wpa_driver_bsd_data *drv = priv; int ret = 0; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); + wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d", + __FUNCTION__, wpa, privacy); - if (!enabled && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0) + if (!wpa && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0) ret = -1; - if (set80211param(drv, IEEE80211_IOC_PRIVACY, enabled) < 0) + if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) ret = -1; - if (set80211param(drv, IEEE80211_IOC_WPA, enabled ? 3 : 0) < 0) + if (set80211param(drv, IEEE80211_IOC_WPA, wpa) < 0) ret = -1; return ret; } +static int +wpa_driver_bsd_set_wpa(void *priv, int enabled) +{ + wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); + + return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled); +} + static int wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx, const unsigned char *addr) @@ -201,8 +232,11 @@ wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx, memset(&wk, 0, sizeof(wk)); if (addr != NULL && bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) != 0) { + struct ether_addr ea; + + memcpy(&ea, addr, IEEE80211_ADDR_LEN); wpa_printf(MSG_DEBUG, "%s: addr=%s keyidx=%d", - __func__, ether_ntoa(addr), key_idx); + __func__, ether_ntoa(&ea), key_idx); memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); wk.idk_keyix = (uint8_t) IEEE80211_KEYIX_NONE; } else { @@ -220,6 +254,7 @@ wpa_driver_bsd_set_key(void *priv, wpa_alg alg, { struct wpa_driver_bsd_data *drv = priv; struct ieee80211req_key wk; + struct ether_addr ea; char *alg_name; u_int8_t cipher; @@ -245,18 +280,19 @@ wpa_driver_bsd_set_key(void *priv, wpa_alg alg, return -1; } + memcpy(&ea, addr, IEEE80211_ADDR_LEN); wpa_printf(MSG_DEBUG, - "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%d key_len=%d", - __func__, alg_name, ether_ntoa(addr), key_idx, set_tx, + "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu", + __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx, seq_len, key_len); if (seq_len > sizeof(u_int64_t)) { - wpa_printf(MSG_DEBUG, "%s: seq_len %d too big", + wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big", __func__, seq_len); return -2; } if (key_len > sizeof(wk.ik_keydata)) { - wpa_printf(MSG_DEBUG, "%s: key length %d too big", + wpa_printf(MSG_DEBUG, "%s: key length %zu too big", __func__, key_len); return -3; } @@ -644,6 +680,8 @@ wpa_driver_bsd_get_scan_results(void *priv, static void * wpa_driver_bsd_init(void *ctx, const char *ifname) { +#define GETPARAM(drv, param, v) \ + (((v) = get80211param(drv, param)) != -1) struct wpa_driver_bsd_data *drv; drv = malloc(sizeof(*drv)); @@ -674,6 +712,21 @@ wpa_driver_bsd_init(void *ctx, const char *ifname) drv->ctx = ctx; strncpy(drv->ifname, ifname, sizeof(drv->ifname)); + if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) { + wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s", + __func__, strerror(errno)); + goto fail; + } + if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) { + wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s", + __func__, strerror(errno)); + goto fail; + } + if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) { + wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s", + __func__, strerror(errno)); + goto fail; + } if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) { wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based " "roaming: %s", __func__, strerror(errno)); @@ -692,6 +745,7 @@ wpa_driver_bsd_init(void *ctx, const char *ifname) fail1: free(drv); return NULL; +#undef GETPARAM } static void @@ -704,10 +758,10 @@ wpa_driver_bsd_deinit(void *priv) if (getifflags(drv, &flags) == 0) (void) setifflags(drv, flags &~ IFF_UP); - wpa_driver_bsd_set_wpa(drv, 0); - if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_DEVICE) < 0) - wpa_printf(MSG_DEBUG, "%s: failed to enable driver-based " - "roaming", __func__); + wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); + if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) + wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state", + __func__); (void) close(drv->route); /* ioctl socket */ (void) close(drv->sock); /* event socket */