diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2024-08-18 03:35:41 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2024-08-18 03:35:41 +0000 |
commit | 7b36e30a8f599942379909f5ec39456e010488b6 (patch) | |
tree | 100218d06f36eb8f042fb9eefdfe967c406715c1 | |
parent | a08ca5f05b4a6bacc5b80b738d6a071593465a97 (diff) | |
download | s6-7b36e30a8f599942379909f5ec39456e010488b6.tar.xz |
Tentatively fix selfpipe clobbering by notification-fd
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/supervision/s6-supervise.c | 33 |
2 files changed, 24 insertions, 10 deletions
@@ -42,3 +42,4 @@ Thanks to: Oliver Schad <oliver.schad@automatic-server.com> Alex Kiernan <alex.kiernan@gmail.com> Earl Chew <earl_chew@yahoo.com> + Saj Goonatilleke <saj@discourse.org> 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", ¬if)) { - 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) |