]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
include/pidfd-utils: improve robustness
authorKarel Zak <kzak@redhat.com>
Tue, 4 Mar 2025 08:47:11 +0000 (09:47 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 4 Mar 2025 10:39:26 +0000 (11:39 +0100)
* remove global UL_HAVE_PIDFD, in many cases we need only subset of pidfd
  kernel API, rrather than all the functios

* improve #ifdefs for pidfd_*() direct syscalls

* improve dummy fallback to not redefine system header files

Fixes: https://github.com/util-linux/util-linux/issues/3437
Signed-off-by: Karel Zak <kzak@redhat.com>
include/pidfd-utils.h
misc-utils/kill.c
sys-utils/unshare.c

index 5bd59694a5ba6a788a334ad6bc53a4bc33028cc4..08627ca8d286e023c0c9dc48f0b6290d2fc45aa5 100644 (file)
 # include <sys/syscall.h>
 # include <unistd.h>
 
-# if defined(SYS_pidfd_send_signal) && defined(SYS_pidfd_open)
-#  ifndef HAVE_PIDFD_SEND_SIGNAL
+# if !defined(HAVE_PIDFD_SEND_SIGNAL) && defined(SYS_pidfd_send_signal)
 static inline int pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
                                    unsigned int flags)
 {
        return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags);
 }
-#  endif
+# endif
 
-#  ifndef HAVE_PIDFD_OPEN
+# if !defined(HAVE_PIDFD_OPEN) && defined(SYS_pidfd_open)
 static inline int pidfd_open(pid_t pid, unsigned int flags)
 {
        return syscall(SYS_pidfd_open, pid, flags);
 }
-#  endif
+# endif
 
-#  ifndef HAVE_PIDFD_GETFD
+# if !defined(HAVE_PIDFD_GETFD) && defined(SYS_pidfd_getfd)
 static inline int pidfd_getfd(int pidfd, int targetfd, unsigned int flags)
 {
        return syscall(SYS_pidfd_getfd, pidfd, targetfd, flags);
 }
-#  endif
+# endif
+#endif /* HAVE_SYS_SYSCALL_H */
 
-#  define UL_HAVE_PIDFD 1
 
-# endif        /* SYS_pidfd_send_signal */
-#endif /* HAVE_SYS_SYSCALL_H */
+/*
+ * Dummy fallbacks for cases when #ifdef HAVE_PIDFD_* makes the code too complex.
+ */
 
-#ifndef UL_HAVE_PIDFD
+#if !defined(HAVE_PIDFD_SEND_SIGNAL) && !defined(SYS_pidfd_send_signal)
 static inline int pidfd_send_signal(int pidfd __attribute__((unused)),
                                    int sig __attribute__((unused)),
                                    siginfo_t *info __attribute__((unused)),
@@ -73,14 +73,18 @@ static inline int pidfd_send_signal(int pidfd __attribute__((unused)),
        errno = ENOSYS;
        return -1;
 }
+#endif
 
+#if !defined(HAVE_PIDFD_OPEN) && !defined(SYS_pidfd_open)
 static inline int pidfd_open(pid_t pid __attribute__((unused)),
                             unsigned int flags __attribute__((unused)))
 {
        errno = ENOSYS;
        return -1;
 }
+#endif
 
+# if !defined(HAVE_PIDFD_GETFD) && !defined(SYS_pidfd_getfd)
 static inline int pidfd_getfd(int pidfd __attribute__((unused)),
                              int targetfd __attribute__((unused)),
                              unsigned int flags __attribute__((unused)))
index a911df6b723448ee2899c8a3741196810dbec21c..fefe0d89179be93216c5f84f892374dff5d12e78 100644 (file)
 /* partial success, otherwise we return regular EXIT_{SUCCESS,FAILURE} */
 #define KILL_EXIT_SOMEOK       64
 
+#if defined(HAVE_PIDFD_OPEN) && defined(HAVE_PIDFD_SEND_SIGNAL)
+# define USE_KILL_WITH_TIMEOUT 1
+#endif
+
 enum {
        KILL_FIELD_WIDTH = 11,
        KILL_OUTPUT_WIDTH = 72
 };
 
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
 # include <poll.h>
 # include "list.h"
 struct timeouts {
@@ -89,7 +93,7 @@ struct kill_control {
 #ifdef HAVE_SIGQUEUE
        union sigval sigdata;
 #endif
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
        struct list_head follow_ups;
 #endif
        bool    check_all,
@@ -97,7 +101,7 @@ struct kill_control {
                do_pid,
                require_handler,
                use_sigval,
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
                timeout,
 #endif
                verbose;
@@ -269,7 +273,7 @@ static void __attribute__((__noreturn__)) usage(void)
 #ifdef HAVE_SIGQUEUE
        fputs(_(" -q, --queue <value>    use sigqueue(2), not kill(2), and pass <value> as data\n"), out);
 #endif
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
        fputs(_("     --timeout <milliseconds> <follow-up signal>\n"
                "                        wait up to timeout and send follow-up signal\n"), out);
 #endif
@@ -296,7 +300,7 @@ static void __attribute__((__noreturn__)) print_kill_version(void)
 #ifdef HAVE_SIGQUEUE
                "sigqueue",
 #endif
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
                "pidfd",
 #endif
        };
@@ -443,7 +447,7 @@ static char **parse_arguments(int argc, char **argv, struct kill_control *ctl)
                        continue;
                }
 #endif
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
                if (!strcmp(arg, "--timeout")) {
                        struct timeouts *next;
 
@@ -485,7 +489,7 @@ static char **parse_arguments(int argc, char **argv, struct kill_control *ctl)
        return argv;
 }
 
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
 static int kill_with_timeout(const struct kill_control *ctl)
 {
        int pfd, n;
@@ -537,7 +541,7 @@ static int kill_verbose(const struct kill_control *ctl)
                printf("%ld\n", (long) ctl->pid);
                return 0;
        }
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
        if (ctl->timeout) {
                rc = kill_with_timeout(ctl);
        } else
@@ -590,7 +594,7 @@ int main(int argc, char **argv)
        textdomain(PACKAGE);
        close_stdout_atexit();
 
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
        INIT_LIST_HEAD(&ctl.follow_ups);
 #endif
        argv = parse_arguments(argc, argv, &ctl);
@@ -642,7 +646,7 @@ int main(int argc, char **argv)
                }
        }
 
-#ifdef UL_HAVE_PIDFD
+#ifdef USE_KILL_WITH_TIMEOUT
        while (!list_empty(&ctl.follow_ups)) {
                struct timeouts *x = list_entry(ctl.follow_ups.next,
                                                  struct timeouts, follow_ups);
index 9ec6ef7cce15096ad3296314e11ded390404dddd..d5ce369c2b4d80cdb1dcfc1afcd100ffa4c4bef8 100644 (file)
@@ -889,7 +889,7 @@ int main(int argc, char *argv[])
        pid_t pid_bind = 0, pid_idmap = 0;
        const char *newinterp = NULL;
        pid_t pid = 0;
-#ifdef UL_HAVE_PIDFD
+#ifdef HAVE_PIDFD_OPEN
        int fd_parent_pid = -1;
 #endif
        int fd_idmap, fd_bind = -1;
@@ -1116,7 +1116,7 @@ int main(int argc, char *argv[])
                        sigaddset(&sigset, SIGTERM) != 0 ||
                        sigprocmask(SIG_BLOCK, &sigset, &oldsigset) != 0)
                        err(EXIT_FAILURE, _("sigprocmask block failed"));
-#ifdef UL_HAVE_PIDFD
+#ifdef HAVE_PIDFD_OPEN
                if (kill_child_signo != 0) {
                        /* make a connection to the original process (parent) */
                        fd_parent_pid = pidfd_open(getpid(), 0);
@@ -1182,7 +1182,7 @@ int main(int argc, char *argv[])
        if (kill_child_signo != 0) {
                if (prctl(PR_SET_PDEATHSIG, kill_child_signo) < 0)
                        err(EXIT_FAILURE, "prctl failed");
-#ifdef UL_HAVE_PIDFD
+#ifdef HAVE_PIDFD_OPEN
                /* Use poll() to check that there is still the original parent. */
                if (fd_parent_pid != -1) {
                        struct pollfd pollfds[1] = {