1
0
mirror of https://github.com/systemd/systemd synced 2024-07-08 20:15:55 +00:00

basic/missing_syscall: add missing_fchmodat2()

Follow-up for 8b45281daa
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>
This commit is contained in:
Arseny Maslennikov 2023-10-20 14:22:50 +03:00 committed by Mike Yuan
parent 2b5b25f123
commit c21566d90b
No known key found for this signature in database
GPG Key ID: 417471C0A40F58B3
3 changed files with 29 additions and 11 deletions

View 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

View File

@ -32,6 +32,21 @@
/* ======================================================================= */
#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);

View 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) {