1/* 2 * WPA Supplicant / UNIX domain socket -based control interface 3 * Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "includes.h" 10#include <sys/un.h> 11#include <sys/stat.h> 12#include <grp.h> 13#include <stddef.h> 14#include <unistd.h> 15#include <fcntl.h> 16#ifdef __linux__ 17#include <sys/ioctl.h> 18#endif /* __linux__ */ 19#ifdef ANDROID 20#include <cutils/sockets.h> 21#endif /* ANDROID */ 22 23#include "utils/common.h" 24#include "utils/eloop.h" 25#include "utils/list.h" 26#include "common/ctrl_iface_common.h" 27#include "eapol_supp/eapol_supp_sm.h" 28#include "config.h" 29#include "wpa_supplicant_i.h" 30#include "ctrl_iface.h" 31 32/* Per-interface ctrl_iface */ 33 34struct ctrl_iface_priv { 35 struct wpa_supplicant *wpa_s; 36 int sock; 37 struct dl_list ctrl_dst; 38 int android_control_socket; 39 struct dl_list msg_queue; 40 unsigned int throttle_count; 41}; 42 43 44struct ctrl_iface_global_priv { 45 struct wpa_global *global; 46 int sock; 47 struct dl_list ctrl_dst; 48 int android_control_socket; 49 struct dl_list msg_queue; 50 unsigned int throttle_count; 51}; 52 53struct ctrl_iface_msg { 54 struct dl_list list; 55 struct wpa_supplicant *wpa_s; 56 int level; 57 enum wpa_msg_type type; 58 const char *txt; 59 size_t len; 60}; 61 62 63static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s, 64 const char *ifname, int sock, 65 struct dl_list *ctrl_dst, 66 int level, const char *buf, 67 size_t len, 68 struct ctrl_iface_priv *priv, 69 struct ctrl_iface_global_priv *gp); 70static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s, 71 struct ctrl_iface_priv *priv); 72static int wpas_ctrl_iface_global_reinit(struct wpa_global *global, 73 struct ctrl_iface_global_priv *priv); 74 75 76static void wpas_ctrl_sock_debug(const char *title, int sock, const char *buf, 77 size_t len) 78{ 79#ifdef __linux__ 80 socklen_t optlen; 81 int sndbuf, outq; 82 int level = MSG_MSGDUMP; 83 84 if (len >= 5 && os_strncmp(buf, "PONG\n", 5) == 0) 85 level = MSG_EXCESSIVE; 86 87 optlen = sizeof(sndbuf); 88 sndbuf = 0; 89 if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &optlen) < 0) 90 sndbuf = -1; 91 92 if (ioctl(sock, TIOCOUTQ, &outq) < 0) 93 outq = -1; 94 95 wpa_printf(level, 96 "CTRL-DEBUG: %s: sock=%d sndbuf=%d outq=%d send_len=%d", 97 title, sock, sndbuf, outq, (int) len); 98#endif /* __linux__ */ 99} 100 101 102static int wpa_supplicant_ctrl_iface_attach(struct dl_list *ctrl_dst, 103 struct sockaddr_storage *from, 104 socklen_t fromlen, int global) 105{ 106 return ctrl_iface_attach(ctrl_dst, from, fromlen); 107} 108 109 110static int wpa_supplicant_ctrl_iface_detach(struct dl_list *ctrl_dst, 111 struct sockaddr_storage *from, 112 socklen_t fromlen) 113{ 114 return ctrl_iface_detach(ctrl_dst, from, fromlen); 115} 116 117 118static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv, 119 struct sockaddr_storage *from, 120 socklen_t fromlen, 121 char *level) 122{ 123 wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level); 124 125 return ctrl_iface_level(&priv->ctrl_dst, from, fromlen, level); 126} 127 128 129static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, 130 void *sock_ctx) 131{ 132 struct wpa_supplicant *wpa_s = eloop_ctx; 133 struct ctrl_iface_priv *priv = sock_ctx; 134 char buf[4096]; 135 int res; 136 struct sockaddr_storage from; 137 socklen_t fromlen = sizeof(from); 138 char *reply = NULL, *reply_buf = NULL; 139 size_t reply_len = 0; 140 int new_attached = 0; 141 142 res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 143 (struct sockaddr *) &from, &fromlen); 144 if (res < 0) { 145 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 146 strerror(errno)); 147 return; 148 } 149 buf[res] = '\0'; 150 151 if (os_strcmp(buf, "ATTACH") == 0) { 152 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from, 153 fromlen, 0)) 154 reply_len = 1; 155 else { 156 new_attached = 1; 157 reply_len = 2; 158 } 159 } else if (os_strcmp(buf, "DETACH") == 0) { 160 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from, 161 fromlen)) 162 reply_len = 1; 163 else 164 reply_len = 2; 165 } else if (os_strncmp(buf, "LEVEL ", 6) == 0) { 166 if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen, 167 buf + 6)) 168 reply_len = 1; 169 else 170 reply_len = 2; 171 } else { 172 reply_buf = wpa_supplicant_ctrl_iface_process(wpa_s, buf, 173 &reply_len); 174 reply = reply_buf; 175 176 /* 177 * There could be some password/key material in the command, so 178 * clear the buffer explicitly now that it is not needed 179 * anymore. 180 */ 181 os_memset(buf, 0, res); 182 } 183 184 if (!reply && reply_len == 1) { 185 reply = "FAIL\n"; 186 reply_len = 5; 187 } else if (!reply && reply_len == 2) { 188 reply = "OK\n"; 189 reply_len = 3; 190 } 191 192 if (reply) { 193 wpas_ctrl_sock_debug("ctrl_sock-sendto", sock, reply, 194 reply_len); 195 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 196 fromlen) < 0) { 197 int _errno = errno; 198 wpa_dbg(wpa_s, MSG_DEBUG, 199 "ctrl_iface sendto failed: %d - %s", 200 _errno, strerror(_errno)); 201 if (_errno == ENOBUFS || _errno == EAGAIN) { 202 /* 203 * The socket send buffer could be full. This 204 * may happen if client programs are not 205 * receiving their pending messages. Close and 206 * reopen the socket as a workaround to avoid 207 * getting stuck being unable to send any new 208 * responses. 209 */ 210 sock = wpas_ctrl_iface_reinit(wpa_s, priv); 211 if (sock < 0) { 212 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to reinitialize ctrl_iface socket"); 213 } 214 } 215 if (new_attached) { 216 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to send response to ATTACH - detaching"); 217 new_attached = 0; 218 wpa_supplicant_ctrl_iface_detach( 219 &priv->ctrl_dst, &from, fromlen); 220 } 221 } 222 } 223 os_free(reply_buf); 224 225 if (new_attached) 226 eapol_sm_notify_ctrl_attached(wpa_s->eapol); 227} 228 229 230static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s) 231{ 232 char *buf; 233 size_t len; 234 char *pbuf, *dir = NULL; 235 int res; 236 237 if (wpa_s->conf->ctrl_interface == NULL) 238 return NULL; 239 240 pbuf = os_strdup(wpa_s->conf->ctrl_interface); 241 if (pbuf == NULL) 242 return NULL; 243 if (os_strncmp(pbuf, "DIR=", 4) == 0) { 244 char *gid_str; 245 dir = pbuf + 4; 246 gid_str = os_strstr(dir, " GROUP="); 247 if (gid_str) 248 *gid_str = '\0'; 249 } else 250 dir = pbuf; 251 252 len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2; 253 buf = os_malloc(len); 254 if (buf == NULL) { 255 os_free(pbuf); 256 return NULL; 257 } 258 259 res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname); 260 if (os_snprintf_error(len, res)) { 261 os_free(pbuf); 262 os_free(buf); 263 return NULL; 264 } 265#ifdef __CYGWIN__ 266 { 267 /* Windows/WinPcap uses interface names that are not suitable 268 * as a file name - convert invalid chars to underscores */ 269 char *pos = buf; 270 while (*pos) { 271 if (*pos == '\\') 272 *pos = '_'; 273 pos++; 274 } 275 } 276#endif /* __CYGWIN__ */ 277 os_free(pbuf); 278 return buf; 279} 280 281 282static int wpas_ctrl_iface_throttle(int sock) 283{ 284#ifdef __linux__ 285 socklen_t optlen; 286 int sndbuf, outq; 287 288 optlen = sizeof(sndbuf); 289 sndbuf = 0; 290 if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &optlen) < 0 || 291 ioctl(sock, TIOCOUTQ, &outq) < 0 || 292 sndbuf <= 0 || outq < 0) 293 return 0; 294 return outq > sndbuf / 2; 295#else /* __linux__ */ 296 return 0; 297#endif /* __linux__ */ 298} 299 300 301static void wpas_ctrl_msg_send_pending_global(struct wpa_global *global) 302{ 303 struct ctrl_iface_global_priv *gpriv; 304 struct ctrl_iface_msg *msg; 305 306 gpriv = global->ctrl_iface; 307 while (gpriv && !dl_list_empty(&gpriv->msg_queue) && 308 !wpas_ctrl_iface_throttle(gpriv->sock)) { 309 msg = dl_list_first(&gpriv->msg_queue, struct ctrl_iface_msg, 310 list); 311 if (!msg) 312 break; 313 dl_list_del(&msg->list); 314 wpa_supplicant_ctrl_iface_send( 315 msg->wpa_s, 316 msg->type != WPA_MSG_PER_INTERFACE ? 317 NULL : msg->wpa_s->ifname, 318 gpriv->sock, &gpriv->ctrl_dst, msg->level, 319 msg->txt, msg->len, NULL, gpriv); 320 os_free(msg); 321 } 322} 323 324 325static void wpas_ctrl_msg_send_pending_iface(struct wpa_supplicant *wpa_s) 326{ 327 struct ctrl_iface_priv *priv; 328 struct ctrl_iface_msg *msg; 329 330 priv = wpa_s->ctrl_iface; 331 while (priv && !dl_list_empty(&priv->msg_queue) && 332 !wpas_ctrl_iface_throttle(priv->sock)) { 333 msg = dl_list_first(&priv->msg_queue, struct ctrl_iface_msg, 334 list); 335 if (!msg) 336 break; 337 dl_list_del(&msg->list); 338 wpa_supplicant_ctrl_iface_send(wpa_s, NULL, priv->sock, 339 &priv->ctrl_dst, msg->level, 340 msg->txt, msg->len, priv, NULL); 341 os_free(msg); 342 } 343} 344 345 346static void wpas_ctrl_msg_queue_timeout(void *eloop_ctx, void *timeout_ctx) 347{ 348 struct wpa_supplicant *wpa_s = eloop_ctx; 349 struct ctrl_iface_priv *priv; 350 struct ctrl_iface_global_priv *gpriv; 351 int sock = -1, gsock = -1; 352 353 wpas_ctrl_msg_send_pending_global(wpa_s->global); 354 wpas_ctrl_msg_send_pending_iface(wpa_s); 355 356 priv = wpa_s->ctrl_iface; 357 if (priv && !dl_list_empty(&priv->msg_queue)) 358 sock = priv->sock; 359 360 gpriv = wpa_s->global->ctrl_iface; 361 if (gpriv && !dl_list_empty(&gpriv->msg_queue)) 362 gsock = gpriv->sock; 363 364 if (sock > -1 || gsock > -1) { 365 /* Continue pending message transmission from a timeout */ 366 wpa_printf(MSG_MSGDUMP, 367 "CTRL: Had to throttle pending event message transmission for (sock %d gsock %d)", 368 sock, gsock); 369 eloop_register_timeout(0, 20000, wpas_ctrl_msg_queue_timeout, 370 wpa_s, NULL); 371 } 372} 373 374 375static void wpas_ctrl_msg_queue(struct dl_list *queue, 376 struct wpa_supplicant *wpa_s, int level, 377 enum wpa_msg_type type, 378 const char *txt, size_t len) 379{ 380 struct ctrl_iface_msg *msg; 381 382 msg = os_zalloc(sizeof(*msg) + len); 383 if (!msg) 384 return; 385 386 msg->wpa_s = wpa_s; 387 msg->level = level; 388 msg->type = type; 389 os_memcpy(msg + 1, txt, len); 390 msg->txt = (const char *) (msg + 1); 391 msg->len = len; 392 dl_list_add_tail(queue, &msg->list); 393 eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL); 394 eloop_register_timeout(0, 0, wpas_ctrl_msg_queue_timeout, wpa_s, NULL); 395} 396 397 398static void wpas_ctrl_msg_queue_limit(unsigned int throttle_count, 399 struct dl_list *queue) 400{ 401 struct ctrl_iface_msg *msg; 402 403 if (throttle_count < 2000) 404 return; 405 406 msg = dl_list_first(queue, struct ctrl_iface_msg, list); 407 if (msg) { 408 wpa_printf(MSG_DEBUG, "CTRL: Dropped oldest pending message"); 409 dl_list_del(&msg->list); 410 os_free(msg); 411 } 412} 413 414 415static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, 416 enum wpa_msg_type type, 417 const char *txt, size_t len) 418{ 419 struct wpa_supplicant *wpa_s = ctx; 420 struct ctrl_iface_priv *priv; 421 struct ctrl_iface_global_priv *gpriv; 422 423 if (wpa_s == NULL) 424 return; 425 426 gpriv = wpa_s->global->ctrl_iface; 427 428 if (type != WPA_MSG_NO_GLOBAL && gpriv && 429 !dl_list_empty(&gpriv->ctrl_dst)) { 430 if (!dl_list_empty(&gpriv->msg_queue) || 431 wpas_ctrl_iface_throttle(gpriv->sock)) { 432 if (gpriv->throttle_count == 0) { 433 wpa_printf(MSG_MSGDUMP, 434 "CTRL: Had to throttle global event message for sock %d", 435 gpriv->sock); 436 } 437 gpriv->throttle_count++; 438 wpas_ctrl_msg_queue_limit(gpriv->throttle_count, 439 &gpriv->msg_queue); 440 wpas_ctrl_msg_queue(&gpriv->msg_queue, wpa_s, level, 441 type, txt, len); 442 } else { 443 if (gpriv->throttle_count) { 444 wpa_printf(MSG_MSGDUMP, 445 "CTRL: Had to throttle %u global event message(s) for sock %d", 446 gpriv->throttle_count, gpriv->sock); 447 } 448 gpriv->throttle_count = 0; 449 wpa_supplicant_ctrl_iface_send( 450 wpa_s, 451 type != WPA_MSG_PER_INTERFACE ? 452 NULL : wpa_s->ifname, 453 gpriv->sock, &gpriv->ctrl_dst, level, 454 txt, len, NULL, gpriv); 455 } 456 } 457 458 priv = wpa_s->ctrl_iface; 459 460 if (type != WPA_MSG_ONLY_GLOBAL && priv) { 461 if (!dl_list_empty(&priv->msg_queue) || 462 wpas_ctrl_iface_throttle(priv->sock)) { 463 if (priv->throttle_count == 0) { 464 wpa_printf(MSG_MSGDUMP, 465 "CTRL: Had to throttle event message for sock %d", 466 priv->sock); 467 } 468 priv->throttle_count++; 469 wpas_ctrl_msg_queue_limit(priv->throttle_count, 470 &priv->msg_queue); 471 wpas_ctrl_msg_queue(&priv->msg_queue, wpa_s, level, 472 type, txt, len); 473 } else { 474 if (priv->throttle_count) { 475 wpa_printf(MSG_MSGDUMP, 476 "CTRL: Had to throttle %u event message(s) for sock %d", 477 priv->throttle_count, priv->sock); 478 } 479 priv->throttle_count = 0; 480 wpa_supplicant_ctrl_iface_send(wpa_s, NULL, priv->sock, 481 &priv->ctrl_dst, level, 482 txt, len, priv, NULL); 483 } 484 } 485} 486 487 488static int wpas_ctrl_iface_open_sock(struct wpa_supplicant *wpa_s, 489 struct ctrl_iface_priv *priv) 490{ 491 struct sockaddr_un addr; 492 char *fname = NULL; 493 gid_t gid = 0; 494 int gid_set = 0; 495 char *buf, *dir = NULL, *gid_str = NULL; 496 struct group *grp; 497 char *endp; 498 int flags; 499 500 buf = os_strdup(wpa_s->conf->ctrl_interface); 501 if (buf == NULL) 502 goto fail; 503#ifdef ANDROID 504 os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s", 505 wpa_s->conf->ctrl_interface); 506 priv->sock = android_get_control_socket(addr.sun_path); 507 if (priv->sock >= 0) { 508 priv->android_control_socket = 1; 509 goto havesock; 510 } 511#endif /* ANDROID */ 512 if (os_strncmp(buf, "DIR=", 4) == 0) { 513 dir = buf + 4; 514 gid_str = os_strstr(dir, " GROUP="); 515 if (gid_str) { 516 *gid_str = '\0'; 517 gid_str += 7; 518 } 519 } else { 520 dir = buf; 521 gid_str = wpa_s->conf->ctrl_interface_group; 522 } 523 524 if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) { 525 if (errno == EEXIST) { 526 wpa_printf(MSG_DEBUG, "Using existing control " 527 "interface directory."); 528 } else { 529 wpa_printf(MSG_ERROR, "mkdir[ctrl_interface=%s]: %s", 530 dir, strerror(errno)); 531 goto fail; 532 } 533 } 534 535#ifdef ANDROID 536 /* 537 * wpa_supplicant is started from /init.*.rc on Android and that seems 538 * to be using umask 0077 which would leave the control interface 539 * directory without group access. This breaks things since Wi-Fi 540 * framework assumes that this directory can be accessed by other 541 * applications in the wifi group. Fix this by adding group access even 542 * if umask value would prevent this. 543 */ 544 if (chmod(dir, S_IRWXU | S_IRWXG) < 0) { 545 wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s", 546 strerror(errno)); 547 /* Try to continue anyway */ 548 } 549#endif /* ANDROID */ 550 551 if (gid_str) { 552 grp = getgrnam(gid_str); 553 if (grp) { 554 gid = grp->gr_gid; 555 gid_set = 1; 556 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" 557 " (from group name '%s')", 558 (int) gid, gid_str); 559 } else { 560 /* Group name not found - try to parse this as gid */ 561 gid = strtol(gid_str, &endp, 10); 562 if (*gid_str == '\0' || *endp != '\0') { 563 wpa_printf(MSG_ERROR, "CTRL: Invalid group " 564 "'%s'", gid_str); 565 goto fail; 566 } 567 gid_set = 1; 568 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", 569 (int) gid); 570 } 571 } 572 573 if (gid_set && chown(dir, -1, gid) < 0) { 574 wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s", 575 dir, (int) gid, strerror(errno)); 576 goto fail; 577 } 578 579 /* Make sure the group can enter and read the directory */ 580 if (gid_set && 581 chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) { 582 wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s", 583 strerror(errno)); 584 goto fail; 585 } 586 587 if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >= 588 sizeof(addr.sun_path)) { 589 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded"); 590 goto fail; 591 } 592 593 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 594 if (priv->sock < 0) { 595 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); 596 goto fail; 597 } 598 599 os_memset(&addr, 0, sizeof(addr)); 600#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 601 addr.sun_len = sizeof(addr); 602#endif /* __FreeBSD__ */ 603 addr.sun_family = AF_UNIX; 604 fname = wpa_supplicant_ctrl_iface_path(wpa_s); 605 if (fname == NULL) 606 goto fail; 607 os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path)); 608 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 609 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s", 610 strerror(errno)); 611 if (connect(priv->sock, (struct sockaddr *) &addr, 612 sizeof(addr)) < 0) { 613 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 614 " allow connections - assuming it was left" 615 "over from forced program termination"); 616 if (unlink(fname) < 0) { 617 wpa_printf(MSG_ERROR, 618 "Could not unlink existing ctrl_iface socket '%s': %s", 619 fname, strerror(errno)); 620 goto fail; 621 } 622 if (bind(priv->sock, (struct sockaddr *) &addr, 623 sizeof(addr)) < 0) { 624 wpa_printf(MSG_ERROR, "supp-ctrl-iface-init: bind(PF_UNIX): %s", 625 strerror(errno)); 626 goto fail; 627 } 628 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 629 "ctrl_iface socket '%s'", fname); 630 } else { 631 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 632 "be in use - cannot override it"); 633 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 634 "not used anymore", fname); 635 os_free(fname); 636 fname = NULL; 637 goto fail; 638 } 639 } 640 641 if (gid_set && chown(fname, -1, gid) < 0) { 642 wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s", 643 fname, (int) gid, strerror(errno)); 644 goto fail; 645 } 646 647 if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { 648 wpa_printf(MSG_ERROR, "chmod[ctrl_interface=%s]: %s", 649 fname, strerror(errno)); 650 goto fail; 651 } 652 os_free(fname); 653 654#ifdef ANDROID 655havesock: 656#endif /* ANDROID */ 657 658 /* 659 * Make socket non-blocking so that we don't hang forever if 660 * target dies unexpectedly. 661 */ 662 flags = fcntl(priv->sock, F_GETFL); 663 if (flags >= 0) { 664 flags |= O_NONBLOCK; 665 if (fcntl(priv->sock, F_SETFL, flags) < 0) { 666 wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s", 667 strerror(errno)); 668 /* Not fatal, continue on.*/ 669 } 670 } 671 672 eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive, 673 wpa_s, priv); 674 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); 675 676 os_free(buf); 677 return 0; 678 679fail: 680 if (priv->sock >= 0) { 681 close(priv->sock); 682 priv->sock = -1; 683 } 684 if (fname) { 685 unlink(fname); 686 os_free(fname); 687 } 688 os_free(buf); 689 return -1; 690} 691 692 693struct ctrl_iface_priv * 694wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) 695{ 696 struct ctrl_iface_priv *priv; 697 698 priv = os_zalloc(sizeof(*priv)); 699 if (priv == NULL) 700 return NULL; 701 dl_list_init(&priv->ctrl_dst); 702 dl_list_init(&priv->msg_queue); 703 priv->wpa_s = wpa_s; 704 priv->sock = -1; 705 706 if (wpa_s->conf->ctrl_interface == NULL) 707 return priv; 708 709#ifdef ANDROID 710 if (wpa_s->global->params.ctrl_interface) { 711 int same = 0; 712 713 if (wpa_s->global->params.ctrl_interface[0] == '/') { 714 if (os_strcmp(wpa_s->global->params.ctrl_interface, 715 wpa_s->conf->ctrl_interface) == 0) 716 same = 1; 717 } else if (os_strncmp(wpa_s->global->params.ctrl_interface, 718 "@android:", 9) == 0 || 719 os_strncmp(wpa_s->global->params.ctrl_interface, 720 "@abstract:", 10) == 0) { 721 char *pos; 722 723 /* 724 * Currently, Android uses @android:wpa_* as the naming 725 * convention for the global ctrl interface. This logic 726 * needs to be revisited if the above naming convention 727 * is modified. 728 */ 729 pos = os_strchr(wpa_s->global->params.ctrl_interface, 730 '_'); 731 if (pos && 732 os_strcmp(pos + 1, 733 wpa_s->conf->ctrl_interface) == 0) 734 same = 1; 735 } 736 737 if (same) { 738 /* 739 * The invalid configuration combination might be 740 * possible to hit in an Android OTA upgrade case, so 741 * instead of refusing to start the wpa_supplicant 742 * process, do not open the per-interface ctrl_iface 743 * and continue with the global control interface that 744 * was set from the command line since the Wi-Fi 745 * framework will use it for operations. 746 */ 747 wpa_printf(MSG_ERROR, 748 "global ctrl interface %s matches ctrl interface %s - do not open per-interface ctrl interface", 749 wpa_s->global->params.ctrl_interface, 750 wpa_s->conf->ctrl_interface); 751 return priv; 752 } 753 } 754#endif /* ANDROID */ 755 756 if (wpas_ctrl_iface_open_sock(wpa_s, priv) < 0) { 757 os_free(priv); 758 return NULL; 759 } 760 761 return priv; 762} 763 764 765static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s, 766 struct ctrl_iface_priv *priv) 767{ 768 int res; 769 770 if (priv->sock <= 0) 771 return -1; 772 773 /* 774 * On Android, the control socket being used may be the socket 775 * that is created when wpa_supplicant is started as a /init.*.rc 776 * service. Such a socket is maintained as a key-value pair in 777 * Android's environment. Closing this control socket would leave us 778 * in a bad state with an invalid socket descriptor. 779 */ 780 if (priv->android_control_socket) 781 return priv->sock; 782 783 eloop_unregister_read_sock(priv->sock); 784 close(priv->sock); 785 priv->sock = -1; 786 res = wpas_ctrl_iface_open_sock(wpa_s, priv); 787 if (res < 0) 788 return -1; 789 return priv->sock; 790} 791 792 793void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) 794{ 795 struct wpa_ctrl_dst *dst, *prev; 796 struct ctrl_iface_msg *msg, *prev_msg; 797 struct ctrl_iface_global_priv *gpriv; 798 799 if (priv->sock > -1) { 800 char *fname; 801 char *buf, *dir = NULL; 802 eloop_unregister_read_sock(priv->sock); 803 if (!dl_list_empty(&priv->ctrl_dst)) { 804 /* 805 * Wait before closing the control socket if 806 * there are any attached monitors in order to allow 807 * them to receive any pending messages. 808 */ 809 wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached " 810 "monitors to receive messages"); 811 os_sleep(0, 100000); 812 } 813 close(priv->sock); 814 priv->sock = -1; 815 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s); 816 if (fname) { 817 unlink(fname); 818 os_free(fname); 819 } 820 821 if (priv->wpa_s->conf->ctrl_interface == NULL) 822 goto free_dst; 823 buf = os_strdup(priv->wpa_s->conf->ctrl_interface); 824 if (buf == NULL) 825 goto free_dst; 826 if (os_strncmp(buf, "DIR=", 4) == 0) { 827 char *gid_str; 828 dir = buf + 4; 829 gid_str = os_strstr(dir, " GROUP="); 830 if (gid_str) 831 *gid_str = '\0'; 832 } else 833 dir = buf; 834 835 if (rmdir(dir) < 0) { 836 if (errno == ENOTEMPTY) { 837 wpa_printf(MSG_DEBUG, "Control interface " 838 "directory not empty - leaving it " 839 "behind"); 840 } else { 841 wpa_printf(MSG_ERROR, 842 "rmdir[ctrl_interface=%s]: %s", 843 dir, strerror(errno)); 844 } 845 } 846 os_free(buf); 847 } 848 849free_dst: 850 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst, 851 list) { 852 dl_list_del(&dst->list); 853 os_free(dst); 854 } 855 dl_list_for_each_safe(msg, prev_msg, &priv->msg_queue, 856 struct ctrl_iface_msg, list) { 857 dl_list_del(&msg->list); 858 os_free(msg); 859 } 860 gpriv = priv->wpa_s->global->ctrl_iface; 861 if (gpriv) { 862 dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue, 863 struct ctrl_iface_msg, list) { 864 if (msg->wpa_s == priv->wpa_s) { 865 dl_list_del(&msg->list); 866 os_free(msg); 867 } 868 } 869 } 870 eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, priv->wpa_s, NULL); 871 os_free(priv); 872} 873 874 875/** 876 * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors 877 * @ifname: Interface name for global control socket or %NULL 878 * @sock: Local socket fd 879 * @ctrl_dst: List of attached listeners 880 * @level: Priority level of the message 881 * @buf: Message data 882 * @len: Message length 883 * 884 * Send a packet to all monitor programs attached to the control interface. 885 */ 886static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s, 887 const char *ifname, int sock, 888 struct dl_list *ctrl_dst, 889 int level, const char *buf, 890 size_t len, 891 struct ctrl_iface_priv *priv, 892 struct ctrl_iface_global_priv *gp) 893{ 894 struct wpa_ctrl_dst *dst, *next; 895 char levelstr[10]; 896 int idx, res; 897 struct msghdr msg; 898 struct iovec io[5]; 899 900 if (sock < 0 || dl_list_empty(ctrl_dst)) 901 return; 902 903 res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); 904 if (os_snprintf_error(sizeof(levelstr), res)) 905 return; 906 idx = 0; 907 if (ifname) { 908 io[idx].iov_base = "IFNAME="; 909 io[idx].iov_len = 7; 910 idx++; 911 io[idx].iov_base = (char *) ifname; 912 io[idx].iov_len = os_strlen(ifname); 913 idx++; 914 io[idx].iov_base = " "; 915 io[idx].iov_len = 1; 916 idx++; 917 } 918 io[idx].iov_base = levelstr; 919 io[idx].iov_len = os_strlen(levelstr); 920 idx++; 921 io[idx].iov_base = (char *) buf; 922 io[idx].iov_len = len; 923 idx++; 924 os_memset(&msg, 0, sizeof(msg)); 925 msg.msg_iov = io; 926 msg.msg_iovlen = idx; 927 928 dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) { 929 int _errno; 930 char txt[200]; 931 932 if (level < dst->debug_level) 933 continue; 934 935 msg.msg_name = (void *) &dst->addr; 936 msg.msg_namelen = dst->addrlen; 937 wpas_ctrl_sock_debug("ctrl_sock-sendmsg", sock, buf, len); 938 if (sendmsg(sock, &msg, MSG_DONTWAIT) >= 0) { 939 sockaddr_print(MSG_MSGDUMP, 940 "CTRL_IFACE monitor sent successfully to", 941 &dst->addr, dst->addrlen); 942 dst->errors = 0; 943 continue; 944 } 945 946 _errno = errno; 947 os_snprintf(txt, sizeof(txt), "CTRL_IFACE monitor: %d (%s) for", 948 _errno, strerror(_errno)); 949 sockaddr_print(MSG_DEBUG, txt, &dst->addr, dst->addrlen); 950 dst->errors++; 951 952 if (dst->errors > 10 || _errno == ENOENT || _errno == EPERM) { 953 sockaddr_print(MSG_INFO, "CTRL_IFACE: Detach monitor that cannot receive messages:", 954 &dst->addr, dst->addrlen); 955 wpa_supplicant_ctrl_iface_detach(ctrl_dst, &dst->addr, 956 dst->addrlen); 957 } 958 959 if (_errno == ENOBUFS || _errno == EAGAIN) { 960 /* 961 * The socket send buffer could be full. This may happen 962 * if client programs are not receiving their pending 963 * messages. Close and reopen the socket as a workaround 964 * to avoid getting stuck being unable to send any new 965 * responses. 966 */ 967 if (priv) 968 sock = wpas_ctrl_iface_reinit(wpa_s, priv); 969 else if (gp) 970 sock = wpas_ctrl_iface_global_reinit( 971 wpa_s->global, gp); 972 else 973 break; 974 if (sock < 0) { 975 wpa_dbg(wpa_s, MSG_DEBUG, 976 "Failed to reinitialize ctrl_iface socket"); 977 break; 978 } 979 } 980 } 981} 982 983 984void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv) 985{ 986 char buf[256]; 987 int res; 988 struct sockaddr_storage from; 989 socklen_t fromlen = sizeof(from); 990 991 if (priv->sock == -1) 992 return; 993 994 for (;;) { 995 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to " 996 "attach", priv->wpa_s->ifname); 997 eloop_wait_for_read_sock(priv->sock); 998 999 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0, 1000 (struct sockaddr *) &from, &fromlen); 1001 if (res < 0) { 1002 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 1003 strerror(errno)); 1004 continue; 1005 } 1006 buf[res] = '\0'; 1007 1008 if (os_strcmp(buf, "ATTACH") == 0) { 1009 /* handle ATTACH signal of first monitor interface */ 1010 if (!wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, 1011 &from, fromlen, 1012 0)) { 1013 if (sendto(priv->sock, "OK\n", 3, 0, 1014 (struct sockaddr *) &from, fromlen) < 1015 0) { 1016 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s", 1017 strerror(errno)); 1018 } 1019 /* OK to continue */ 1020 return; 1021 } else { 1022 if (sendto(priv->sock, "FAIL\n", 5, 0, 1023 (struct sockaddr *) &from, fromlen) < 1024 0) { 1025 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s", 1026 strerror(errno)); 1027 } 1028 } 1029 } else { 1030 /* return FAIL for all other signals */ 1031 if (sendto(priv->sock, "FAIL\n", 5, 0, 1032 (struct sockaddr *) &from, fromlen) < 0) { 1033 wpa_printf(MSG_DEBUG, 1034 "ctrl_iface sendto failed: %s", 1035 strerror(errno)); 1036 } 1037 } 1038 } 1039} 1040 1041 1042/* Global ctrl_iface */ 1043 1044static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, 1045 void *sock_ctx) 1046{ 1047 struct wpa_global *global = eloop_ctx; 1048 struct ctrl_iface_global_priv *priv = sock_ctx; 1049 char buf[4096]; 1050 int res; 1051 struct sockaddr_storage from; 1052 socklen_t fromlen = sizeof(from); 1053 char *reply = NULL, *reply_buf = NULL; 1054 size_t reply_len; 1055 1056 res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 1057 (struct sockaddr *) &from, &fromlen); 1058 if (res < 0) { 1059 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 1060 strerror(errno)); 1061 return; 1062 } 1063 buf[res] = '\0'; 1064 1065 if (os_strcmp(buf, "ATTACH") == 0) { 1066 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from, 1067 fromlen, 1)) 1068 reply_len = 1; 1069 else 1070 reply_len = 2; 1071 } else if (os_strcmp(buf, "DETACH") == 0) { 1072 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from, 1073 fromlen)) 1074 reply_len = 1; 1075 else 1076 reply_len = 2; 1077 } else { 1078 reply_buf = wpa_supplicant_global_ctrl_iface_process( 1079 global, buf, &reply_len); 1080 reply = reply_buf; 1081 1082 /* 1083 * There could be some password/key material in the command, so 1084 * clear the buffer explicitly now that it is not needed 1085 * anymore. 1086 */ 1087 os_memset(buf, 0, res); 1088 } 1089 1090 if (!reply && reply_len == 1) { 1091 reply = "FAIL\n"; 1092 reply_len = 5; 1093 } else if (!reply && reply_len == 2) { 1094 reply = "OK\n"; 1095 reply_len = 3; 1096 } 1097 1098 if (reply) { 1099 wpas_ctrl_sock_debug("global_ctrl_sock-sendto", 1100 sock, reply, reply_len); 1101 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 1102 fromlen) < 0) { 1103 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s", 1104 strerror(errno)); 1105 } 1106 } 1107 os_free(reply_buf); 1108} 1109 1110 1111static int wpas_global_ctrl_iface_open_sock(struct wpa_global *global, 1112 struct ctrl_iface_global_priv *priv) 1113{ 1114 struct sockaddr_un addr; 1115 const char *ctrl = global->params.ctrl_interface; 1116 int flags; 1117 1118 wpa_printf(MSG_DEBUG, "Global control interface '%s'", ctrl); 1119 1120#ifdef ANDROID 1121 if (os_strncmp(ctrl, "@android:", 9) == 0) { 1122 priv->sock = android_get_control_socket(ctrl + 9); 1123 if (priv->sock < 0) { 1124 wpa_printf(MSG_ERROR, "Failed to open Android control " 1125 "socket '%s'", ctrl + 9); 1126 goto fail; 1127 } 1128 wpa_printf(MSG_DEBUG, "Using Android control socket '%s'", 1129 ctrl + 9); 1130 priv->android_control_socket = 1; 1131 goto havesock; 1132 } 1133 1134 if (os_strncmp(ctrl, "@abstract:", 10) != 0) { 1135 /* 1136 * Backwards compatibility - try to open an Android control 1137 * socket and if that fails, assume this was a UNIX domain 1138 * socket instead. 1139 */ 1140 priv->sock = android_get_control_socket(ctrl); 1141 if (priv->sock >= 0) { 1142 wpa_printf(MSG_DEBUG, 1143 "Using Android control socket '%s'", 1144 ctrl); 1145 priv->android_control_socket = 1; 1146 goto havesock; 1147 } 1148 } 1149#endif /* ANDROID */ 1150 1151 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 1152 if (priv->sock < 0) { 1153 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); 1154 goto fail; 1155 } 1156 1157 os_memset(&addr, 0, sizeof(addr)); 1158#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1159 addr.sun_len = sizeof(addr); 1160#endif /* __FreeBSD__ */ 1161 addr.sun_family = AF_UNIX; 1162 1163 if (os_strncmp(ctrl, "@abstract:", 10) == 0) { 1164 addr.sun_path[0] = '\0'; 1165 os_strlcpy(addr.sun_path + 1, ctrl + 10, 1166 sizeof(addr.sun_path) - 1); 1167 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 1168 0) { 1169 wpa_printf(MSG_ERROR, "supp-global-ctrl-iface-init: " 1170 "bind(PF_UNIX;%s) failed: %s", 1171 ctrl, strerror(errno)); 1172 goto fail; 1173 } 1174 wpa_printf(MSG_DEBUG, "Using Abstract control socket '%s'", 1175 ctrl + 10); 1176 goto havesock; 1177 } 1178 1179 os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path)); 1180 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1181 wpa_printf(MSG_INFO, "supp-global-ctrl-iface-init(%s) (will try fixup): bind(PF_UNIX): %s", 1182 ctrl, strerror(errno)); 1183 if (connect(priv->sock, (struct sockaddr *) &addr, 1184 sizeof(addr)) < 0) { 1185 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 1186 " allow connections - assuming it was left" 1187 "over from forced program termination"); 1188 if (unlink(ctrl) < 0) { 1189 wpa_printf(MSG_ERROR, 1190 "Could not unlink existing ctrl_iface socket '%s': %s", 1191 ctrl, strerror(errno)); 1192 goto fail; 1193 } 1194 if (bind(priv->sock, (struct sockaddr *) &addr, 1195 sizeof(addr)) < 0) { 1196 wpa_printf(MSG_ERROR, "supp-glb-iface-init: bind(PF_UNIX;%s): %s", 1197 ctrl, strerror(errno)); 1198 goto fail; 1199 } 1200 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 1201 "ctrl_iface socket '%s'", 1202 ctrl); 1203 } else { 1204 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 1205 "be in use - cannot override it"); 1206 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 1207 "not used anymore", 1208 ctrl); 1209 goto fail; 1210 } 1211 } 1212 1213 wpa_printf(MSG_DEBUG, "Using UNIX control socket '%s'", ctrl); 1214 1215 if (global->params.ctrl_interface_group) { 1216 char *gid_str = global->params.ctrl_interface_group; 1217 gid_t gid = 0; 1218 struct group *grp; 1219 char *endp; 1220 1221 grp = getgrnam(gid_str); 1222 if (grp) { 1223 gid = grp->gr_gid; 1224 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" 1225 " (from group name '%s')", 1226 (int) gid, gid_str); 1227 } else { 1228 /* Group name not found - try to parse this as gid */ 1229 gid = strtol(gid_str, &endp, 10); 1230 if (*gid_str == '\0' || *endp != '\0') { 1231 wpa_printf(MSG_ERROR, "CTRL: Invalid group " 1232 "'%s'", gid_str); 1233 goto fail; 1234 } 1235 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", 1236 (int) gid); 1237 } 1238 if (chown(ctrl, -1, gid) < 0) { 1239 wpa_printf(MSG_ERROR, 1240 "chown[global_ctrl_interface=%s,gid=%d]: %s", 1241 ctrl, (int) gid, strerror(errno)); 1242 goto fail; 1243 } 1244 1245 if (chmod(ctrl, S_IRWXU | S_IRWXG) < 0) { 1246 wpa_printf(MSG_ERROR, 1247 "chmod[global_ctrl_interface=%s]: %s", 1248 ctrl, strerror(errno)); 1249 goto fail; 1250 } 1251 } else { 1252 if (chmod(ctrl, S_IRWXU) < 0) { 1253 wpa_printf(MSG_DEBUG, 1254 "chmod[global_ctrl_interface=%s](S_IRWXU): %s", 1255 ctrl, strerror(errno)); 1256 /* continue anyway since group change was not required 1257 */ 1258 } 1259 } 1260 1261havesock: 1262 1263 /* 1264 * Make socket non-blocking so that we don't hang forever if 1265 * target dies unexpectedly. 1266 */ 1267 flags = fcntl(priv->sock, F_GETFL); 1268 if (flags >= 0) { 1269 flags |= O_NONBLOCK; 1270 if (fcntl(priv->sock, F_SETFL, flags) < 0) { 1271 wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s", 1272 strerror(errno)); 1273 /* Not fatal, continue on.*/ 1274 } 1275 } 1276 1277 eloop_register_read_sock(priv->sock, 1278 wpa_supplicant_global_ctrl_iface_receive, 1279 global, priv); 1280 1281 return 0; 1282 1283fail: 1284 if (priv->sock >= 0) { 1285 close(priv->sock); 1286 priv->sock = -1; 1287 } 1288 return -1; 1289} 1290 1291 1292struct ctrl_iface_global_priv * 1293wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global) 1294{ 1295 struct ctrl_iface_global_priv *priv; 1296 1297 priv = os_zalloc(sizeof(*priv)); 1298 if (priv == NULL) 1299 return NULL; 1300 dl_list_init(&priv->ctrl_dst); 1301 dl_list_init(&priv->msg_queue); 1302 priv->global = global; 1303 priv->sock = -1; 1304 1305 if (global->params.ctrl_interface == NULL) 1306 return priv; 1307 1308 if (wpas_global_ctrl_iface_open_sock(global, priv) < 0) { 1309 os_free(priv); 1310 return NULL; 1311 } 1312 1313 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); 1314 1315 return priv; 1316} 1317 1318 1319static int wpas_ctrl_iface_global_reinit(struct wpa_global *global, 1320 struct ctrl_iface_global_priv *priv) 1321{ 1322 int res; 1323 1324 if (priv->sock <= 0) 1325 return -1; 1326 1327 /* 1328 * On Android, the control socket being used may be the socket 1329 * that is created when wpa_supplicant is started as a /init.*.rc 1330 * service. Such a socket is maintained as a key-value pair in 1331 * Android's environment. Closing this control socket would leave us 1332 * in a bad state with an invalid socket descriptor. 1333 */ 1334 if (priv->android_control_socket) 1335 return priv->sock; 1336 1337 eloop_unregister_read_sock(priv->sock); 1338 close(priv->sock); 1339 priv->sock = -1; 1340 res = wpas_global_ctrl_iface_open_sock(global, priv); 1341 if (res < 0) 1342 return -1; 1343 return priv->sock; 1344} 1345 1346 1347void 1348wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv) 1349{ 1350 struct wpa_ctrl_dst *dst, *prev; 1351 struct ctrl_iface_msg *msg, *prev_msg; 1352 1353 if (priv->sock >= 0) { 1354 eloop_unregister_read_sock(priv->sock); 1355 close(priv->sock); 1356 } 1357 if (priv->global->params.ctrl_interface) 1358 unlink(priv->global->params.ctrl_interface); 1359 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst, 1360 list) { 1361 dl_list_del(&dst->list); 1362 os_free(dst); 1363 } 1364 dl_list_for_each_safe(msg, prev_msg, &priv->msg_queue, 1365 struct ctrl_iface_msg, list) { 1366 dl_list_del(&msg->list); 1367 os_free(msg); 1368 } 1369 os_free(priv); 1370} 1371