libc-wrapper: introduce a tiny libc wrapper

Then, move syscall definitions to the wrapper, and prototypes are moved
to relevant headers.

This also adds checks for add_key() and request_key(), as one day
glibc may be going to add some of them separatedly.

The check for fspick in meson.build is dropped, as it is currently
unused in our code.

This also moves
- basic/missing_bpf.h -> include/override/linux/bpf.h,
- basic/missing_keyctl.h -> include/override/linux/keyctl.h.
This commit is contained in:
Yu Watanabe
2025-07-11 13:05:46 +09:00
parent da522c9921
commit 543a48b653
68 changed files with 494 additions and 327 deletions
+14
View File
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include_next <linux/bpf.h> /* IWYU pragma: export */
/* defined in linux/filter.h */
/* Unconditional jumps, goto pc + off16 */
#define BPF_JMP_A(OFF) \
((struct bpf_insn) { \
.code = BPF_JMP | BPF_JA, \
.dst_reg = 0, \
.src_reg = 0, \
.off = OFF, \
.imm = 0 })
+46
View File
@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include_next <linux/keyctl.h> /* IWYU pragma: export */
#include <stdint.h>
/* From linux/key.h */
#ifndef KEY_POS_VIEW
typedef int32_t key_serial_t;
# define KEY_POS_VIEW 0x01000000
# define KEY_POS_READ 0x02000000
# define KEY_POS_WRITE 0x04000000
# define KEY_POS_SEARCH 0x08000000
# define KEY_POS_LINK 0x10000000
# define KEY_POS_SETATTR 0x20000000
# define KEY_POS_ALL 0x3f000000
# define KEY_USR_VIEW 0x00010000
# define KEY_USR_READ 0x00020000
# define KEY_USR_WRITE 0x00040000
# define KEY_USR_SEARCH 0x00080000
# define KEY_USR_LINK 0x00100000
# define KEY_USR_SETATTR 0x00200000
# define KEY_USR_ALL 0x003f0000
# define KEY_GRP_VIEW 0x00000100
# define KEY_GRP_READ 0x00000200
# define KEY_GRP_WRITE 0x00000400
# define KEY_GRP_SEARCH 0x00000800
# define KEY_GRP_LINK 0x00001000
# define KEY_GRP_SETATTR 0x00002000
# define KEY_GRP_ALL 0x00003f00
# define KEY_OTH_VIEW 0x00000001
# define KEY_OTH_READ 0x00000002
# define KEY_OTH_WRITE 0x00000004
# define KEY_OTH_SEARCH 0x00000008
# define KEY_OTH_LINK 0x00000010
# define KEY_OTH_SETATTR 0x00000020
# define KEY_OTH_ALL 0x0000003f
#else
static_assert(KEY_OTH_ALL == 0x0000003f, "");
#endif
+19
View File
@@ -35,3 +35,22 @@ static_assert(PF_KTHREAD == 0x00200000, "");
#else
static_assert(TASK_COMM_LEN == 16, "");
#endif
/* glibc does not provide clone() on ia64, only clone2(). Not only that, but it also doesn't provide a
* prototype, only the symbol in the shared library (it provides a prototype for clone(), but not the
* symbol in the shared library). */
#if defined(__ia64__)
int __clone2(int (*fn)(void *), void *stack_base, size_t stack_size, int flags, void *arg);
#define HAVE_CLONE 0
#else
/* We know that everywhere else clone() is available, so we don't bother with a meson check (that takes time
* at build time) and just define it. Once the kernel drops ia64 support, we can drop this too. */
#define HAVE_CLONE 1
#endif
/* Defined since glibc-2.41.
* Supported since kernel 3.14 (e6cfc0295c7d51b008999a8b13a44fb43f8685ea). */
#if !HAVE_SCHED_SETATTR
int missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned flags);
# define sched_setattr missing_sched_setattr
#endif
+9
View File
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include_next <signal.h>
#if !HAVE_RT_TGSIGQUEUEINFO
int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info);
# define rt_tgsigqueueinfo missing_rt_tgsigqueueinfo
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <linux/bpf.h> /* IWYU pragma: export */
#include <stddef.h>
/* Supported since kernel v3.18 (749730ce42a2121e1c88350d69478bff3994b10a). */
#if !HAVE_BPF
int missing_bpf(int cmd, union bpf_attr *attr, size_t size);
# define bpf missing_bpf
#endif
+14
View File
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <linux/ioprio.h> /* IWYU pragma: export */
#if !HAVE_IOPRIO_GET
int missing_ioprio_get(int which, int who);
# define ioprio_get missing_ioprio_get
#endif
#if !HAVE_IOPRIO_SET
int missing_ioprio_set(int which, int who, int ioprio);
# define ioprio_set missing_ioprio_set
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <linux/kcmp.h> /* IWYU pragma: export */
#include <sys/types.h>
/* Supported since kernel v3.5 (d97b46a64674a267bc41c9e16132ee2a98c3347d). */
#if !HAVE_KCMP
int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2);
# define kcmp missing_kcmp
#endif
+20
View File
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <linux/keyctl.h> /* IWYU pragma: export */
#include <stddef.h>
#if !HAVE_KEYCTL
long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
# define keyctl missing_keyctl
#endif
#if !HAVE_ADD_KEY
key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid);
# define add_key missing_add_key
#endif
#if !HAVE_REQUEST_KEY
key_serial_t missing_request_key(const char *type, const char *description, const char *callout_info, key_serial_t destringid);
# define request_key missing_request_key
#endif
+14
View File
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <linux/mempolicy.h> /* IWYU pragma: export */
#if !HAVE_SET_MEMPOLICY
int missing_set_mempolicy(int mode, const unsigned long *nodemask, unsigned long maxnode);
# define set_mempolicy missing_set_mempolicy
#endif
#if !HAVE_GET_MEMPOLICY
int missing_get_mempolicy(int *mode, unsigned long *nodemask, unsigned long maxnode, void *addr, unsigned long flags);
# define get_mempolicy missing_get_mempolicy
#endif
+21 -35
View File
@@ -8,8 +8,6 @@
#include <stddef.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <unistd.h>
/* Since glibc-2.37 (774058d72942249f71d74e7f2b639f77184160a6), sys/mount.h includes linux/mount.h, and
* we can safely include both headers in the same source file. However, we cannot do that with older glibc.
@@ -41,67 +39,56 @@ extern int umount2(const char *__special_file, int __flags) __THROW;
/* Open the filesystem referenced by FS_NAME so it can be configured for
mouting. */
/* Defined since glibc-2.36.
* Supported since kernel v5.2 (24dcb3d90a1f67fe08c68a004af37df059d74005). */
#if HAVE_FSOPEN
extern int fsopen(const char *__fs_name, unsigned int __flags) __THROW;
#else
static inline int missing_fsopen(const char *fsname, unsigned flags) {
return syscall(__NR_fsopen, fsname, flags);
}
int missing_fsopen(const char *fsname, unsigned flags);
# define fsopen missing_fsopen
#endif
/* Create a mount representation for the FD created by fsopen using
FLAGS with ATTR_FLAGS describing how the mount is to be performed. */
/* Defined since glibc-2.36.
* Supported since kernel v5.2 (93766fbd2696c2c4453dd8e1070977e9cd4e6b6d). */
#if HAVE_FSMOUNT
extern int fsmount(int __fd, unsigned int __flags, unsigned int __ms_flags) __THROW;
#else
static inline int missing_fsmount(int fd, unsigned flags, unsigned ms_flags) {
return syscall(__NR_fsmount, fd, flags, ms_flags);
}
int missing_fsmount(int fd, unsigned flags, unsigned ms_flags);
# define fsmount missing_fsmount
#endif
/* Add the mounted FROM_DFD referenced by FROM_PATHNAME filesystem returned
by fsmount in the hierarchy in the place TO_DFD reference by TO_PATHNAME
using FLAGS. */
/* Defined since glibc-2.36.
* Supported since kernel v5.2 (2db154b3ea8e14b04fee23e3fdfd5e9d17fbc6ae). */
#if HAVE_MOVE_MOUNT
extern int move_mount(int __from_dfd, const char *__from_pathname, int __to_dfd, const char *__to_pathname, unsigned int flags) __THROW;
#else
static inline int missing_move_mount(
int from_dfd,
const char *from_pathname,
int to_dfd,
const char *to_pathname,
unsigned flags) {
return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags);
}
int missing_move_mount(int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, unsigned flags);
# define move_mount missing_move_mount
#endif
/* Set parameters and trigger CMD action on the FD context. KEY, VALUE,
and AUX are used depending ng of the CMD. */
/* Defined since glibc-2.36.
* Supported since kernel v5.2 (ecdab150fddb42fe6a739335257949220033b782). */
#if HAVE_FSCONFIG
extern int fsconfig(int __fd, unsigned int __cmd, const char *__key, const void *__value, int __aux) __THROW;
#else
static inline int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux) {
return syscall(__NR_fsconfig, fd, cmd, key, value, aux);
}
int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux);
# define fsconfig missing_fsconfig
#endif
/* Equivalent of fopen for an existing mount point. */
#if HAVE_FSPICK
extern int fspick(int __dfd, const char *__path, unsigned int __flags) __THROW;
#endif
/* Open the mount point FILENAME in directory DFD using FLAGS. */
/* Defined since glibc-2.36.
* Supported since kernel v5.2 (a07b20004793d8926f78d63eb5980559f7813404). */
#if HAVE_OPEN_TREE
extern int open_tree(int __dfd, const char *__filename, unsigned int __flags) __THROW;
#else
static inline int missing_open_tree(int dfd, const char *filename, unsigned flags) {
return syscall(__NR_open_tree, dfd, filename, flags);
}
int missing_open_tree(int dfd, const char *filename, unsigned flags);
# define open_tree missing_open_tree
#endif
@@ -110,21 +97,20 @@ static inline int missing_open_tree(int dfd, const char *filename, unsigned flag
directory referred to by the file descriptor dirfd. Otherwise if DFD is
the special value AT_FDCWD then PATH is interpreted relative to the current
working directory of the calling process. */
/* Defined since glibc-2.36.
* Supported since kernel v5.12 (2a1867219c7b27f928e2545782b86daaf9ad50bd). */
#if HAVE_MOUNT_SETATTR
extern int mount_setattr(int __dfd, const char *__path, unsigned int __flags, struct mount_attr *__uattr, size_t __usize) __THROW;
#else
static inline int missing_mount_setattr(int dfd, const char *path, unsigned flags, struct mount_attr *attr, size_t size) {
return syscall(__NR_mount_setattr, dfd, path, flags, attr, size);
}
int missing_mount_setattr(int dfd, const char *path, unsigned flags, struct mount_attr *attr, size_t size);
# define mount_setattr missing_mount_setattr
#endif
/* Not defined in glibc yet as of glibc-2.41.
* Supported since kernel v6.15 (c4a16820d90199409c9bf01c4f794e1e9e8d8fd8). */
#if HAVE_OPEN_TREE_ATTR
extern int open_tree_attr(int __dfd, const char *__filename, unsigned int __flags, struct mount_attr *__uattr, size_t __usize) __THROW;
#else
static inline int missing_open_tree_attr(int dfd, const char *filename, unsigned int flags, struct mount_attr *attr, size_t size) {
return syscall(__NR_open_tree_attr, dfd, filename, flags, attr, size);
}
int missing_open_tree_attr(int dfd, const char *filename, unsigned int flags, struct mount_attr *attr, size_t size);
# define open_tree_attr missing_open_tree_attr
#endif
+18 -3
View File
@@ -1,14 +1,29 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <linux/types.h>
#include <sys/ioctl.h>
/* since glibc-2.36 */
#if HAVE_PIDFD_OPEN
#include_next <sys/pidfd.h>
#endif
#include <linux/types.h>
#include <signal.h>
#include <sys/ioctl.h>
/* Defined since glibc-2.36.
* Supported since kernel v5.3 (7615d9e1780e26e0178c93c55b73309a5dc093d7). */
#if !HAVE_PIDFD_OPEN
int missing_pidfd_open(pid_t pid, unsigned flags);
# define pidfd_open missing_pidfd_open
#endif
/* Defined since glibc-2.36.
* Supported since kernel v5.1 (3eb39f47934f9d5a3027fe00d906a45fe3a15fad). */
#if !HAVE_PIDFD_SEND_SIGNAL
int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags);
# define pidfd_send_signal missing_pidfd_send_signal
#endif
/* since glibc-2.41 */
#ifndef PIDFS_IOCTL_MAGIC
# define PIDFS_IOCTL_MAGIC 0xFF
+10
View File
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include_next <sys/quota.h>
/* Supported since kernel v5.14 (64c2c2c62f92339b176ea24403d8db16db36f9e6). */
#if !HAVE_QUOTACTL_FD
int missing_quotactl_fd(int fd, int cmd, int id, void *addr);
# define quotactl_fd missing_quotactl_fd
#endif
+10
View File
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include_next <sys/stat.h>
/* Supported since kernel v6.6 (78252deb023cf0879256fcfbafe37022c390762b). */
#if !HAVE_FCHMODAT2
int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags);
# define fchmodat2 missing_fchmodat2
#endif
+12
View File
@@ -6,3 +6,15 @@
#include <linux/xattr.h>
#include_next <sys/xattr.h>
/* Supported since kernel v6.13 (6140be90ec70c39fa844741ca3cc807dd0866394). */
#if !HAVE_SETXATTRAT
int missing_setxattrat(int fd, const char *path, int at_flags, const char *name, const struct xattr_args *args, size_t size);
# define setxattrat missing_setxattrat
#endif
/* Supported since kernel v6.13 (6140be90ec70c39fa844741ca3cc807dd0866394). */
#if !HAVE_REMOVEXATTRAT
int missing_removexattrat(int fd, const char *path, int at_flags, const char *name);
# define removexattrat missing_removexattrat
#endif
+23
View File
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include_next <unistd.h>
/* Defined since glibc-2.34.
* Supported since kernel v5.9 (9b4feb630e8e9801603f3cab3a36369e3c1cf88d). */
#if !HAVE_CLOSE_RANGE
int missing_close_range(unsigned first_fd, unsigned end_fd, unsigned flags);
# define close_range missing_close_range
#endif
/* Defined since glibc-2.34.
* Supported since kernel v3.19 (51f39a1f0cea1cacf8c787f652f26dfee9611874). */
#if !HAVE_EXECVEAT
int missing_execveat(int dirfd, const char *pathname, char * const argv[], char * const envp[], int flags);
# define execveat missing_execveat
#endif
#if !HAVE_PIVOT_ROOT
int missing_pivot_root(const char *new_root, const char *put_old);
# define pivot_root missing_pivot_root
#endif