about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2024-08-18 03:35:41 +0000
committerLaurent Bercot <ska@appnovation.com>2024-08-18 03:35:41 +0000
commit7b36e30a8f599942379909f5ec39456e010488b6 (patch)
tree100218d06f36eb8f042fb9eefdfe967c406715c1 /src
parenta08ca5f05b4a6bacc5b80b738d6a071593465a97 (diff)
downloads6-7b36e30a8f599942379909f5ec39456e010488b6.tar.gz
s6-7b36e30a8f599942379909f5ec39456e010488b6.tar.xz
s6-7b36e30a8f599942379909f5ec39456e010488b6.zip
Tentatively fix selfpipe clobbering by notification-fd
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-rw-r--r--src/supervision/s6-supervise.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c
index c0a3edb..86c7709 100644
--- a/src/supervision/s6-supervise.c
+++ b/src/supervision/s6-supervise.c
@@ -142,6 +142,15 @@ static void set_down_and_ready (char const *s, unsigned int n)
   ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, s, n) ;
 }
 
+static int check_available_fd (int fd, char const *name)
+{
+  int r = fd > maxfd ? (errno = EMFILE, -1) : fcntl(fd, F_GETFD) ;
+  if (r == -1 && errno == EBADF) return 1 ;
+  if (r == -1) strerr_warnwu3sys("check availability of ", name, " (waiting 60 seconds)") ;
+  else strerr_warnw3x(name, " already used internally, please modify its value!", " (waiting 60 seconds)") ;
+  return 0 ;
+}
+
 
 /* The action array. */
 
@@ -298,7 +307,11 @@ static void trystart (void)
 
   if (read_uint("lock-fd", &lk))
   {
-    if (lk > maxfd) strerr_warnw2x("invalid ", "lock-fd") ;
+    if (!check_available_fd(lk, "lock-fd"))
+    {
+      settimeout(60) ;
+      return ;
+    }
     else
     {
       struct stat st ;
@@ -306,14 +319,14 @@ static void trystart (void)
       int lfd = open_write(SLCK) ;
       if (lfd == -1)
       {
-        settimeout(60) ;
         strerr_warnwu4sys("open ", SLCK, " for writing", " (waiting 60 seconds)") ;
-        goto errn ;
+        settimeout(60) ;
+        return ;
       }
       if (fstat(lfd, &st) == -1)
       {
-        settimeout(60) ;
         strerr_warnwu3sys("stat ", SLCK, " (waiting 60 seconds)") ;
+        settimeout(60) ;
         fd_close(lfd) ;
         return ;
       }
@@ -325,13 +338,13 @@ static void trystart (void)
       islocked = fd_islocked(lfd) ;
       if (islocked == -1)
       {
-        settimeout(60) ;
         strerr_warnwu3sys("read lock state on ", SLCK, " (waiting 60 seconds)") ;
+        settimeout(60) ;
         fd_close(lfd) ;
         return ;
       }
       if (islocked)
-        strerr_warnw1x("another instance of the service is already running, child will block") ;
+        strerr_warni1x("another instance of the service is already running, child will block") ;
       fd_close(lfd) ;
       lkfmt[uint_fmt(lkfmt, lk)] = 0 ;
       orig = 0 ;
@@ -340,11 +353,11 @@ static void trystart (void)
 
   if (read_uint("notification-fd", &notif))
   {
-    if (notif > maxfd) strerr_warnw2x("invalid ", "notification-fd") ;
-    if (!orig && notif == lk)
+    if (!check_available_fd(notif, "notification-fd"))
     {
-      settimeout_infinite() ;
-      strerr_warnwu1x("start service: notification-fd and lock-fd are the same") ;
+      settimeout(60) ;
+      if (!orig && notif == lk)
+      strerr_warnw1x("notification-fd and lock-fd are the same") ;
       return ;
     }
     if (pipe(notifyp) == -1)