Dear Maintainer,
I configured wpa_supplicant to run as a non-root user (with CAP_NET_RAW
and CAP_NET_ADMIN as the README suggests), and found that wpa_cli would
hang on startup when trying to connect to it. strace shows that wpa_cli
creates named sockets in /tmp (despite $TMPDIR pointing elsewhere):
bind(3, {sa_family=AF_UNIX, sun_path="/tmp/wpa_ctrl_4848-1"}, 110) = 0
bind(4, {sa_family=AF_UNIX, sun_path="/tmp/wpa_ctrl_4848-2"}, 110) = 0
And then wpa_supplicant cannot reply:
sendto(12, "OK\n", 3, 0, {sa_family=AF_UNIX, sun_path=
"/tmp/wpa_ctrl_4824-2"}, 23) = -1 EACCES (Permission denied)
This is due to the umask and uid/gid being applied:
srwx--x--x 1 michael michael 0 Feb 15 14:10 /tmp/wpa_ctrl_4824-2
A workaround is to set umask to 0 before running wpa_cli.
On Linux, it would be better for wpa_cli to use the "autobind" feature
(see man 7 unix) by calling bind() with addrlen==sizeof(sa_family_t).
This seems to work fine, and then the server needs no special permission
to reply and doesn't need access to /tmp (and the client won't leave
garbage there if it exits abnormally).
Also, maybe wpa_cli's existing Android code to chmod() the socket should
be enabled more widely. POSIX says, for connect(), that "For SOCK_DGRAM
sockets, the peer address [...] limits the remote sender for subsequent
recv() functions"; so, if anyone other than the server sent messages to
the world-writable socket, the client wouldn't see them.
(I think SOCK_SEQPACKET would be a better fit than SOCK_DGRAM for the
control sockets, but that would require server and client changes.)
- Michael