Zbigniew Jędrzejewski-Szmek 126222
From 9b618fb2369046434ced28fe1420d8d5c75cd46e Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 126222
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Zbigniew Jędrzejewski-Szmek 126222
Date: Tue, 10 Dec 2013 21:52:11 -0500
Zbigniew Jędrzejewski-Szmek 126222
Subject: [PATCH] activate: clean up inherited descriptors
Zbigniew Jędrzejewski-Szmek 126222
Zbigniew Jędrzejewski-Szmek 126222
> [simon@troela server]$ /usr/lib/systemd/systemd-activate -l 9000 main.js
Zbigniew Jędrzejewski-Szmek 126222
> Assertion 'fd == 3 + count' failed at src/activate/activate.c:115,
Zbigniew Jędrzejewski-Szmek 126222
> function open_sockets(). Aborting.
Zbigniew Jędrzejewski-Szmek 126222
> Aborted (core dumped)
Zbigniew Jędrzejewski-Szmek 126222
Zbigniew Jędrzejewski-Szmek 126222
> after a bit debuging i found the problem:
Zbigniew Jędrzejewski-Szmek 126222
> slim appears to leak an fd into all of its children:
Zbigniew Jędrzejewski-Szmek 126222
> stat /proc/14004/fd/3  (14004 is the pid a random process in my session)
Zbigniew Jędrzejewski-Szmek 126222
>  File: '/proc/14004/fd/3' -> '/var/log/slim.log'
Zbigniew Jędrzejewski-Szmek 126222
Zbigniew Jędrzejewski-Szmek 126222
systemd-activate should be robust against the shell (or anything else) leaking
Zbigniew Jędrzejewski-Szmek 126222
descriptors. Now everything except stdin/stdout/stderr and received sockets
Zbigniew Jędrzejewski-Szmek 126222
will be closed.
Zbigniew Jędrzejewski-Szmek 126222
---
Zbigniew Jędrzejewski-Szmek 126222
 src/activate/activate.c | 23 +++++++++++++++++++----
Zbigniew Jędrzejewski-Szmek 126222
 1 file changed, 19 insertions(+), 4 deletions(-)
Zbigniew Jędrzejewski-Szmek 126222
Zbigniew Jędrzejewski-Szmek 126222
diff --git a/src/activate/activate.c b/src/activate/activate.c
Zbigniew Jędrzejewski-Szmek 126222
index a9461bc..6aa8b9f 100644
Zbigniew Jędrzejewski-Szmek 126222
--- a/src/activate/activate.c
Zbigniew Jędrzejewski-Szmek 126222
+++ b/src/activate/activate.c
Zbigniew Jędrzejewski-Szmek 126222
@@ -137,6 +137,17 @@ static int open_sockets(int *epoll_fd, bool accept) {
Zbigniew Jędrzejewski-Szmek 126222
                 count ++;
Zbigniew Jędrzejewski-Szmek 126222
         }
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
+        /* Close logging and all other descriptors */
Zbigniew Jędrzejewski-Szmek 126222
+        if (arg_listen) {
Zbigniew Jędrzejewski-Szmek 126222
+                int except[3 + n];
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+                for (fd = 0; fd < SD_LISTEN_FDS_START + n; fd++)
Zbigniew Jędrzejewski-Szmek 126222
+                        except[fd] = fd;
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+                log_close();
Zbigniew Jędrzejewski-Szmek 126222
+                close_all_fds(except, 3 + n);
Zbigniew Jędrzejewski-Szmek 126222
+        }
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
         /** Note: we leak some fd's on error here. I doesn't matter
Zbigniew Jędrzejewski-Szmek 126222
          *  much, since the program will exit immediately anyway, but
Zbigniew Jędrzejewski-Szmek 126222
          *  would be a pain to fix.
Zbigniew Jędrzejewski-Szmek 126222
@@ -147,6 +158,7 @@ static int open_sockets(int *epoll_fd, bool accept) {
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
                 fd = make_socket_fd(*address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
Zbigniew Jędrzejewski-Szmek 126222
                 if (fd < 0) {
Zbigniew Jędrzejewski-Szmek 126222
+                        log_open();
Zbigniew Jędrzejewski-Szmek 126222
                         log_error("Failed to open '%s': %s", *address, strerror(-fd));
Zbigniew Jędrzejewski-Szmek 126222
                         return fd;
Zbigniew Jędrzejewski-Szmek 126222
                 }
Zbigniew Jędrzejewski-Szmek 126222
@@ -154,6 +166,9 @@ static int open_sockets(int *epoll_fd, bool accept) {
Zbigniew Jędrzejewski-Szmek 126222
                 count ++;
Zbigniew Jędrzejewski-Szmek 126222
         }
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
+        if (arg_listen)
Zbigniew Jędrzejewski-Szmek 126222
+                log_open();
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
         *epoll_fd = epoll_create1(EPOLL_CLOEXEC);
Zbigniew Jędrzejewski-Szmek 126222
         if (*epoll_fd < 0) {
Zbigniew Jędrzejewski-Szmek 126222
                 log_error("Failed to create epoll object: %m");
Zbigniew Jędrzejewski-Szmek 126222
@@ -298,10 +313,10 @@ static void sigchld_hdl(int sig, siginfo_t *t, void *data) {
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
 static int install_chld_handler(void) {
Zbigniew Jędrzejewski-Szmek 126222
         int r;
Zbigniew Jędrzejewski-Szmek 126222
-        struct sigaction act;
Zbigniew Jędrzejewski-Szmek 126222
-        zero(act);
Zbigniew Jędrzejewski-Szmek 126222
-        act.sa_flags = SA_SIGINFO;
Zbigniew Jędrzejewski-Szmek 126222
-        act.sa_sigaction = sigchld_hdl;
Zbigniew Jędrzejewski-Szmek 126222
+        struct sigaction act = {
Zbigniew Jędrzejewski-Szmek 126222
+                .sa_flags = SA_SIGINFO,
Zbigniew Jędrzejewski-Szmek 126222
+                .sa_sigaction = sigchld_hdl,
Zbigniew Jędrzejewski-Szmek 126222
+        };
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         r = sigaction(SIGCHLD, &act, 0);
Zbigniew Jędrzejewski-Szmek 126222
         if (r < 0)