mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-28 18:28:23 -05:00
wpa_priv: Use fromlen instead sizeof(struct sockaddr_un)
This gets rid of some dependencies on how extra octets at the end of the struct sockaddr_un get "uninitialized" consistently by only using the exact length of the address data from the recvfrom() call. This resolves number of valgrind warnings about use of uninitialized memory. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
128d3c69fc
commit
e0641772a3
@ -36,10 +36,12 @@ struct wpa_priv_interface {
|
|||||||
void *drv_priv;
|
void *drv_priv;
|
||||||
void *drv_global_priv;
|
void *drv_global_priv;
|
||||||
struct sockaddr_un drv_addr;
|
struct sockaddr_un drv_addr;
|
||||||
|
socklen_t drv_addr_len;
|
||||||
int wpas_registered;
|
int wpas_registered;
|
||||||
|
|
||||||
struct l2_packet_data *l2[WPA_PRIV_MAX_L2];
|
struct l2_packet_data *l2[WPA_PRIV_MAX_L2];
|
||||||
struct sockaddr_un l2_addr[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_l2 {
|
||||||
struct wpa_priv_interface *parent;
|
struct wpa_priv_interface *parent;
|
||||||
int idx;
|
int idx;
|
||||||
@ -52,7 +54,7 @@ struct wpa_priv_global {
|
|||||||
|
|
||||||
|
|
||||||
static void wpa_priv_cmd_register(struct wpa_priv_interface *iface,
|
static void wpa_priv_cmd_register(struct wpa_priv_interface *iface,
|
||||||
struct sockaddr_un *from)
|
struct sockaddr_un *from, socklen_t fromlen)
|
||||||
{
|
{
|
||||||
int i;
|
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 "
|
wpa_printf(MSG_DEBUG, "Driver wrapper '%s' initialized for interface "
|
||||||
"'%s'", iface->driver_name, iface->ifname);
|
"'%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;
|
iface->wpas_registered = 1;
|
||||||
|
|
||||||
if (iface->driver->set_param &&
|
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,
|
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;
|
struct wpa_scan_results *res;
|
||||||
u8 *buf = NULL, *pos, *end;
|
u8 *buf = NULL, *pos, *end;
|
||||||
@ -182,8 +186,7 @@ static void wpa_priv_get_scan_results2(struct wpa_priv_interface *iface,
|
|||||||
pos += val;
|
pos += val;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto(iface->fd, buf, pos - buf, 0, (struct sockaddr *) from,
|
sendto(iface->fd, buf, pos - buf, 0, (struct sockaddr *) from, fromlen);
|
||||||
sizeof(*from));
|
|
||||||
|
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
wpa_scan_results_free(res);
|
wpa_scan_results_free(res);
|
||||||
@ -192,21 +195,21 @@ static void wpa_priv_get_scan_results2(struct wpa_priv_interface *iface,
|
|||||||
fail:
|
fail:
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
wpa_scan_results_free(res);
|
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,
|
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)
|
if (iface->drv_priv == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (iface->driver->get_scan_results2)
|
if (iface->driver->get_scan_results2)
|
||||||
wpa_priv_get_scan_results2(iface, from);
|
wpa_priv_get_scan_results2(iface, from, fromlen);
|
||||||
else
|
else
|
||||||
sendto(iface->fd, "", 0, 0, (struct sockaddr *) from,
|
sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen);
|
||||||
sizeof(*from));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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,
|
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];
|
u8 bssid[ETH_ALEN];
|
||||||
|
|
||||||
@ -323,16 +326,16 @@ static void wpa_priv_cmd_get_bssid(struct wpa_priv_interface *iface,
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
sendto(iface->fd, bssid, ETH_ALEN, 0, (struct sockaddr *) from,
|
sendto(iface->fd, bssid, ETH_ALEN, 0, (struct sockaddr *) from,
|
||||||
sizeof(*from));
|
fromlen);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
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,
|
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];
|
u8 ssid[sizeof(int) + SSID_MAX_LEN];
|
||||||
int res;
|
int res;
|
||||||
@ -349,11 +352,11 @@ static void wpa_priv_cmd_get_ssid(struct wpa_priv_interface *iface,
|
|||||||
os_memcpy(ssid, &res, sizeof(int));
|
os_memcpy(ssid, &res, sizeof(int));
|
||||||
|
|
||||||
sendto(iface->fd, ssid, sizeof(ssid), 0, (struct sockaddr *) from,
|
sendto(iface->fd, ssid, sizeof(ssid), 0, (struct sockaddr *) from,
|
||||||
sizeof(*from));
|
fromlen);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
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,
|
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;
|
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_mask = NULL;
|
||||||
capa.extended_capa_len = 0;
|
capa.extended_capa_len = 0;
|
||||||
sendto(iface->fd, &capa, sizeof(capa), 0, (struct sockaddr *) from,
|
sendto(iface->fd, &capa, sizeof(capa), 0, (struct sockaddr *) from,
|
||||||
sizeof(*from));
|
fromlen);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
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_iov = io;
|
||||||
msg.msg_iovlen = 2;
|
msg.msg_iovlen = 2;
|
||||||
msg.msg_name = &iface->l2_addr[l2_ctx->idx];
|
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) {
|
if (sendmsg(iface->fd, &msg, 0) < 0) {
|
||||||
wpa_printf(MSG_ERROR, "sendmsg(l2 rx): %s", strerror(errno));
|
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,
|
static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface,
|
||||||
struct sockaddr_un *from,
|
struct sockaddr_un *from,
|
||||||
|
socklen_t fromlen,
|
||||||
void *buf, size_t len)
|
void *buf, size_t len)
|
||||||
{
|
{
|
||||||
int *reg_cmd = buf;
|
int *reg_cmd = buf;
|
||||||
@ -474,7 +478,8 @@ static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface,
|
|||||||
return;
|
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].idx = idx;
|
||||||
iface->l2_ctx[idx].parent = iface;
|
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,
|
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);
|
wpa_printf(MSG_DEBUG, "L2 registration[idx=%d]: res=%d", idx, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpa_priv_cmd_l2_unregister(struct wpa_priv_interface *iface,
|
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;
|
int idx;
|
||||||
|
|
||||||
for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) {
|
for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) {
|
||||||
if (os_memcmp(&iface->l2_addr[idx], from,
|
if (iface->l2_addr_len[idx] == fromlen &&
|
||||||
sizeof(struct sockaddr_un)) == 0)
|
os_memcmp(&iface->l2_addr[idx], from, fromlen) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (idx == WPA_PRIV_MAX_L2) {
|
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,
|
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)
|
void *buf, size_t len)
|
||||||
{
|
{
|
||||||
u8 *dst_addr;
|
u8 *dst_addr;
|
||||||
@ -546,8 +552,8 @@ static void wpa_priv_cmd_l2_send(struct wpa_priv_interface *iface,
|
|||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) {
|
for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) {
|
||||||
if (os_memcmp(&iface->l2_addr[idx], from,
|
if (iface->l2_addr_len[idx] == fromlen &&
|
||||||
sizeof(struct sockaddr_un)) == 0)
|
os_memcmp(&iface->l2_addr[idx], from, fromlen) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (idx == WPA_PRIV_MAX_L2) {
|
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) {
|
switch (cmd) {
|
||||||
case PRIVSEP_CMD_REGISTER:
|
case PRIVSEP_CMD_REGISTER:
|
||||||
wpa_priv_cmd_register(iface, &from);
|
wpa_priv_cmd_register(iface, &from, fromlen);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_UNREGISTER:
|
case PRIVSEP_CMD_UNREGISTER:
|
||||||
wpa_priv_cmd_unregister(iface, &from);
|
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);
|
wpa_priv_cmd_scan(iface, cmd_buf, cmd_len);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_GET_SCAN_RESULTS:
|
case PRIVSEP_CMD_GET_SCAN_RESULTS:
|
||||||
wpa_priv_cmd_get_scan_results(iface, &from);
|
wpa_priv_cmd_get_scan_results(iface, &from, fromlen);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_ASSOCIATE:
|
case PRIVSEP_CMD_ASSOCIATE:
|
||||||
wpa_priv_cmd_associate(iface, cmd_buf, cmd_len);
|
wpa_priv_cmd_associate(iface, cmd_buf, cmd_len);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_GET_BSSID:
|
case PRIVSEP_CMD_GET_BSSID:
|
||||||
wpa_priv_cmd_get_bssid(iface, &from);
|
wpa_priv_cmd_get_bssid(iface, &from, fromlen);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_GET_SSID:
|
case PRIVSEP_CMD_GET_SSID:
|
||||||
wpa_priv_cmd_get_ssid(iface, &from);
|
wpa_priv_cmd_get_ssid(iface, &from, fromlen);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_SET_KEY:
|
case PRIVSEP_CMD_SET_KEY:
|
||||||
wpa_priv_cmd_set_key(iface, cmd_buf, cmd_len);
|
wpa_priv_cmd_set_key(iface, cmd_buf, cmd_len);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_GET_CAPA:
|
case PRIVSEP_CMD_GET_CAPA:
|
||||||
wpa_priv_cmd_get_capa(iface, &from);
|
wpa_priv_cmd_get_capa(iface, &from, fromlen);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_L2_REGISTER:
|
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;
|
break;
|
||||||
case PRIVSEP_CMD_L2_UNREGISTER:
|
case PRIVSEP_CMD_L2_UNREGISTER:
|
||||||
wpa_priv_cmd_l2_unregister(iface, &from);
|
wpa_priv_cmd_l2_unregister(iface, &from, fromlen);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_L2_NOTIFY_AUTH_START:
|
case PRIVSEP_CMD_L2_NOTIFY_AUTH_START:
|
||||||
wpa_priv_cmd_l2_notify_auth_start(iface, &from);
|
wpa_priv_cmd_l2_notify_auth_start(iface, &from);
|
||||||
break;
|
break;
|
||||||
case PRIVSEP_CMD_L2_SEND:
|
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;
|
break;
|
||||||
case PRIVSEP_CMD_SET_COUNTRY:
|
case PRIVSEP_CMD_SET_COUNTRY:
|
||||||
pos = cmd_buf;
|
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_iov = io;
|
||||||
msg.msg_iovlen = data ? 2 : 1;
|
msg.msg_iovlen = data ? 2 : 1;
|
||||||
msg.msg_name = &iface->drv_addr;
|
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) {
|
if (sendmsg(iface->fd, &msg, 0) < 0) {
|
||||||
wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s",
|
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_iov = io;
|
||||||
msg.msg_iovlen = 3;
|
msg.msg_iovlen = 3;
|
||||||
msg.msg_name = &iface->drv_addr;
|
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)
|
if (sendmsg(iface->fd, &msg, 0) < 0)
|
||||||
wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s",
|
wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s",
|
||||||
|
Loading…
Reference in New Issue
Block a user