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
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/bpf.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_BPF
int missing_bpf(int cmd, union bpf_attr *attr, size_t size) {
return syscall(__NR_bpf, cmd, attr, size);
}
#endif
+17
View File
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/ioprio.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_IOPRIO_GET
int missing_ioprio_get(int which, int who) {
return syscall(__NR_ioprio_get, which, who);
}
#endif
#if !HAVE_IOPRIO_SET
int missing_ioprio_set(int which, int who, int ioprio) {
return syscall(__NR_ioprio_set, which, who, ioprio);
}
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/kcmp.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_KCMP
int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
}
#endif
+23
View File
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/keyctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_KEYCTL
long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) {
return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
}
#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) {
return syscall(__NR_add_key, type, description, payload, plen, ringid);
}
#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) {
return syscall(__NR_request_key, type, description, callout_info, destringid);
}
#endif
+17
View File
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/mempolicy.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_SET_MEMPOLICY
int missing_set_mempolicy(int mode, const unsigned long *nodemask, unsigned long maxnode) {
return syscall(__NR_set_mempolicy, mode, nodemask, maxnode);
}
#endif
#if !HAVE_GET_MEMPOLICY
int missing_get_mempolicy(int *mode, unsigned long *nodemask, unsigned long maxnode, void *addr, unsigned long flags) {
return syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags);
}
#endif
+28
View File
@@ -0,0 +1,28 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
libc_wrapper_sources = files(
'bpf.c',
'ioprio.c',
'kcmp.c',
'keyctl.c',
'mempolicy.c',
'mount.c',
'pidfd.c',
'quota.c',
'sched.c',
'signal.c',
'stat.c',
'unistd.c',
'xattr.c',
)
sources += libc_wrapper_sources
libc_wrapper_static = static_library(
'c-wrapper',
libc_wrapper_sources,
include_directories : system_includes,
implicit_include_directories : false,
dependencies : [userspace],
c_args : ['-fvisibility=default'],
build_by_default : false)
+47
View File
@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/mount.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_FSOPEN
int missing_fsopen(const char *fsname, unsigned flags) {
return syscall(__NR_fsopen, fsname, flags);
}
#endif
#if !HAVE_FSMOUNT
int missing_fsmount(int fd, unsigned flags, unsigned ms_flags) {
return syscall(__NR_fsmount, fd, flags, ms_flags);
}
#endif
#if !HAVE_MOVE_MOUNT
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);
}
#endif
#if !HAVE_FSCONFIG
int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux) {
return syscall(__NR_fsconfig, fd, cmd, key, value, aux);
}
#endif
#if !HAVE_OPEN_TREE
int missing_open_tree(int dfd, const char *filename, unsigned flags) {
return syscall(__NR_open_tree, dfd, filename, flags);
}
#endif
#if !HAVE_MOUNT_SETATTR
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);
}
#endif
#if !HAVE_OPEN_TREE_ATTR
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);
}
#endif
+17
View File
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/pidfd.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_PIDFD_OPEN
int missing_pidfd_open(pid_t pid, unsigned flags) {
return syscall(__NR_pidfd_open, pid, flags);
}
#endif
#if !HAVE_PIDFD_SEND_SIGNAL
int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) {
return syscall(__NR_pidfd_send_signal, fd, sig, info, flags);
}
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/quota.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_QUOTACTL_FD
int missing_quotactl_fd(int fd, int cmd, int id, void *addr) {
return syscall(__NR_quotactl_fd, fd, cmd, id, addr);
}
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sched.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_SCHED_SETATTR
int missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned flags) {
return syscall(__NR_sched_setattr, pid, attr, flags);
}
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <signal.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_RT_TGSIGQUEUEINFO
int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info) {
return syscall(__NR_rt_tgsigqueueinfo, tgid, tid, sig, info);
}
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_FCHMODAT2
int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) {
return syscall(__NR_fchmodat2, dirfd, path, mode, flags);
}
#endif
+25
View File
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/syscall.h>
#include <unistd.h>
#if !HAVE_CLOSE_RANGE
int missing_close_range(unsigned first_fd, unsigned end_fd, unsigned flags) {
/* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while
* userspace exclusively uses signed integers for fds. glibc chose to expose it 1:1 however, hence we
* do so here too, even if we end up passing signed fds to it most of the time. */
return syscall(__NR_close_range, first_fd, end_fd, flags);
}
#endif
#if !HAVE_EXECVEAT
int missing_execveat(int dirfd, const char *pathname, char * const argv[], char * const envp[], int flags) {
return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags);
}
#endif
#if !HAVE_PIVOT_ROOT
int missing_pivot_root(const char *new_root, const char *put_old) {
return syscall(__NR_pivot_root, new_root, put_old);
}
#endif
+17
View File
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/syscall.h>
#include <sys/xattr.h>
#include <unistd.h>
#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) {
return syscall(__NR_setxattrat, fd, path, at_flags, name, args, size);
}
#endif
#if !HAVE_REMOVEXATTRAT
int missing_removexattrat(int fd, const char *path, int at_flags, const char *name) {
return syscall(__NR_removexattrat, fd, path, at_flags, name);
}
#endif