#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>
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) {
}
#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(
void wpa_ctrl_cleanup(void)
{
DIR *dir;
- struct dirent entry;
struct dirent *result;
size_t dirnamelen;
size_t maxcopy;
}
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);