]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/missing_syscall: add missing_fchmodat2()
authorArseny Maslennikov <arseny@altlinux.org>
Fri, 20 Oct 2023 11:22:50 +0000 (14:22 +0300)
committerMike Yuan <me@yhndnzj.com>
Wed, 1 Nov 2023 16:23:12 +0000 (00:23 +0800)
Follow-up for 8b45281daa3a87b4b7a3248263cd0ba929d15596
and preparation for later commits.

Since libcs are more interested in the POSIX `fchmodat(3)`, they are
unlikely to provide a direct wrapper for this syscall. Thus, the headers
we examine to set `HAVE_*` are picked somewhat arbitrarily.

Also, hook up `try_fchmodat2()` in `test-seccomp.c`. (Also, correct that
function's prototype, despite the fact that mistake would not matter in
practice)

Co-authored-by: Mike Yuan <me@yhndnzj.com>
meson.build
src/basic/missing_syscall.h
src/test/test-seccomp.c

index 7f5d465783b998d405a40a3842580d6e9df359be..4f50b32cdf6f64452e10d8670e3c47a93b4cbcc9 100644 (file)
@@ -568,6 +568,8 @@ foreach ident : [
         ['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
index 83ec137fa59288b2d19e678a54a7d91141fa9162..d795efd8f2807baa39bf960f8f5ad300bbf7904c 100644 (file)
 
 /* ======================================================================= */
 
+#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);
index 56c4b3fd872e89b335dc47900f12bd46b8cb13ca..279a155cb0a98e4be33d13496ab6d3a56c8ac377 100644 (file)
@@ -21,7 +21,7 @@
 #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"
@@ -1007,21 +1007,22 @@ static int real_open(const char *path, int flags, mode_t mode) {
 #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) {