1

I want to create a Unix domain socket which is restricted to a particular group. So what I'd ideally do is (ignoring error checking) something like:

// Set the "address" (ie filesystem path)
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, "./my.sock");

int fd = socket(AF_UNIX, SOCK_DGRAM, 0);  // create the socket

// Set the group owner and permissions
fchmod(fd, 0770); // This seems to succeed
fchown(fd, -1, wanted_group_id);  // Silently fails

// Create the filesystem entry
bind(fd, (struct sockaddr *)&addr, sizeof(addr));

However, fchown on a socket has no effect, so it seems that chown afterwards is the only way to set the group. I want to avoid having the socket temporarily accessible to processes which shouldn't be permitted to access it.

The best idea I have is:

int fd = socket(...);
fchmod(fd, 0700);  // Remove group permissions
bind(fd, ...);     // Create fs entry
chown("./my.sock", -1, wanted_group_id); // set the correct group owner
fchmod(fd, 0770);  // And restore group permissions

Surely this is a common thing to want to do with Unix sockets, and there's a canonical way of achieving this, but I haven't found any clear answers.

I'm only really interested in Linux, but bonus points for something that only relies on POSIX.

Chris Emerson
  • 13,041
  • 3
  • 44
  • 66
  • You could make the program creating the socket Set-GID to the desired group, in order to cause it to get created with the desired group in the first place. – Gil Hamilton Jun 29 '16 at 14:54
  • I don't think that helps. My program will already have that group available, and will want to create multiple sockets with different groups. – Chris Emerson Jun 29 '16 at 15:53
  • A similar idea: on linux at least, you could grant your program the `CAP_SETGID` capability and then you can adopt whatever group ID you wish temporarily. – Gil Hamilton Jun 29 '16 at 18:25
  • I'm trying to reduce permissions processes have rather than increase them; adding root capabilities goes against that. – Chris Emerson Jun 29 '16 at 18:39

1 Answers1

2

The way to do this is to put the socket into a directory with the correct permissions. Directories can be created (or renamed into place) atomically, and once the directory is present the permissions on the socket itself are not very important. This also works on the Unixes where the permissions on the socket itself aren't always honoured.

Chris Emerson
  • 13,041
  • 3
  • 44
  • 66