/*
* WPA Supplicant / UDP socket -based control interface
- * Copyright (c) 2004-2016, 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.
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct ctrl_iface_priv *priv = sock_ctx;
- char buf[4096], *pos;
+ char *buf, *pos;
int res;
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
struct sockaddr_in6 from;
int new_attached = 0;
u8 cookie[COOKIE_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, 0,
(struct sockaddr *) &from, &fromlen);
if (res < 0) {
wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
strerror(errno));
+ os_free(buf);
return;
}
if (os_strcmp(addr, "::1")) {
wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected source %s",
addr);
+ os_free(buf);
+ return;
}
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) {
*/
wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected "
"source %s", inet_ntoa(from.sin_addr));
+ os_free(buf);
return;
}
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
+ if ((size_t) res > CTRL_IFACE_MAX_LEN) {
+ wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
+ os_free(buf);
+ return;
+ }
buf[res] = '\0';
if (os_strcmp(buf, "GET_COOKIE") == 0) {
if (os_strncmp(buf, "COOKIE=", 7) != 0) {
wpa_printf(MSG_DEBUG, "CTLR: No cookie in the request - "
"drop request");
+ os_free(buf);
return;
}
if (hexstr2bin(buf + 7, cookie, COOKIE_LEN) < 0) {
wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie format in the "
"request - drop request");
+ os_free(buf);
return;
}
if (os_memcmp(cookie, priv->cookie, COOKIE_LEN) != 0) {
wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie in the request - "
"drop request");
+ os_free(buf);
return;
}
fromlen);
}
+ os_free(buf);
+
if (new_attached)
eapol_sm_notify_ctrl_attached(wpa_s->eapol);
}
{
struct wpa_global *global = eloop_ctx;
struct ctrl_iface_global_priv *priv = sock_ctx;
- char buf[4096], *pos;
+ char *buf, *pos;
int res;
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
struct sockaddr_in6 from;
+#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
+ char addr[INET6_ADDRSTRLEN];
+#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
struct sockaddr_in from;
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
size_t reply_len;
u8 cookie[COOKIE_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, 0,
(struct sockaddr *) &from, &fromlen);
if (res < 0) {
wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
strerror(errno));
+ os_free(buf);
return;
}
#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
-#ifndef CONFIG_CTRL_IFACE_UDP_IPV6
+#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
+ inet_ntop(AF_INET6, &from.sin6_addr, addr, sizeof(from));
+ if (os_strcmp(addr, "::1")) {
+ wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected source %s",
+ addr);
+ os_free(buf);
+ return;
+ }
+#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) {
/*
* The OS networking stack is expected to drop this kind of
*/
wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected "
"source %s", inet_ntoa(from.sin_addr));
+ os_free(buf);
return;
}
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
+ if ((size_t) res > CTRL_IFACE_MAX_LEN) {
+ wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
+ os_free(buf);
+ return;
+ }
buf[res] = '\0';
if (os_strcmp(buf, "GET_COOKIE") == 0) {
if (os_strncmp(buf, "COOKIE=", 7) != 0) {
wpa_printf(MSG_DEBUG, "CTLR: No cookie in the request - "
"drop request");
+ os_free(buf);
return;
}
if (hexstr2bin(buf + 7, cookie, COOKIE_LEN) < 0) {
wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie format in the "
"request - drop request");
+ os_free(buf);
return;
}
if (os_memcmp(cookie, priv->cookie, COOKIE_LEN) != 0) {
wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie in the request - "
"drop request");
+ os_free(buf);
return;
}
sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from,
fromlen);
}
+
+ os_free(buf);
}
/*
* 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.
{
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);
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, 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';
}
}
os_free(reply_buf);
+ os_free(buf);
if (new_attached)
eapol_sm_notify_ctrl_attached(wpa_s->eapol);
{
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, 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';
}
}
os_free(reply_buf);
+ os_free(buf);
}