aboutsummaryrefslogtreecommitdiff
path: root/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/wpa/wpa_supplicant/ctrl_iface_unix.c')
-rw-r--r--contrib/wpa/wpa_supplicant/ctrl_iface_unix.c73
1 files changed, 67 insertions, 6 deletions
diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c b/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c
index 71fe7ed6bef5..639573dae75e 100644
--- a/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c
+++ b/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / UNIX domain socket -based control interface
- * Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2020, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -131,7 +131,7 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct ctrl_iface_priv *priv = sock_ctx;
- char buf[4096];
+ char *buf;
int res;
struct sockaddr_storage from;
socklen_t fromlen = sizeof(from);
@@ -139,11 +139,20 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
size_t reply_len = 0;
int new_attached = 0;
- res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
+ buf = os_malloc(CTRL_IFACE_MAX_LEN + 1);
+ if (!buf)
+ return;
+ res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN + 1, 0,
(struct sockaddr *) &from, &fromlen);
if (res < 0) {
wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
strerror(errno));
+ os_free(buf);
+ return;
+ }
+ if ((size_t) res > CTRL_IFACE_MAX_LEN) {
+ wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
+ os_free(buf);
return;
}
buf[res] = '\0';
@@ -221,6 +230,7 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
}
}
os_free(reply_buf);
+ os_free(buf);
if (new_attached)
eapol_sm_notify_ctrl_attached(wpa_s->eapol);
@@ -790,12 +800,52 @@ static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
}
-void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
+static void
+wpas_global_ctrl_iface_flush_queued_msg(struct wpa_global *global,
+ struct wpa_supplicant *wpa_s)
+{
+ struct ctrl_iface_global_priv *gpriv;
+ struct ctrl_iface_msg *msg, *prev_msg;
+ unsigned int count = 0;
+
+ if (!global || !global->ctrl_iface)
+ return;
+
+ gpriv = global->ctrl_iface;
+ dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue,
+ struct ctrl_iface_msg, list) {
+ if (msg->wpa_s == wpa_s) {
+ count++;
+ dl_list_del(&msg->list);
+ os_free(msg);
+ }
+ }
+
+ if (count) {
+ wpa_printf(MSG_DEBUG,
+ "CTRL: Dropped %u pending message(s) for interface that is being removed",
+ count);
+ }
+}
+
+
+void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
+ struct ctrl_iface_priv *priv)
{
struct wpa_ctrl_dst *dst, *prev;
struct ctrl_iface_msg *msg, *prev_msg;
struct ctrl_iface_global_priv *gpriv;
+ if (!priv) {
+ /* Control interface has not yet been initialized, so there is
+ * nothing to deinitialize here. However, there might be a
+ * pending message for this interface, so get rid of any such
+ * entry before completing interface removal. */
+ wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s);
+ eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL);
+ return;
+ }
+
if (priv->sock > -1) {
char *fname;
char *buf, *dir = NULL;
@@ -867,6 +917,7 @@ free_dst:
}
}
}
+ wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s);
eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, priv->wpa_s, NULL);
os_free(priv);
}
@@ -1046,18 +1097,27 @@ static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
{
struct wpa_global *global = eloop_ctx;
struct ctrl_iface_global_priv *priv = sock_ctx;
- char buf[4096];
+ char *buf;
int res;
struct sockaddr_storage from;
socklen_t fromlen = sizeof(from);
char *reply = NULL, *reply_buf = NULL;
size_t reply_len;
- res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
+ buf = os_malloc(CTRL_IFACE_MAX_LEN + 1);
+ if (!buf)
+ return;
+ res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN + 1, 0,
(struct sockaddr *) &from, &fromlen);
if (res < 0) {
wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
strerror(errno));
+ os_free(buf);
+ return;
+ }
+ if ((size_t) res > CTRL_IFACE_MAX_LEN) {
+ wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
+ os_free(buf);
return;
}
buf[res] = '\0';
@@ -1105,6 +1165,7 @@ static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
}
}
os_free(reply_buf);
+ os_free(buf);
}