Skip to content

Commit

Permalink
listen_for_commands: stop leaking the control socket to forked procs
Browse files Browse the repository at this point in the history
All the exec'ed processes would get copies of the control socket
descriptors, because of the default UNIX semantics of fd inherit across
execv().  This was easily seen on my system where an 'lsof' revealed
that all my terminals and shells had a copy.

To fix this we add the SOCK_CLOEXEC flag whilst opening the listener
socket(), avoiding this problem.  We also need to set CLOEXEC on the
socket returned by accept():

  "accept() ... extracts the first connection request on the queue of
  pending connections ... creates a new connected socket, and returns a
  new file descriptor"

The new descriptor does not inherit CLOEXEC flag from the listener.

The "bar" descriptor already handles this by setting O_CLOEXEC in its
own open() call on the FIFO.
  • Loading branch information
smemsh authored and jcs committed Aug 29, 2024
1 parent 336e5ab commit 50c0635
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion communications.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ listen_for_commands(void)
struct sockaddr_un sun;

if ((rp_glob_screen.control_socket_fd = socket(AF_UNIX,
SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)) == -1)
err(1, "socket");

if (strlen(rp_glob_screen.control_socket_path) >= sizeof(sun.sun_path))
Expand Down Expand Up @@ -265,6 +265,11 @@ receive_command(void)
warn("accept");
return;
}
if ((fcntl(cl, F_SETFD, FD_CLOEXEC)) == -1) {
warn("cloexec");
close(cl);
return;
}

if ((len = recv_unix(cl, &cmd)) <= 1) {
warnx("receive_command: %s\n",
Expand Down

0 comments on commit 50c0635

Please sign in to comment.