By my experience unprivileged user can not access unix socket he/she does not own without x bit set. What does this bit do exactly? Thanks
Linux – What does x (execute) permission do on unix sockets
linuxpermissionsunix-sockets
Related Solutions
The code that generates this file is in the unix_seq_show()
function in net/unix/af_unix.c
in the kernel source. Looking at include/net/af_unix.h
is also helpful, to see the data structures in use.
The socket path is always the last column in the output, and the Android kernel source matches the stock kernel in this respect. So unless I'm mistaken, that number that looks like a column isn't actually a separate column.
You can name UNIX domain sockets practically anything you want, as long as the total path length is less than 108 bytes. So you can't make any assumptions as to what these paths will look like. It's possible that the userspace code that's choosing those names is using a tab character followed by a number, or even padding the name out to a certain length with spaces. To test my theory, you might try looking at the socket files in /dev/socket/qmux_radio/
.
Yes, linux automatically "cleans up" abstract sockets to the extent that cleaning up even makes sense. Here's a minimal working example with which you can verify this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
int
main(int argc, char **argv)
{
int s;
struct sockaddr_un sun;
if (argc != 2 || strlen(argv[1]) + 1 > sizeof(sun.sun_path)) {
fprintf(stderr, "usage: %s abstract-path\n", argv[0]);
exit(1);
}
s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s < 0) {
perror("socket");
exit(1);
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path + 1, argv[1]);
if (bind(s, (struct sockaddr *) &sun, sizeof(sun))) {
perror("bind");
exit(1);
}
pause();
}
Run this program as ./a.out /test-socket &
, then run ss -ax | grep test-socket
, and you will see the socket in use. Then kill %./a.out
, and ss -ax
will show the socket is gone.
However, the reason you can't find this clean-up in any documentation is that it isn't really cleaning up in the same sense that non-abstract unix-domain sockets need cleaning up. A non-abstract socket actually allocates an inode and creates an entry in a directory, which needs to be cleaned up in the underlying file system. By contrast, think of an abstract socket more like a TCP or UDP port number. Sure, if you bind a TCP port and then exit, that TCP port will be free again. But whatever 16-bit number you used still exists abstractly and always did. The namespace of port numbers is 1-65535 and never changes or needs cleaning.
So just think of the abstract socket name like a TCP or UDP port number, just picked from a much larger set of possible port numbers that happen to look like pathnames but are not. You can't bind the same port number twice (barring SO_REUSEADDR
or SO_REUSEPORT
). But closing the socket (explicitly or implicitly by terminating) frees the port, with nothing left to clean up.
Best Answer
Nothing, as I can see.
The Linux man page unix(7) says that the permissions of the directory containing a socket apply normally (i.e. you need
+x
on/foo
to connect to/foo/sock
, and+w
on/foo
to create/foo/sock
) and that write permission controls connecting to the socket itself:Apparently some other systems behave differently:
unix(4)
on FreeBSD describes similar requirements. The Linux man page didn't say if socket access on some systems ignores the directory permissions too.Removing the
x
bit from the socket seems to have the effect of giving a different error for trying execute the socket, but that's not much of a practical difference:(I did also test that indeed only the
w
bit seems to matter for accessing the socket on Debian's Linux 4.9.0.)Perhaps the sockets you meant had all permission bits removed from the user, or you meant the
x
bit on the directory?