[PATCH v2 0/1] Call prctl(2) with signed long integers, and avoid casts
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Tue Jan 20 13:57:12 GMT 2026
On 12/01/26 11:58, Alejandro Colomar wrote:
> On Wed, Dec 03, 2025 at 11:45:09PM +0100, Alejandro Colomar wrote:
>> Hi!
>>
>> We were discussing some patch for fixing some less-than-ideal calls to
>> prctl(2) in util-linux. I've found similar calls elsewhere too. In the
>> end, prctl(2) is easy to get wrong (or at least not right), because it's
>> not type-safe, by being a variadic function.
>>
>> We were wondering if libc could do something to fix this in every
>> project at the same time, by providing some type-safe wrappers.
>>
>> How about providing a header file like the one below in glibc?
>
> Ping.
>
I don't have a strong opinion, prctl is really being used sporadically and
the kernel keeps adding new functionalities that this header will need to be
always updated.
This does seems to be a very-specific program ABI than a generic one provided
by the libc.
>>
>>
>> Have a lovely night!
>> Alex
>>
>> ---
>> // Copyright 2025, Alejandro Colomar <alx@kernel.org>
>> // SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
>>
>> #include <linux/filter.h>
>> #include <linux/seccomp.h>
>> #include <stdbool.h>
>> #include <stddef.h>
>> #include <stdint.h>
>> #include <sys/prctl.h>
>> #include <sys/types.h>
>>
>> #if !defined(__has_c_attribute)
>> # define __has_c_attribute(x) 0
>> #endif
>> #if __has_attribute(__null_terminated_string_arg__)
>> # define LIBPRCTL_ATTR_STRING(i) __attribute__((__null_terminated_string_arg__(i)))
>> #else
>> # define LIBPRCTL_ATTR_STRING(i)
>> #endif
>> #if __has_attribute(__deprecated__)
>> # define LIBPRCTL_ATTR_DEPRECATED __attribute__((__deprecated__))
>> #else
>> # define LIBPRCTL_ATTR_DEPRECATED
>> #endif
>>
>> _Static_assert(sizeof(long) == sizeof(void *), "");
>> _Static_assert(sizeof(long) == sizeof(size_t), "");
>>
>> static inline int pr_cap_ambient_raise(int64_t cap) {
>> return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (long){cap}, 0L, 0L);
>> }
>> static inline int pr_cap_ambient_lower(int64_t cap) {
>> return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, (long){cap}, 0L, 0L);
>> }
>> static inline int pr_cap_ambient_is_set(int64_t cap) {
>> return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, (long){cap}, 0L,0L);
>> }
>> static inline int pr_cap_ambient_clear_all(void) {
>> return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0L, 0L, 0L);
>> }
>> static inline int pr_capbset_read(int64_t cap) {
>> return prctl(PR_CAPBSET_READ, (long){cap});
>> }
>> static inline int pr_capbset_drop(int64_t cap) {
>> return prctl(PR_CAPBSET_DROP, (long){cap});
>> }
>> static inline int pr_set_child_subreaper(bool set) {
>> return prctl(PR_SET_CHILD_SUBREAPER, (long){set});
>> }
>> static inline int pr_get_child_subreaper(bool *isset)
>> {
>> int ret, x;
>> ret = prctl(PR_GET_CHILD_SUBREAPER, &x);
>> *isset = x;
>> return ret;
>> }
>> static inline int pr_set_dumpable(bool set) {
>> return prctl(PR_SET_DUMPABLE, (long){set});
>> }
>> static inline int pr_get_dumpable(void) {
>> return prctl(PR_GET_DUMPABLE);
>> }
>> static inline int pr_set_endian(int endianness) {
>> return prctl(PR_SET_ENDIAN, (long){endianness});
>> }
>> static inline int pr_get_endian(int *endianness) {
>> return prctl(PR_GET_ENDIAN, endianness);
>> }
>> static inline int pr_set_fp_mode(unsigned int mode) {
>> return prctl(PR_SET_FP_MODE, (unsigned long){mode});
>> }
>> static inline int pr_get_fp_mode(void) {
>> return prctl(PR_GET_FP_MODE);
>> }
>> static inline int pr_set_fpemu(int fpemu) {
>> return prctl(PR_SET_FPEMU, (long){fpemu});
>> }
>> static inline int pr_get_fpemu(int *fpemu) {
>> return prctl(PR_GET_FPEMU, fpemu);
>> }
>> static inline int pr_set_fpexec(int mode) {
>> return prctl(PR_SET_FPEXC, (long){mode});
>> }
>> static inline int pr_get_fpexec(int *mode) {
>> return prctl(PR_GET_FPEXC, mode);
>> }
>> static inline int pr_set_io_flusher(bool set) {
>> return prctl(PR_SET_IO_FLUSHER, (long){set}, 0L, 0L, 0L);
>> }
>> static inline int pr_get_io_flusher(void) {
>> return prctl(PR_GET_IO_FLUSHER, 0L, 0L, 0L, 0L);
>> }
>> static inline int pr_set_keepcaps(bool set) {
>> return prctl(PR_SET_KEEPCAPS, (long){set});
>> }
>> static inline int pr_get_keepcaps(void) {
>> return prctl(PR_GET_KEEPCAPS);
>> }
>> static inline int pr_mce_kill_clear(void) {
>> return prctl(PR_MCE_KILL, PR_MCE_KILL_CLEAR, 0L, 0L, 0L);
>> }
>> static inline int pr_mce_kill_set(int policy) {
>> return prctl(PR_MCE_KILL, PR_MCE_KILL_SET, (long){policy}, 0L, 0L);
>> }
>> static inline int pr_mce_kill_get(void) {
>> return prctl(PR_MCE_KILL_GET, 0L, 0L, 0L, 0L);
>> }
>> static inline int pr_set_mm_start_code(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_START_CODE, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_end_code(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_END_CODE, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_start_data(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_START_DATA, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_end_data(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_END_DATA, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_start_stack(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_START_STACK, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_start_brk(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_START_BRK, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_brk(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_BRK, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_arg_start(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_ARG_START, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_arg_end(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_ARG_END, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_env_start(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_ENV_START, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_env_end(const void *addr) {
>> return prctl(PR_SET_MM, PR_SET_MM_ENV_END, addr, 0L, 0L);
>> }
>> static inline int pr_set_mm_auxv(const void *addr, size_t size) {
>> return prctl(PR_SET_MM, PR_SET_MM_AUXV, addr, size, 0L);
>> }
>> static inline int pr_set_mm_exe_file(int fd) {
>> return prctl(PR_SET_MM, PR_SET_MM_EXE_FILE, (long){fd}, 0L, 0L);
>> }
>> static inline int pr_set_mm_map(struct prctl_mm_map *map)
>> {
>> return prctl(PR_SET_MM, PR_SET_MM_MAP, map,
>> sizeof(struct prctl_mm_map), 0L);
>> }
>> static inline int pr_set_mm_map_size(size_t *size)
>> {
>> int ret;
>> unsigned int x;
>> ret = prctl(PR_SET_MM, PR_SET_MM_MAP_SIZE, &x, 0L, 0L);
>> *size = x;
>> return ret;
>> }
>> LIBPRCTL_ATTR_STRING(3)
>> static inline int
>> pr_set_vma_anon_name(const void *addr, size_t size, const char *name)
>> {
>> return prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, addr, size, name);
>> }
>> LIBPRCTL_ATTR_DEPRECATED
>> static inline int pr_mpx_enable_management(void) {
>> return prctl(PR_MPX_ENABLE_MANAGEMENT, 0L, 0L, 0L, 0L);
>> }
>> LIBPRCTL_ATTR_DEPRECATED
>> static inline int pr_mpx_disable_management(void) {
>> return prctl(PR_MPX_DISABLE_MANAGEMENT, 0L, 0L, 0L, 0L);
>> }
>> LIBPRCTL_ATTR_STRING(1)
>> static inline int pr_set_name(const char *name) {
>> return prctl(PR_SET_NAME, name);
>> }
>> LIBPRCTL_ATTR_STRING(1)
>> static inline int pr_get_name(char name[16]) {
>> return prctl(PR_GET_NAME, name);
>> }
>> static inline int pr_set_no_new_privs(void) {
>> return prctl(PR_SET_NO_NEW_PRIVS, 1L, 0L, 0L, 0L);
>> }
>> static inline int pr_get_no_new_privs(void) {
>> return prctl(PR_GET_NO_NEW_PRIVS, 0L, 0L, 0L, 0L);
>> }
>> static inline int pr_pac_reset_keys(unsigned long keys) {
>> return prctl(PR_PAC_RESET_KEYS, keys, 0L, 0L, 0L);
>> }
>> static inline int pr_set_pdeathsig(int sig) {
>> return prctl(PR_SET_PDEATHSIG, (long){sig});
>> }
>> static inline int pr_get_pdeathsig(int *sig) {
>> return prctl(PR_GET_PDEATHSIG, sig);
>> }
>> static inline int pr_set_ptracer(pid_t pid) {
>> return prctl(PR_SET_PTRACER, (long){pid});
>> }
>> LIBPRCTL_ATTR_DEPRECATED
>> static inline int pr_set_seccomp_mode_strict(void) {
>> return prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
>> }
>> LIBPRCTL_ATTR_DEPRECATED
>> static inline int pr_set_seccomp_mode_filter(const struct sock_fprog *filter) {
>> return prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter);
>> }
>> static inline int pr_get_seccomp(void) {
>> return prctl(PR_GET_SECCOMP);
>> }
>> static inline int pr_set_securebits(unsigned int securebits) {
>> return prctl(PR_SET_SECUREBITS, (unsigned long){securebits});
>> }
>> static inline int pr_get_securebits(void) {
>> return prctl(PR_GET_SECUREBITS);
>> }
>> static inline int pr_get_speculation_ctrl(long misfeature) {
>> return prctl(PR_GET_SPECULATION_CTRL, misfeature, 0L, 0L, 0L);
>> }
>> static inline int pr_set_speculation_ctrl(long misfeature, int ctrl) {
>> return prctl(PR_SET_SPECULATION_CTRL, misfeature, (long){ctrl}, 0L, 0L);
>> }
>> static inline int pr_sve_set_vl(unsigned long val) {
>> return prctl(PR_SVE_SET_VL, val);
>> }
>> static inline int pr_sve_get_vl(void) {
>> return prctl(PR_SVE_GET_VL);
>> }
>> static inline int pr_sys_dispatch_on(size_t off, size_t size, int8_t *sw)
>> {
>> return prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_ON,
>> off, size, sw);
>> }
>> static inline int pr_sys_dispatch_off(void) {
>> return prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,0L,0L,0L);
>> }
>> static inline int pr_set_tagged_addr_ctrl(int mode) {
>> return prctl(PR_SET_TAGGED_ADDR_CTRL, (long){mode}, 0L, 0L, 0L);
>> }
>> static inline int pr_get_tagged_addr_ctrl(void) {
>> return prctl(PR_GET_TAGGED_ADDR_CTRL, 0L, 0L, 0L, 0L);
>> }
>> static inline int pr_task_perf_events_enable(void) {
>> return prctl(PR_TASK_PERF_EVENTS_ENABLE);
>> }
>> static inline int pr_task_perf_events_disable(void) {
>> return prctl(PR_TASK_PERF_EVENTS_DISABLE);
>> }
>> static inline int pr_set_thp_disable(bool set, unsigned int flags)
>> {
>> return prctl(PR_SET_THP_DISABLE, (long){set},
>> (unsigned long){flags}, 0L, 0L);
>> }
>> static inline int pr_get_thp_disable(void) {
>> return prctl(PR_GET_THP_DISABLE, 0L, 0L, 0L, 0L);
>> }
>> static inline int pr_get_tid_address(int **addrp) {
>> return prctl(PR_GET_TID_ADDRESS, addrp);
>> }
>> static inline int pr_set_timerslack(unsigned int slack) {
>> return prctl(PR_SET_TIMERSLACK, (unsigned long){slack});
>> }
>> static inline int pr_get_timerslack(void) {
>> return prctl(PR_GET_TIMERSLACK);
>> }
>> static inline int pr_set_timing(int mode) {
>> return prctl(PR_SET_TIMING, (long){mode});
>> }
>> static inline int pr_get_timing(void) {
>> return prctl(PR_GET_TIMING);
>> }
>> static inline int pr_set_tsc(int mode) {
>> return prctl(PR_SET_TSC, (long){mode});
>> }
>> static inline int pr_get_tsc(int *mode) {
>> return prctl(PR_GET_TSC, mode);
>> }
>> static inline int pr_set_unalign(unsigned int bits) {
>> return prctl(PR_SET_UNALIGN, (long){bits});
>> }
>> static inline int pr_get_unalign(unsigned int *bits) {
>> return prctl(PR_GET_UNALIGN, bits);
>> }
>> static inline int pr_get_auxv(void *auxv, size_t size) {
>> return prctl(PR_GET_AUXV, auxv, size, 0L, 0L);
>> }
>> static inline int pr_set_mdwe(unsigned int mask) {
>> return prctl(PR_SET_MDWE, mask, 0L, 0L, 0L);
>> }
>> static inline int pr_get_mdwe(void) {
>> return prctl(PR_GET_MDWE, 0L, 0L, 0L, 0L);
>> }
>> static inline int pr_riscv_set_icache_flush_ctx(int ctx, int scope) {
>> return prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, (long){ctx}, (long){scope});
>> }
>> static inline int pr_futex_hash_get_slots(void) {
>> return prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_GET_SLOTS);
>> }
>> static inline int pr_futex_hash_set_slots(size_t size) {
>> return prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS, size, 0L);
>> }
>>
>>
>>
>>
>> --
>> <https://www.alejandro-colomar.es>
>
>
>
More information about the Libc-alpha
mailing list