POSIX specifies EACCES as a "may fail" condition for connect() on an AF_UNIX socket; it is a "shall fail" condition for open(). I take this to mean that a conforming connect() implementation could ignore directory search permissions and/or the socket's own file mode. Indeed, a couple of decades ago, some systems did ignore the socket's own file mode:
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-1999-1402 Do any porting targets of contemporary relevance still behave this way? If so, which OS versions are known affected? I have attached a test program that illustrates the exact behavior in question, which you can use to test your own system if curious. The most gnulib could do is to document this portability hazard, since nothing outside the kernel could effectively eliminate it. I ask here since the gnulib documentation is one of my go-to sources for portability information. Thanks, nm
#include <errno.h> #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/un.h> #include <unistd.h> const char sockpath[] = "/tmp/sockperm_test"; int main(int argc, char **argv) { int server_fd, client_fd; struct sockaddr_un addr; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, sockpath); server_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (server_fd < 0) { perror("socket"); return 1; } if (bind(server_fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { perror("bind"); return 1; } if (chmod(sockpath, 0) != 0) { perror("chmod"); return 1; } if (listen(server_fd, 0) != 0) { perror("listen"); return 1; } client_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (client_fd < 0) { perror("socket"); return 1; } if (connect(client_fd, (struct sockaddr *) &addr, sizeof(addr)) == 0) puts("connect: unexpected non-failure"); else if (errno == EACCES) puts("connect: normal behavior (EACCES)"); else perror("connect: unexpected failure"); if (unlink(sockpath) != 0) { perror("unlink"); return 1; } return 0; }