diff --git a/src/basic/argv-util.c b/src/basic/argv-util.c index 0602193809..20587f66ad 100644 --- a/src/basic/argv-util.c +++ b/src/basic/argv-util.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include "argv-util.h" #include "capability-util.h" @@ -133,10 +133,10 @@ static int update_argv(const char name[], size_t l) { strncpy(nn, name, nn_size); /* Now, let's tell the kernel about this new memory */ - if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) { - if (ERRNO_IS_PRIVILEGE(errno)) - return log_debug_errno(errno, "PR_SET_MM_ARG_START failed: %m"); - + r = prctl_safe(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0); + if (ERRNO_IS_NEG_PRIVILEGE(r)) + return log_debug_errno(r, "PR_SET_MM_ARG_START failed: %m"); + if (r < 0) { /* HACK: prctl() API is kind of dumb on this point. The existing end address may already be * below the desired start address, in which case the kernel may have kicked this back due * to a range-check failure (see linux/kernel/sys.c:validate_prctl_map() to see this in @@ -145,22 +145,25 @@ static int update_argv(const char name[], size_t l) { * and respond accordingly. For now, we can only guess at the cause of this failure and try * a workaround--which will briefly expand the arg space to something potentially huge before * resizing it to what we want. */ - log_debug_errno(errno, "PR_SET_MM_ARG_START failed, attempting PR_SET_MM_ARG_END hack: %m"); + log_debug_errno(r, "PR_SET_MM_ARG_START failed, attempting PR_SET_MM_ARG_END hack: %m"); - if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0) { - r = log_debug_errno(errno, "PR_SET_MM_ARG_END hack failed, proceeding without: %m"); + r = prctl_safe(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0); + if (r < 0) { + log_debug_errno(r, "PR_SET_MM_ARG_END hack failed, proceeding without: %m"); (void) munmap(nn, nn_size); return r; } - if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) - return log_debug_errno(errno, "PR_SET_MM_ARG_START still failed, proceeding without: %m"); + r = prctl_safe(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0); + if (r < 0) + return log_debug_errno(r, "PR_SET_MM_ARG_START still failed, proceeding without: %m"); } else { /* And update the end pointer to the new end, too. If this fails, we don't really know what * to do, it's pretty unlikely that we can rollback, hence we'll just accept the failure, * and continue. */ - if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0) - log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m"); + r = prctl_safe(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0); + if (r < 0) + log_debug_errno(r, "PR_SET_MM_ARG_END failed, proceeding without: %m"); } if (mm) @@ -172,8 +175,9 @@ static int update_argv(const char name[], size_t l) { strncpy(mm, name, mm_size); /* Update the end pointer, continuing regardless of any failure. */ - if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0) < 0) - log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m"); + r = prctl_safe(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0); + if (r < 0) + log_debug_errno(r, "PR_SET_MM_ARG_END failed, proceeding without: %m"); } can_do = true; @@ -182,6 +186,7 @@ static int update_argv(const char name[], size_t l) { int rename_process_full(const char *comm, const char *invocation) { bool truncated = false; + int r; /* This is a like a poor man's setproctitle(). It changes the comm field by the name specified by * 'comm', and changes argv[0] and the glibc's internally used names of the process @@ -204,8 +209,9 @@ int rename_process_full(const char *comm, const char *invocation) { /* First step, change the comm field. The main thread's comm is identical to the process comm. This means we * can use PR_SET_NAME, which sets the thread name for the calling thread. */ - if (prctl(PR_SET_NAME, comm) < 0) - log_debug_errno(errno, "PR_SET_NAME failed: %m"); + r = proc_set_comm(comm); + if (r < 0) + log_debug_errno(r, "PR_SET_NAME failed: %m"); if (l >= TASK_COMM_LEN) /* Linux userspace process names can be 15 chars at max */ truncated = true; diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c index 29434dc2ea..18942d4c36 100644 --- a/src/basic/capability-util.c +++ b/src/basic/capability-util.c @@ -2,7 +2,7 @@ #include #include -#include +#include /* IWYU pragma: keep */ #include #include @@ -100,18 +100,18 @@ unsigned cap_last_cap(void) { /* Fall back to syscall-probing for pre linux-3.2, or where /proc/ is not mounted */ unsigned long p = (unsigned long) MIN(CAP_LAST_CAP, CAP_LIMIT); - if (prctl(PR_CAPBSET_READ, p) < 0) { + if (prctl_safe(PR_CAPBSET_READ, p, 0, 0, 0) < 0) { /* Hmm, look downwards, until we find one that works */ for (p--; p > 0; p--) - if (prctl(PR_CAPBSET_READ, p) >= 0) + if (prctl_safe(PR_CAPBSET_READ, p, 0, 0, 0) >= 0) break; } else { /* Hmm, look upwards, until we find one that doesn't work */ for (; p < CAP_LIMIT; p++) - if (prctl(PR_CAPBSET_READ, p+1) < 0) + if (prctl_safe(PR_CAPBSET_READ, p+1, 0, 0, 0) < 0) break; } @@ -154,7 +154,10 @@ int capability_ambient_set_apply(uint64_t set, bool also_inherit) { if (!BIT_SET(set, i)) continue; - if (prctl(PR_CAPBSET_READ, (unsigned long) i) != 1) { + r = prctl_safe(PR_CAPBSET_READ, i, 0, 0, 0); + if (r < 0) + return r; + if (r != 1) { log_debug("Ambient capability %s requested but missing from bounding set, suppressing automatically.", capability_to_name(i)); CLEAR_BIT(set, i); @@ -180,16 +183,19 @@ int capability_ambient_set_apply(uint64_t set, bool also_inherit) { for (unsigned i = 0; i <= cap_last_cap(); i++) if (BIT_SET(set, i)) { /* Add the capability to the ambient set. */ - if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0) - return -errno; + r = prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0); + if (r < 0) + return r; } else { /* Drop the capability so we don't inherit capabilities we didn't ask for. */ - r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0); + r = prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0); if (r < 0) - return -errno; - if (r > 0) - if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, i, 0, 0) < 0) - return -errno; + return r; + if (r > 0) { + r = prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, i, 0, 0); + if (r < 0) + return r; + } } return 0; @@ -241,13 +247,12 @@ int capability_bounding_set_drop(uint64_t keep, bool right_now) { continue; /* Drop it from the bounding set */ - if (prctl(PR_CAPBSET_DROP, i) < 0) { - r = -errno; - + r = prctl_safe(PR_CAPBSET_DROP, i, 0, 0, 0); + if (r < 0) { /* If dropping the capability failed, let's see if we didn't have it in the first * place. If so, continue anyway, as dropping a capability we didn't have in the * first place doesn't really matter anyway. */ - if (prctl(PR_CAPBSET_READ, i) != 0) + if (prctl_safe(PR_CAPBSET_READ, i, 0, 0, 0) != 0) goto finish; } @@ -332,14 +337,16 @@ int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) { /* Ensure we keep the permitted caps across the setresuid(). Note that we do this even if we actually * don't want to keep any capabilities, since we want to be able to drop them from the bounding set * too, and we can only do that if we have capabilities. */ - if (prctl(PR_SET_KEEPCAPS, 1) < 0) - return log_error_errno(errno, "Failed to enable keep capabilities flag: %m"); + r = prctl_safe(PR_SET_KEEPCAPS, 1, 0, 0, 0); + if (r < 0) + return log_error_errno(r, "Failed to enable keep capabilities flag: %m"); if (setresuid(uid, uid, uid) < 0) return log_error_errno(errno, "Failed to change user ID: %m"); - if (prctl(PR_SET_KEEPCAPS, 0) < 0) - return log_error_errno(errno, "Failed to disable keep capabilities flag: %m"); + r = prctl_safe(PR_SET_KEEPCAPS, 0, 0, 0, 0); + if (r < 0) + return log_error_errno(r, "Failed to disable keep capabilities flag: %m"); /* Drop all caps from the bounding set (as well as the inheritable/permitted/effective sets), except * the ones we want to keep */ @@ -404,7 +411,7 @@ bool capability_quintet_mangle(CapabilityQuintet *q) { if (!BIT_SET(combined, i)) continue; - if (prctl(PR_CAPBSET_READ, (unsigned long) i) > 0) + if (prctl_safe(PR_CAPBSET_READ, i, 0, 0, 0) > 0) continue; SET_BIT(drop, i); @@ -515,9 +522,9 @@ int capability_get_ambient(uint64_t *ret) { assert(ret); for (unsigned i = 0; i <= cap_last_cap(); i++) { - r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0); + r = prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0); if (r < 0) - return -errno; + return r; if (r > 0) SET_BIT(a, i); } diff --git a/src/basic/memfd-util.c b/src/basic/memfd-util.c index 3257c1b9dd..54fecd9bdc 100644 --- a/src/basic/memfd-util.c +++ b/src/basic/memfd-util.c @@ -1,8 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include #include -#include #include #include @@ -10,8 +8,8 @@ #include "errno-util.h" #include "fd-util.h" #include "memfd-util.h" +#include "process-util.h" #include "string-util.h" -#include "utf8.h" int memfd_create_wrapper(const char *name, unsigned mode) { unsigned mode_compat; @@ -36,26 +34,23 @@ int memfd_create_wrapper(const char *name, unsigned mode) { int memfd_new_full(const char *name, unsigned extra_flags) { _cleanup_free_ char *g = NULL; + int r; if (!name) { - char pr[TASK_COMM_LEN] = {}; /* If no name is specified we generate one. We include * a hint indicating our library implementation, and * add the thread name to it */ - assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0); + _cleanup_free_ char *comm = NULL; + r = pid_get_comm(/* pid= */ 0, &comm); + if (r < 0) + return r; - if (isempty(pr)) + if (isempty(comm)) name = "sd"; else { - _cleanup_free_ char *e = NULL; - - e = utf8_escape_invalid(pr); - if (!e) - return -ENOMEM; - - g = strjoin("sd-", e); + g = strjoin("sd-", comm); if (!g) return -ENOMEM; diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 14e58e21eb..ab563c5105 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -104,8 +104,9 @@ int pid_get_comm(pid_t pid, char **ret) { if (!comm) return -ENOMEM; - if (prctl(PR_GET_NAME, comm) < 0) - return -errno; + r = prctl_safe(PR_GET_NAME, (unsigned long) comm, 0, 0, 0); + if (r < 0) + return r; } else { const char *p; @@ -1572,11 +1573,13 @@ int pidref_safe_fork_full( if (!FLAGS_SET(flags, FORK_ALLOW_DLOPEN)) block_dlopen(); - if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) - if (prctl(PR_SET_PDEATHSIG, fork_flags_to_signal(flags)) < 0) { - log_full_errno(prio, errno, "Failed to set death signal: %m"); + if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) { + r = prctl_safe(PR_SET_PDEATHSIG, fork_flags_to_signal(flags), 0, 0, 0); + if (r < 0) { + log_full_errno(prio, r, "Failed to set death signal: %m"); _exit(EXIT_FAILURE); } + } if (flags & FORK_RESET_SIGNALS) { r = reset_all_signal_handlers(); @@ -1978,7 +1981,7 @@ int get_process_threads(pid_t pid) { } int is_reaper_process(void) { - int b = 0; + int b = 0, r; /* Checks if we are running in a reaper process, i.e. if we are expected to deal with processes * reparented to us. This simply checks if we are PID 1 or if PR_SET_CHILD_SUBREAPER was called. */ @@ -1986,13 +1989,15 @@ int is_reaper_process(void) { if (getpid_cached() == 1) return true; - if (prctl(PR_GET_CHILD_SUBREAPER, (unsigned long) &b, 0UL, 0UL, 0UL) < 0) - return -errno; + r = prctl_safe(PR_GET_CHILD_SUBREAPER, (unsigned long) &b, 0, 0, 0); + if (r < 0) + return r; return b != 0; } int make_reaper_process(bool b) { + int r; if (getpid_cached() == 1) { @@ -2002,10 +2007,9 @@ int make_reaper_process(bool b) { return 0; } - /* Some prctl()s insist that all 5 arguments are specified, others do not. Let's always specify all, - * to avoid any ambiguities */ - if (prctl(PR_SET_CHILD_SUBREAPER, (unsigned long) b, 0UL, 0UL, 0UL) < 0) - return -errno; + r = prctl_safe(PR_SET_CHILD_SUBREAPER, b, 0, 0, 0); + if (r < 0) + return r; return 0; } @@ -2276,3 +2280,33 @@ int read_errno(int errno_fd) { return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received positive errno from child, refusing: %d", r); } + +int prctl_safe(int op, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { + + /* prctl(2) is a bit messy: it's a variadic function, defined with "unsigned long" arguments. This + * means that unless people explicitly cast it's quite likely they end up passing a shorter type even + * though unsigned long is required. And most of the time it might even kind of work, but not + * always. Moreover, some calls insist on all unused arguments being zeroed out, others don't + * care. Let's define this wrapper to enforce the right types, and that all arguments are always + * passed, to avoid this confusion. */ + + return RET_NERRNO(prctl(op, arg2, arg3, arg4, arg5)); +} + +int proc_set_comm(const char *comm) { + return prctl_safe(PR_SET_NAME, (unsigned long) comm, 0, 0, 0); +} + +int proc_set_nnp(void) { + return prctl_safe(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); +} + +nsec_t proc_get_timerslack(void) { + int r; + + r = prctl_safe(PR_GET_TIMERSLACK, 0, 0, 0, 0); + if (r < 0) + return NSEC_INFINITY; + + return r; +} diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 9d16055d5e..7adb94e8b0 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -255,3 +255,9 @@ int safe_mlockall(int flags); _noreturn_ void report_errno_and_exit(int errno_fd, int error); int read_errno(int errno_fd); + +int prctl_safe(int op, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); + +int proc_set_comm(const char *comm); +int proc_set_nnp(void); +nsec_t proc_get_timerslack(void); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 4b584038ba..24f0897da9 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include #include #include "alloc-util.h" @@ -66,7 +65,7 @@ static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_version, "s", GIT_VERSION); static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_features, "s", systemd_features); static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_architecture, "s", architecture_to_string(uname_architecture())); static BUS_DEFINE_PROPERTY_GET2(property_get_system_state, "s", Manager, manager_state, manager_state_to_string); -static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_timer_slack_nsec, "t", (uint64_t) prctl(PR_GET_TIMERSLACK)); +static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_timer_slack_nsec, "t", proc_get_timerslack()); static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "u", Hashmap *, hashmap_size); static BUS_DEFINE_PROPERTY_GET_REF(property_get_set_size, "u", Set *, set_size); static BUS_DEFINE_PROPERTY_GET(property_get_default_timeout_abort_usec, "t", Manager, manager_default_timeout_abort_usec); diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index b232cd015c..0faedf3dc1 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include @@ -983,19 +983,20 @@ static int enforce_groups(gid_t gid, const gid_t *supplementary_gids, int ngids) static int set_securebits(unsigned bits, unsigned mask) { unsigned applied; - int current; + int current, r; - current = prctl(PR_GET_SECUREBITS); + current = prctl_safe(PR_GET_SECUREBITS, 0, 0, 0, 0); if (current < 0) - return -errno; + return current; /* Clear all securebits defined in mask and set bits */ applied = ((unsigned) current & ~mask) | bits; if ((unsigned) current == applied) return 0; - if (prctl(PR_SET_SECUREBITS, applied) < 0) - return -errno; + r = prctl_safe(PR_SET_SECUREBITS, applied, 0, 0, 0); + if (r < 0) + return r; return 1; } @@ -1408,7 +1409,8 @@ static int setup_pam( /* Wait until our parent died. This will only work if the above setresuid() succeeds, * otherwise the kernel will not allow unprivileged parents kill their privileged children * this way. We rely on the control groups kill logic to do the rest for us. */ - if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + r = prctl_safe(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); + if (r < 0) goto child_finish; /* Tell the parent that our setup is done. This is especially important regarding dropping @@ -1714,13 +1716,13 @@ static int apply_memory_deny_write_execute(const ExecContext *c, const ExecParam return 0; /* use prctl() if kernel supports it (6.3) */ - r = prctl(PR_SET_MDWE, PR_MDWE_REFUSE_EXEC_GAIN, 0, 0, 0); + r = prctl_safe(PR_SET_MDWE, PR_MDWE_REFUSE_EXEC_GAIN, 0, 0, 0); if (r == 0) { log_debug("Enabled MemoryDenyWriteExecute= with PR_SET_MDWE"); return 0; } - if (r < 0 && errno != EINVAL) - return log_debug_errno(errno, "Failed to enable MemoryDenyWriteExecute= with PR_SET_MDWE: %m"); + if (r < 0 && r != -EINVAL) + return log_debug_errno(r, "Failed to enable MemoryDenyWriteExecute= with PR_SET_MDWE: %m"); /* else use seccomp */ log_debug("Kernel doesn't support PR_SET_MDWE: falling back to seccomp"); @@ -4850,15 +4852,15 @@ static int set_memory_thp(ExecMemoryTHP thp) { return 0; case EXEC_MEMORY_THP_DISABLE: - r = RET_NERRNO(prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0)); + r = prctl_safe(PR_SET_THP_DISABLE, 1, 0, 0, 0); break; case EXEC_MEMORY_THP_MADVISE: - r = RET_NERRNO(prctl(PR_SET_THP_DISABLE, 1, PR_THP_DISABLE_EXCEPT_ADVISED, 0, 0)); + r = prctl_safe(PR_SET_THP_DISABLE, 1, PR_THP_DISABLE_EXCEPT_ADVISED, 0, 0); break; case EXEC_MEMORY_THP_SYSTEM: - r = RET_NERRNO(prctl(PR_SET_THP_DISABLE, 0, 0, 0, 0)); + r = prctl_safe(PR_SET_THP_DISABLE, 0, 0, 0, 0); break; default: @@ -5658,11 +5660,13 @@ int exec_invoke( return log_error_errno(errno, "Failed to set up IO scheduling priority: %m"); } - if (context->timer_slack_nsec != NSEC_INFINITY) - if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) { + if (context->timer_slack_nsec != NSEC_INFINITY) { + r = prctl_safe(PR_SET_TIMERSLACK, context->timer_slack_nsec, 0, 0, 0); + if (r < 0) { *exit_status = EXIT_TIMERSLACK; - return log_error_errno(errno, "Failed to set up timer slack: %m"); + return log_error_errno(r, "Failed to set up timer slack: %m"); } + } if (context->personality != PERSONALITY_INVALID) { r = safe_personality(context->personality); @@ -5672,15 +5676,17 @@ int exec_invoke( } } - if (context->memory_ksm >= 0) - if (prctl(PR_SET_MEMORY_MERGE, context->memory_ksm, 0, 0, 0) < 0) { - if (ERRNO_IS_NOT_SUPPORTED(errno)) - log_debug_errno(errno, "KSM support not available, ignoring."); + if (context->memory_ksm >= 0) { + r = prctl_safe(PR_SET_MEMORY_MERGE, context->memory_ksm, 0, 0, 0); + if (r < 0) { + if (ERRNO_IS_NOT_SUPPORTED(r)) + log_debug_errno(r, "KSM support not available, ignoring."); else { *exit_status = EXIT_KSM; - return log_error_errno(errno, "Failed to set KSM: %m"); + return log_error_errno(r, "Failed to set KSM: %m"); } } + } r = set_memory_thp(context->memory_thp); if (r == -EOPNOTSUPP) @@ -6321,9 +6327,10 @@ int exec_invoke( seccomp_allows_drop_privileges(context)) { keep_seccomp_privileges = true; - if (prctl(PR_SET_KEEPCAPS, 1) < 0) { + r = prctl_safe(PR_SET_KEEPCAPS, 1, 0, 0, 0); + if (r < 0) { *exit_status = EXIT_USER; - return log_error_errno(errno, "Failed to enable keep capabilities flag: %m"); + return log_error_errno(r, "Failed to enable keep capabilities flag: %m"); } /* Save the current bounding set so we can restore it after applying the seccomp @@ -6456,7 +6463,8 @@ int exec_invoke( /* PR_GET_SECUREBITS is not privileged, while PR_SET_SECUREBITS is. So to suppress potential * EPERMs we'll try not to call PR_SET_SECUREBITS unless necessary. Setting securebits * requires CAP_SETPCAP. */ - if (prctl(PR_GET_SECUREBITS) != secure_bits) { + r = prctl_safe(PR_GET_SECUREBITS, 0, 0, 0, 0); + if (r != secure_bits) { /* CAP_SETPCAP is required to set securebits. This capability is raised into the * effective set here. * @@ -6473,17 +6481,21 @@ int exec_invoke( *exit_status = EXIT_CAPABILITIES; return log_error_errno(r, "Failed to gain CAP_SETPCAP for setting secure bits"); } - if (prctl(PR_SET_SECUREBITS, secure_bits) < 0) { + + r = prctl_safe(PR_SET_SECUREBITS, secure_bits, 0, 0, 0); + if (r < 0) { *exit_status = EXIT_SECUREBITS; - return log_error_errno(errno, "Failed to set process secure bits: %m"); + return log_error_errno(r, "Failed to set process secure bits: %m"); } } - if (context_has_no_new_privileges(context)) - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { + if (context_has_no_new_privileges(context)) { + r = proc_set_nnp(); + if (r < 0) { *exit_status = EXIT_NO_NEW_PRIVILEGES; - return log_error_errno(errno, "Failed to disable new privileges: %m"); + return log_error_errno(r, "Failed to disable new privileges: %m"); } + } #if HAVE_SECCOMP r = apply_address_families(context, params); @@ -6613,9 +6625,10 @@ int exec_invoke( } } - if (prctl(PR_SET_KEEPCAPS, 0) < 0) { + r = prctl_safe(PR_SET_KEEPCAPS, 0, 0, 0, 0); + if (r < 0) { *exit_status = EXIT_USER; - return log_error_errno(errno, "Failed to drop keep capabilities flag: %m"); + return log_error_errno(r, "Failed to drop keep capabilities flag: %m"); } } #endif diff --git a/src/core/execute.c b/src/core/execute.c index f581b5c120..8eb505d4fb 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include #include @@ -1972,9 +1972,11 @@ uint64_t exec_context_get_timer_slack_nsec(const ExecContext *c) { if (c->timer_slack_nsec != NSEC_INFINITY) return c->timer_slack_nsec; - r = prctl(PR_GET_TIMERSLACK); - if (r < 0) + r = prctl_safe(PR_GET_TIMERSLACK, 0, 0, 0, 0); + if (r < 0) { log_debug_errno(r, "Failed to get timer slack, ignoring: %m"); + return 0; + } return (uint64_t) MAX(r, 0); } diff --git a/src/core/main.c b/src/core/main.c index 2b4036381c..c952472e73 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include @@ -2739,9 +2739,10 @@ static int initialize_runtime( } if (arg_no_new_privs) { - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { + r = proc_set_nnp(); + if (r < 0) { *ret_error_message = "Failed to disable new privileges"; - return log_struct_errno(LOG_EMERG, errno, + return log_struct_errno(LOG_EMERG, r, LOG_MESSAGE("Failed to disable new privileges: %m"), LOG_MESSAGE_ID(SD_MESSAGE_CORE_DISABLE_PRIVILEGES_STR)); } @@ -2794,9 +2795,11 @@ static int initialize_runtime( if (r < 0) log_warning_errno(r, "Failed to reset ambient capability set, ignoring: %m"); - if (arg_timer_slack_nsec != NSEC_INFINITY) - if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0) - log_warning_errno(errno, "Failed to adjust timer slack, ignoring: %m"); + if (arg_timer_slack_nsec != NSEC_INFINITY) { + r = prctl_safe(PR_SET_TIMERSLACK, arg_timer_slack_nsec, 0, 0, 0); + if (r < 0) + log_warning_errno(r, "Failed to adjust timer slack, ignoring: %m"); + } if (arg_syscall_archs) { r = enforce_syscall_archs(arg_syscall_archs); @@ -3567,7 +3570,7 @@ static int run_systemd(int argc, char *argv[]) { * reexecution we are then called 'systemd'. That is confusing, hence let's call us systemd * right-away. */ program_invocation_short_name = systemd; - (void) prctl(PR_SET_NAME, systemd); + (void) proc_set_comm(systemd); /* Save the original command line */ save_argc_argv(argc, argv); diff --git a/src/core/varlink-manager.c b/src/core/varlink-manager.c index b48d212475..6855ee7553 100644 --- a/src/core/varlink-manager.c +++ b/src/core/varlink-manager.c @@ -1,7 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include - #include "sd-bus.h" #include "sd-varlink.h" @@ -18,6 +16,7 @@ #include "manager.h" #include "path-util.h" #include "pidref.h" +#include "process-util.h" #include "selinux-access.h" #include "set.h" #include "strv.h" @@ -118,7 +117,7 @@ static int manager_context_build_json(sd_json_variant **ret, const char *name, v JSON_BUILD_PAIR_FINITE_USEC("RuntimeWatchdogPreUSec", manager_get_watchdog(m, WATCHDOG_PRETIMEOUT)), JSON_BUILD_PAIR_STRING_NON_EMPTY("RuntimeWatchdogPreGovernor", m->watchdog_pretimeout_governor), JSON_BUILD_PAIR_STRING_NON_EMPTY("WatchdogDevice", watchdog_get_device()), - JSON_BUILD_PAIR_FINITE_USEC("TimerSlackNSec", (uint64_t) prctl(PR_GET_TIMERSLACK)), + JSON_BUILD_PAIR_FINITE_USEC("TimerSlackNSec", proc_get_timerslack()), JSON_BUILD_PAIR_ENUM("DefaultOOMPolicy", oom_policy_to_string(m->defaults.oom_policy)), SD_JSON_BUILD_PAIR_INTEGER("DefaultOOMScoreAdjust", m->defaults.oom_score_adjust), SD_JSON_BUILD_PAIR_BOOLEAN("DefaultRestrictSUIDSGID", m->defaults.restrict_suid_sgid), diff --git a/src/import/import-common.c b/src/import/import-common.c index 41e945f1fb..0168311204 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include #include #include "sd-event.h" @@ -81,8 +80,9 @@ int import_fork_tar_x(int tree_fd, int userns_fd, PidRef *ret_pid) { if (r < 0) log_debug_errno(r, "Failed to drop capabilities, ignoring: %m"); - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) - log_warning_errno(errno, "Failed to enable PR_SET_NO_NEW_PRIVS, ignoring: %m"); + r = proc_set_nnp(); + if (r < 0) + log_warning_errno(r, "Failed to enable PR_SET_NO_NEW_PRIVS, ignoring: %m"); if (tar_x(pipefd[0], tree_fd, flags) < 0) _exit(EXIT_FAILURE); @@ -141,8 +141,9 @@ int import_fork_tar_c(int tree_fd, int userns_fd, PidRef *ret_pid) { if (r < 0) log_debug_errno(r, "Failed to drop capabilities, ignoring: %m"); - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) - log_warning_errno(errno, "Failed to enable PR_SET_NO_NEW_PRIVS, ignoring: %m"); + r = proc_set_nnp(); + if (r < 0) + log_warning_errno(r, "Failed to enable PR_SET_NO_NEW_PRIVS, ignoring: %m"); if (tar_c(tree_fd, pipefd[1], /* filename= */ NULL, flags) < 0) _exit(EXIT_FAILURE); diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c index 6a64aea511..2ed7bcffd4 100644 --- a/src/nspawn/nspawn-stub-pid1.c +++ b/src/nspawn/nspawn-stub-pid1.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include +#include /* IWYU pragma: keep */ #include #include #include @@ -18,15 +18,18 @@ static int reset_environ(const char *new_environment, size_t length) { unsigned long start, end; + int r; start = (unsigned long) new_environment; end = start + length; - if (prctl(PR_SET_MM, PR_SET_MM_ENV_START, start, 0, 0) < 0) - return -errno; + r = prctl_safe(PR_SET_MM, PR_SET_MM_ENV_START, start, 0, 0); + if (r < 0) + return r; - if (prctl(PR_SET_MM, PR_SET_MM_ENV_END, end, 0, 0) < 0) - return -errno; + r = prctl_safe(PR_SET_MM, PR_SET_MM_ENV_END, end, 0, 0); + if (r < 0) + return r; return 0; } diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index f4d85c0418..a2e0d31de7 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include @@ -79,6 +79,7 @@ #include "namespace-util.h" #include "netlink-internal.h" #include "notify-recv.h" +#include "nspawn.h" #include "nspawn-bind-user.h" #include "nspawn-cgroup.h" #include "nspawn-expose-ports.h" @@ -90,14 +91,13 @@ #include "nspawn-settings.h" #include "nspawn-setuid.h" #include "nspawn-stub-pid1.h" -#include "nspawn.h" #include "nsresource.h" -#include "os-util.h" -#include "parse-helpers.h" -#include "osc-context.h" #include "options.h" +#include "os-util.h" +#include "osc-context.h" #include "pager.h" #include "parse-argument.h" +#include "parse-helpers.h" #include "parse-util.h" #include "path-lookup.h" #include "path-util.h" @@ -3579,8 +3579,9 @@ static int inner_child( /* Make sure we keep the caps across the uid/gid dropping, so that we can retain some selected caps * if we need to later on. */ - if (prctl(PR_SET_KEEPCAPS, 1) < 0) - return log_error_errno(errno, "Failed to set PR_SET_KEEPCAPS: %m"); + r = prctl_safe(PR_SET_KEEPCAPS, 1, 0, 0, 0); + if (r < 0) + return log_error_errno(r, "Failed to set PR_SET_KEEPCAPS: %m"); if (uid_is_valid(arg_uid) || gid_is_valid(arg_gid)) r = change_uid_gid_raw(arg_uid, arg_gid, arg_supplementary_gids, arg_n_supplementary_gids, arg_console_mode != CONSOLE_PIPE); @@ -3593,9 +3594,11 @@ static int inner_child( if (r < 0) return log_error_errno(r, "Dropping capabilities failed: %m"); - if (arg_no_new_privileges) - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) - return log_error_errno(errno, "Failed to disable new privileges: %m"); + if (arg_no_new_privileges) { + r = proc_set_nnp(); + if (r < 0) + return log_error_errno(r, "Failed to disable new privileges: %m"); + } /* LXC sets container=lxc, so follow the scheme here */ envp[n_env++] = strjoina("container=", arg_container_service_name); @@ -3961,8 +3964,9 @@ static int outer_child( if (r < 0) log_debug_errno(r, "Failed to read os-release from host for container, ignoring: %m"); - if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) - return log_error_errno(errno, "PR_SET_PDEATHSIG failed: %m"); + r = prctl_safe(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); + if (r < 0) + return log_error_errno(r, "PR_SET_PDEATHSIG failed: %m"); r = reset_audit_loginuid(); if (r < 0) diff --git a/src/shared/async.c b/src/shared/async.c index f4843deb78..7aefe62bb1 100644 --- a/src/shared/async.c +++ b/src/shared/async.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include #include #include @@ -64,7 +63,7 @@ int asynchronous_fsync(int fd, PidRef *ret_pid) { static int close_func(void *p) { unsigned v = PTR_TO_UINT(p); - (void) prctl(PR_SET_NAME, (unsigned long*) "(sd-close)"); + (void) proc_set_comm("(sd-close)"); /* Note: 💣 This function is invoked in a child process created via glibc's clone() wrapper. In such * children memory allocation is not allowed, since glibc does not release malloc mutexes in diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c index d979de1776..894cf3869b 100644 --- a/src/shared/coredump-util.c +++ b/src/shared/coredump-util.c @@ -1,15 +1,15 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include +#include /* IWYU pragma: keep */ #include "alloc-util.h" #include "coredump-util.h" -#include "errno-util.h" #include "extract-word.h" #include "fileio.h" #include "log.h" #include "parse-util.h" +#include "process-util.h" #include "stdio-util.h" #include "string-table.h" #include "string-util.h" @@ -18,7 +18,7 @@ int set_dumpable(SuidDumpMode mode) { /* Cast mode explicitly to long, because prctl wants longs but is varargs. */ - return RET_NERRNO(prctl(PR_SET_DUMPABLE, (long) mode)); + return prctl_safe(PR_SET_DUMPABLE, mode, 0, 0, 0); } static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = { diff --git a/src/shared/nsresource.c b/src/shared/nsresource.c index b783cb80b7..5aa87c48b5 100644 --- a/src/shared/nsresource.c +++ b/src/shared/nsresource.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include #include "sd-varlink.h" @@ -25,13 +24,15 @@ assert_cc(TASK_COMM_LEN == NAMESPACE_NAME_MAX); static int make_pid_name(char **ret) { - char comm[TASK_COMM_LEN]; static uint64_t counter = 0; + int r; assert(ret); - if (prctl(PR_GET_NAME, comm) < 0) - return -errno; + _cleanup_free_ char *comm = NULL; + r = pid_get_comm(0, &comm); + if (r < 0) + return r; char spid[DECIMAL_STR_MAX(pid_t)]; xsprintf(spid, PID_FMT, getpid_cached()); diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 2a8995666f..cf65e1ca0e 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include @@ -301,12 +301,11 @@ int seccomp_init_for_arch(scmp_filter_ctx *ret, uint32_t arch, uint32_t default_ } static bool is_basic_seccomp_available(void) { - return prctl(PR_GET_SECCOMP, 0, 0, 0, 0) >= 0; + return prctl_safe(PR_GET_SECCOMP, 0, 0, 0, 0) >= 0; } static bool is_seccomp_filter_available(void) { - return prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0) < 0 && - errno == EFAULT; + return prctl_safe(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0, 0, 0) == -EFAULT; } bool is_seccomp_available(void) { diff --git a/src/test/test-capability-util.c b/src/test/test-capability-util.c index cd536dd4cb..ccf73d2bbf 100644 --- a/src/test/test-capability-util.c +++ b/src/test/test-capability-util.c @@ -3,10 +3,9 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include -#include "pidref.h" #define TEST_CAPABILITY_C @@ -17,6 +16,7 @@ #include "fd-util.h" #include "fileio.h" #include "parse-util.h" +#include "pidref.h" #include "process-util.h" #include "tests.h" @@ -64,13 +64,13 @@ TEST(last_cap_file) { TEST(last_cap_probe) { unsigned long p = (unsigned long)CAP_LAST_CAP; - if (prctl(PR_CAPBSET_READ, p) < 0) { + if (prctl_safe(PR_CAPBSET_READ, p, 0, 0, 0) < 0) { for (p--; p > 0; p--) - if (prctl(PR_CAPBSET_READ, p) >= 0) + if (prctl_safe(PR_CAPBSET_READ, p, 0, 0, 0) >= 0) break; } else { for (;; p++) - if (prctl(PR_CAPBSET_READ, p+1) < 0) + if (prctl_safe(PR_CAPBSET_READ, p+1, 0, 0, 0) < 0) break; } @@ -180,17 +180,17 @@ TEST(have_effective_cap) { } static void test_apply_ambient_caps_impl(void) { - ASSERT_OK_EQ_ERRNO(prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0), 0); + ASSERT_OK_ZERO(prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0)); ASSERT_OK(capability_ambient_set_apply(UINT64_C(1) << CAP_CHOWN, /* also_inherit= */ true)); ASSERT_OK_POSITIVE(have_inheritable_cap(CAP_CHOWN)); - ASSERT_OK_EQ_ERRNO(prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0), 1); + ASSERT_OK_EQ(prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0), 1); ASSERT_OK(capability_ambient_set_apply(0, /* also_inherit= */ true)); ASSERT_OK_ZERO(have_inheritable_cap(CAP_CHOWN)); - ASSERT_OK_EQ_ERRNO(prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0), 0); + ASSERT_OK_ZERO(prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0)); } TEST(apply_ambient_caps) { @@ -234,10 +234,10 @@ TEST(capability_get_ambient) { ASSERT_OK(capability_get_ambient(&c)); - r = prctl(PR_CAPBSET_READ, CAP_MKNOD); + r = prctl_safe(PR_CAPBSET_READ, CAP_MKNOD, 0, 0, 0); if (r <= 0) return (void) log_tests_skipped("Lacking CAP_MKNOD, skipping getambient test."); - r = prctl(PR_CAPBSET_READ, CAP_LINUX_IMMUTABLE); + r = prctl_safe(PR_CAPBSET_READ, CAP_LINUX_IMMUTABLE, 0, 0, 0); if (r <= 0) return (void) log_tests_skipped("Lacking CAP_LINUX_IMMUTABLE, skipping getambient test."); @@ -303,6 +303,8 @@ TEST(pidref_get_capability) { } static int intro(void) { + int r; + /* Try to set up nobody user/ambient caps for tests that need them. * Not finding nobody is non-fatal — those tests will skip themselves. */ struct passwd *nobody = getpwnam(NOBODY_USER_NAME); @@ -311,10 +313,10 @@ static int intro(void) { test_gid = nobody->pw_gid; } - int r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0); + r = prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0); /* There's support for PR_CAP_AMBIENT if the prctl() call succeeded or error code was something else * than EINVAL. The EINVAL check should be good enough to rule out false positives. */ - run_ambient = r >= 0 || errno != EINVAL; + run_ambient = r >= 0 || r != -EINVAL; if (getuid() == 0) show_capabilities(); diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 8206452f4c..9725fa0bf5 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include "sd-event.h" @@ -1195,8 +1195,8 @@ static void test_exec_ambientcapabilities(Manager *m) { * the tests only if that's the case. Clearing all ambient * capabilities is fine, since we are expecting them to be unset * in the first place for the tests. */ - r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0); - if (r < 0 && IN_SET(errno, EINVAL, EOPNOTSUPP, ENOSYS)) { + r = prctl_safe(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0); + if (r < 0 && IN_SET(r, -EINVAL, -EOPNOTSUPP, -ENOSYS)) { log_notice("Skipping %s, the kernel does not support ambient capabilities", __func__); return; } diff --git a/src/test/test-namespace.c b/src/test/test-namespace.c index 41c67a3cf9..b9f4e35f2e 100644 --- a/src/test/test-namespace.c +++ b/src/test/test-namespace.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include #include @@ -363,7 +363,7 @@ TEST(process_is_owned_by_uid) { ASSERT_OK(fully_set_uid_gid(1, 1, NULL, 0)); /* After successfully changing id/gid DEATHSIG is reset, so it has to be set again */ - ASSERT_OK_ERRNO(prctl(PR_SET_PDEATHSIG, SIGKILL)); + ASSERT_OK(prctl_safe(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)); ASSERT_OK_EQ_ERRNO(write(p[1], &(const char[]) { 'x' }, 1), 1); p[1] = safe_close(p[1]); @@ -401,7 +401,7 @@ TEST(process_is_owned_by_uid) { ASSERT_OK(reset_uid_gid()); /* After successfully changing id/gid DEATHSIG is reset, so it has to be set again */ - ASSERT_OK_ERRNO(prctl(PR_SET_PDEATHSIG, SIGKILL)); + ASSERT_OK(prctl_safe(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)); ASSERT_OK_EQ_ERRNO(write(p[1], &(const char[]) { 'x' }, 1), 1); p[1] = safe_close(p[1]); diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index 63458117cb..e1d16165ba 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -175,7 +174,7 @@ static void test_pid_get_comm_escape_one(const char *input, const char *output) log_debug("input: <%s> — output: <%s>", input, output); - ASSERT_OK_ERRNO(prctl(PR_SET_NAME, input)); + ASSERT_OK(proc_set_comm(input)); ASSERT_OK(pid_get_comm(0, &n)); log_debug("got: <%s>", n); @@ -199,7 +198,7 @@ TEST(pid_get_comm_escape) { test_pid_get_comm_escape_one("xxxxäöüß", "xxxx\\303\\244\\303\\266\\303\\274\\303\\237"); test_pid_get_comm_escape_one("xxxxxäöüß", "xxxxx\\303\\244\\303\\266\\303\\274\\303\\237"); - ASSERT_OK_ERRNO(prctl(PR_SET_NAME, saved)); + ASSERT_OK(proc_set_comm(saved)); } TEST(pid_is_unwaited) { @@ -314,7 +313,7 @@ TEST(pid_get_cmdline_harder) { ASSERT_OK_ERRNO(unlink(path)); - ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "testa")); + ASSERT_OK(proc_set_comm("testa")); ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT); @@ -477,7 +476,7 @@ TEST(pid_get_cmdline_harder) { args = strv_free(args); ASSERT_OK_ERRNO(ftruncate(fd, 0)); - ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "aaaa bbbb cccc")); + ASSERT_OK(proc_set_comm("aaaa bbbb cccc")); ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT); diff --git a/src/test/test-thp.c b/src/test/test-thp.c index 047bd26e89..843c3c8560 100644 --- a/src/test/test-thp.c +++ b/src/test/test-thp.c @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include +#include /* IWYU pragma: keep */ +#include "process-util.h" #include "tests.h" #define PR_THP_DISABLE_NOT_SET 0 @@ -12,7 +13,7 @@ static const char *arg_mode = NULL; static int intro(void) { int r; - r = prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0); + r = prctl_safe(PR_GET_THP_DISABLE, 0, 0, 0, 0); if (streq_ptr(arg_mode, "no-disable")) { /* Test case: THPs should not be disabled */ if (r != PR_THP_DISABLE_NOT_SET) { diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index d57ade56c9..c725ef66a8 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include /* IWYU pragma: keep */ #include #include #include @@ -560,7 +560,7 @@ static int ask_on_this_console(const char *tty, char **arguments, PidRef *ret) { if (r < 0) return r; if (r == 0) { - assert_se(prctl(PR_SET_PDEATHSIG, SIGHUP) >= 0); + assert_se(prctl_safe(PR_SET_PDEATHSIG, SIGHUP, 0, 0, 0) >= 0); STRV_FOREACH(i, arguments) { char *k;