['memfd_create', '''#include <sys/mman.h>'''],
['gettid', '''#include <sys/types.h>
#include <unistd.h>'''],
+ ['fchmodat2', '''#include <stdlib.h>
+ #include <fcntl.h>'''], # no known header declares fchmodat2
['pivot_root', '''#include <stdlib.h>
#include <unistd.h>'''], # no known header declares pivot_root
['ioprio_get', '''#include <sched.h>'''], # no known header declares ioprio_get
/* ======================================================================= */
+#if !HAVE_FCHMODAT2
+static inline int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) {
+# ifdef __NR_fchmodat2
+ return syscall(__NR_fchmodat2, dirfd, path, mode, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+# define fchmodat2 missing_fchmodat2
+#endif
+
+/* ======================================================================= */
+
#if !HAVE_PIVOT_ROOT
static inline int missing_pivot_root(const char *new_root, const char *put_old) {
return syscall(__NR_pivot_root, new_root, put_old);
#include "macro.h"
#include "memory-util.h"
#include "missing_sched.h"
-#include "missing_syscall_def.h"
+#include "missing_syscall.h"
#include "nsflags.h"
#include "nulstr-util.h"
#include "process-util.h"
#endif
}
-static int try_fchmodat2(int dirfd, const char *path, int flags, mode_t mode) {
+static int try_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) {
+ int r;
+
/* glibc does not provide a direct wrapper for fchmodat2(). Let's hence define our own wrapper for
* testing purposes that calls the real syscall, on architectures and in environments where
* SYS_fchmodat2 is defined. Otherwise, let's just fall back to the glibc fchmodat() call. */
-#if defined __NR_fchmodat2 && __NR_fchmodat2 >= 0
- int r;
- r = (int) syscall(__NR_fchmodat2, dirfd, path, flags, mode);
+ /* Not supported by fchmodat() */
+ assert_se(!FLAGS_SET(flags, AT_EMPTY_PATH));
+
+ r = RET_NERRNO(fchmodat2(dirfd, path, mode, flags));
+ if (r != -ENOSYS)
+ return r;
+
/* The syscall might still be unsupported by kernel or libseccomp. */
- if (r < 0 && errno == ENOSYS)
- return fchmodat(dirfd, path, flags, mode);
- return r;
-#else
- return fchmodat(dirfd, path, flags, mode);
-#endif
+ return RET_NERRNO(fchmodat(dirfd, path, mode, flags));
}
TEST(restrict_suid_sgid) {