From 4a1053812f396619070b6849f4d8830c1ee272ee Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 4 Mar 2025 09:47:11 +0100 Subject: [PATCH] include/pidfd-utils: improve robustness * 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 --- include/pidfd-utils.h | 26 +++++++++++++++----------- misc-utils/kill.c | 24 ++++++++++++++---------- sys-utils/unshare.c | 6 +++--- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/include/pidfd-utils.h b/include/pidfd-utils.h index 5bd59694a..08627ca8d 100644 --- a/include/pidfd-utils.h +++ b/include/pidfd-utils.h @@ -36,35 +36,35 @@ # include # include -# 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))) diff --git a/misc-utils/kill.c b/misc-utils/kill.c index a911df6b7..fefe0d891 100644 --- a/misc-utils/kill.c +++ b/misc-utils/kill.c @@ -67,12 +67,16 @@ /* 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 # 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 use sigqueue(2), not kill(2), and pass as data\n"), out); #endif -#ifdef UL_HAVE_PIDFD +#ifdef USE_KILL_WITH_TIMEOUT fputs(_(" --timeout \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); diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c index 9ec6ef7cc..d5ce369c2 100644 --- a/sys-utils/unshare.c +++ b/sys-utils/unshare.c @@ -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] = { -- 2.47.3