diff options
Diffstat (limited to 'src/common/wpa_ctrl.c')
| -rw-r--r-- | src/common/wpa_ctrl.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c index 623c2a768e43d..c9890a0e49050 100644 --- a/src/common/wpa_ctrl.c +++ b/src/common/wpa_ctrl.c @@ -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( @@ -540,7 +554,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 |
