diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c index ce925c8f4..7b989ce4f 100644 --- a/wpa_supplicant/wpa_priv.c +++ b/wpa_supplicant/wpa_priv.c @@ -36,10 +36,12 @@ struct wpa_priv_interface { void *drv_priv; void *drv_global_priv; struct sockaddr_un drv_addr; + socklen_t drv_addr_len; int wpas_registered; struct l2_packet_data *l2[WPA_PRIV_MAX_L2]; struct sockaddr_un l2_addr[WPA_PRIV_MAX_L2]; + socklen_t l2_addr_len[WPA_PRIV_MAX_L2]; struct wpa_priv_l2 { struct wpa_priv_interface *parent; int idx; @@ -52,7 +54,7 @@ struct wpa_priv_global { static void wpa_priv_cmd_register(struct wpa_priv_interface *iface, - struct sockaddr_un *from) + struct sockaddr_un *from, socklen_t fromlen) { int i; @@ -104,7 +106,8 @@ static void wpa_priv_cmd_register(struct wpa_priv_interface *iface, wpa_printf(MSG_DEBUG, "Driver wrapper '%s' initialized for interface " "'%s'", iface->driver_name, iface->ifname); - os_memcpy(&iface->drv_addr, from, sizeof(iface->drv_addr)); + os_memcpy(&iface->drv_addr, from, fromlen); + iface->drv_addr_len = fromlen; iface->wpas_registered = 1; if (iface->driver->set_param && @@ -151,7 +154,8 @@ static void wpa_priv_cmd_scan(struct wpa_priv_interface *iface, static void wpa_priv_get_scan_results2(struct wpa_priv_interface *iface, - struct sockaddr_un *from) + struct sockaddr_un *from, + socklen_t fromlen) { struct wpa_scan_results *res; u8 *buf = NULL, *pos, *end; @@ -182,8 +186,7 @@ static void wpa_priv_get_scan_results2(struct wpa_priv_interface *iface, pos += val; } - sendto(iface->fd, buf, pos - buf, 0, (struct sockaddr *) from, - sizeof(*from)); + sendto(iface->fd, buf, pos - buf, 0, (struct sockaddr *) from, fromlen); os_free(buf); wpa_scan_results_free(res); @@ -192,21 +195,21 @@ static void wpa_priv_get_scan_results2(struct wpa_priv_interface *iface, fail: os_free(buf); wpa_scan_results_free(res); - sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); + sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen); } static void wpa_priv_cmd_get_scan_results(struct wpa_priv_interface *iface, - struct sockaddr_un *from) + struct sockaddr_un *from, + socklen_t fromlen) { if (iface->drv_priv == NULL) return; if (iface->driver->get_scan_results2) - wpa_priv_get_scan_results2(iface, from); + wpa_priv_get_scan_results2(iface, from, fromlen); else - sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, - sizeof(*from)); + sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen); } @@ -311,7 +314,7 @@ static void wpa_priv_cmd_associate(struct wpa_priv_interface *iface, static void wpa_priv_cmd_get_bssid(struct wpa_priv_interface *iface, - struct sockaddr_un *from) + struct sockaddr_un *from, socklen_t fromlen) { u8 bssid[ETH_ALEN]; @@ -323,16 +326,16 @@ static void wpa_priv_cmd_get_bssid(struct wpa_priv_interface *iface, goto fail; sendto(iface->fd, bssid, ETH_ALEN, 0, (struct sockaddr *) from, - sizeof(*from)); + fromlen); return; fail: - sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); + sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen); } static void wpa_priv_cmd_get_ssid(struct wpa_priv_interface *iface, - struct sockaddr_un *from) + struct sockaddr_un *from, socklen_t fromlen) { u8 ssid[sizeof(int) + SSID_MAX_LEN]; int res; @@ -349,11 +352,11 @@ static void wpa_priv_cmd_get_ssid(struct wpa_priv_interface *iface, os_memcpy(ssid, &res, sizeof(int)); sendto(iface->fd, ssid, sizeof(ssid), 0, (struct sockaddr *) from, - sizeof(*from)); + fromlen); return; fail: - sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); + sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen); } @@ -386,7 +389,7 @@ static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface, static void wpa_priv_cmd_get_capa(struct wpa_priv_interface *iface, - struct sockaddr_un *from) + struct sockaddr_un *from, socklen_t fromlen) { struct wpa_driver_capa capa; @@ -402,11 +405,11 @@ static void wpa_priv_cmd_get_capa(struct wpa_priv_interface *iface, capa.extended_capa_mask = NULL; capa.extended_capa_len = 0; sendto(iface->fd, &capa, sizeof(capa), 0, (struct sockaddr *) from, - sizeof(*from)); + fromlen); return; fail: - sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); + sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen); } @@ -427,7 +430,7 @@ static void wpa_priv_l2_rx(void *ctx, const u8 *src_addr, const u8 *buf, msg.msg_iov = io; msg.msg_iovlen = 2; msg.msg_name = &iface->l2_addr[l2_ctx->idx]; - msg.msg_namelen = sizeof(iface->l2_addr[l2_ctx->idx]); + msg.msg_namelen = iface->l2_addr_len[l2_ctx->idx]; if (sendmsg(iface->fd, &msg, 0) < 0) { wpa_printf(MSG_ERROR, "sendmsg(l2 rx): %s", strerror(errno)); @@ -444,6 +447,7 @@ static int wpa_priv_allowed_l2_proto(u16 proto) static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface, struct sockaddr_un *from, + socklen_t fromlen, void *buf, size_t len) { int *reg_cmd = buf; @@ -474,7 +478,8 @@ static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface, return; } - os_memcpy(&iface->l2_addr[idx], from, sizeof(iface->l2_addr[idx])); + os_memcpy(&iface->l2_addr[idx], from, fromlen); + iface->l2_addr_len[idx] = fromlen; iface->l2_ctx[idx].idx = idx; iface->l2_ctx[idx].parent = iface; @@ -496,19 +501,20 @@ static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface, } res = sendto(iface->fd, own_addr, ETH_ALEN, 0, - (struct sockaddr *) from, sizeof(*from)); + (struct sockaddr *) from, fromlen); wpa_printf(MSG_DEBUG, "L2 registration[idx=%d]: res=%d", idx, res); } static void wpa_priv_cmd_l2_unregister(struct wpa_priv_interface *iface, - struct sockaddr_un *from) + struct sockaddr_un *from, + socklen_t fromlen) { int idx; for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) { - if (os_memcmp(&iface->l2_addr[idx], from, - sizeof(struct sockaddr_un)) == 0) + if (iface->l2_addr_len[idx] == fromlen && + os_memcmp(&iface->l2_addr[idx], from, fromlen) == 0) break; } if (idx == WPA_PRIV_MAX_L2) { @@ -537,7 +543,7 @@ static void wpa_priv_cmd_l2_notify_auth_start(struct wpa_priv_interface *iface, static void wpa_priv_cmd_l2_send(struct wpa_priv_interface *iface, - struct sockaddr_un *from, + struct sockaddr_un *from, socklen_t fromlen, void *buf, size_t len) { u8 *dst_addr; @@ -546,8 +552,8 @@ static void wpa_priv_cmd_l2_send(struct wpa_priv_interface *iface, int idx; for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) { - if (os_memcmp(&iface->l2_addr[idx], from, - sizeof(struct sockaddr_un)) == 0) + if (iface->l2_addr_len[idx] == fromlen && + os_memcmp(&iface->l2_addr[idx], from, fromlen) == 0) break; } if (idx == WPA_PRIV_MAX_L2) { @@ -621,7 +627,7 @@ static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx) switch (cmd) { case PRIVSEP_CMD_REGISTER: - wpa_priv_cmd_register(iface, &from); + wpa_priv_cmd_register(iface, &from, fromlen); break; case PRIVSEP_CMD_UNREGISTER: wpa_priv_cmd_unregister(iface, &from); @@ -630,34 +636,35 @@ static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx) wpa_priv_cmd_scan(iface, cmd_buf, cmd_len); break; case PRIVSEP_CMD_GET_SCAN_RESULTS: - wpa_priv_cmd_get_scan_results(iface, &from); + wpa_priv_cmd_get_scan_results(iface, &from, fromlen); break; case PRIVSEP_CMD_ASSOCIATE: wpa_priv_cmd_associate(iface, cmd_buf, cmd_len); break; case PRIVSEP_CMD_GET_BSSID: - wpa_priv_cmd_get_bssid(iface, &from); + wpa_priv_cmd_get_bssid(iface, &from, fromlen); break; case PRIVSEP_CMD_GET_SSID: - wpa_priv_cmd_get_ssid(iface, &from); + wpa_priv_cmd_get_ssid(iface, &from, fromlen); break; case PRIVSEP_CMD_SET_KEY: wpa_priv_cmd_set_key(iface, cmd_buf, cmd_len); break; case PRIVSEP_CMD_GET_CAPA: - wpa_priv_cmd_get_capa(iface, &from); + wpa_priv_cmd_get_capa(iface, &from, fromlen); break; case PRIVSEP_CMD_L2_REGISTER: - wpa_priv_cmd_l2_register(iface, &from, cmd_buf, cmd_len); + wpa_priv_cmd_l2_register(iface, &from, fromlen, + cmd_buf, cmd_len); break; case PRIVSEP_CMD_L2_UNREGISTER: - wpa_priv_cmd_l2_unregister(iface, &from); + wpa_priv_cmd_l2_unregister(iface, &from, fromlen); break; case PRIVSEP_CMD_L2_NOTIFY_AUTH_START: wpa_priv_cmd_l2_notify_auth_start(iface, &from); break; case PRIVSEP_CMD_L2_SEND: - wpa_priv_cmd_l2_send(iface, &from, cmd_buf, cmd_len); + wpa_priv_cmd_l2_send(iface, &from, fromlen, cmd_buf, cmd_len); break; case PRIVSEP_CMD_SET_COUNTRY: pos = cmd_buf; @@ -831,7 +838,7 @@ static int wpa_priv_send_event(struct wpa_priv_interface *iface, int event, msg.msg_iov = io; msg.msg_iovlen = data ? 2 : 1; msg.msg_name = &iface->drv_addr; - msg.msg_namelen = sizeof(iface->drv_addr); + msg.msg_namelen = iface->drv_addr_len; if (sendmsg(iface->fd, &msg, 0) < 0) { wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s", @@ -1115,7 +1122,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, msg.msg_iov = io; msg.msg_iovlen = 3; msg.msg_name = &iface->drv_addr; - msg.msg_namelen = sizeof(iface->drv_addr); + msg.msg_namelen = iface->drv_addr_len; if (sendmsg(iface->fd, &msg, 0) < 0) wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s",