]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - src/common/wpa_ctrl.c
Add attribute for dwell time in QCA vendor scan
[thirdparty/hostap.git] / src / common / wpa_ctrl.c
index 623c2a768e43de522c7f05ee6134a36412dd21f8..40a979531b53673b4f7dafbc8d55919c8c493a7f 100644 (file)
@@ -11,6 +11,8 @@
 #ifdef CONFIG_CTRL_IFACE
 
 #ifdef CONFIG_CTRL_IFACE_UNIX
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <sys/un.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -133,6 +135,19 @@ try_again:
                return NULL;
        }
        tries++;
+#ifdef ANDROID
+       /* Set client socket file permissions so that bind() creates the client
+        * socket with these permissions and there is no need to try to change
+        * them with chmod() after bind() which would have potential issues with
+        * race conditions. These permissions are needed to make sure the server
+        * side (wpa_supplicant or hostapd) can reply to the control interface
+        * messages.
+        *
+        * The lchown() calls below after bind() are also part of the needed
+        * operations to allow the response to go through. Those are using the
+        * no-deference-symlinks version to avoid races. */
+       fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+#endif /* ANDROID */
        if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
                    sizeof(ctrl->local)) < 0) {
                if (errno == EADDRINUSE && tries < 2) {
@@ -151,10 +166,9 @@ try_again:
        }
 
 #ifdef ANDROID
-       chmod(ctrl->local.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
        /* Set group even if we do not have privileges to change owner */
-       chown(ctrl->local.sun_path, -1, AID_WIFI);
-       chown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI);
+       lchown(ctrl->local.sun_path, -1, AID_WIFI);
+       lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI);
 
        if (os_strncmp(ctrl_path, "@android:", 9) == 0) {
                if (socket_local_client_connect(
@@ -252,7 +266,6 @@ void wpa_ctrl_close(struct wpa_ctrl *ctrl)
 void wpa_ctrl_cleanup(void)
 {
        DIR *dir;
-       struct dirent entry;
        struct dirent *result;
        size_t dirnamelen;
        size_t maxcopy;
@@ -270,8 +283,8 @@ void wpa_ctrl_cleanup(void)
        }
        namep = pathname + dirnamelen;
        maxcopy = PATH_MAX - dirnamelen;
-       while (readdir_r(dir, &entry, &result) == 0 && result != NULL) {
-               if (os_strlcpy(namep, entry.d_name, maxcopy) < maxcopy)
+       while ((result = readdir(dir)) != NULL) {
+               if (os_strlcpy(namep, result->d_name, maxcopy) < maxcopy)
                        unlink(pathname);
        }
        closedir(dir);
@@ -540,7 +553,8 @@ retry_send:
                        res = recv(ctrl->s, reply, *reply_len, 0);
                        if (res < 0)
                                return res;
-                       if (res > 0 && reply[0] == '<') {
+                       if ((res > 0 && reply[0] == '<') ||
+                           (res > 6 && strncmp(reply, "IFNAME=", 7) == 0)) {
                                /* This is an unsolicited message from
                                 * wpa_supplicant, not the reply to the
                                 * request. Use msg_cb to report this to the