From a539314a87df37fea0bd39bf2b61cfab776968ec Mon Sep 17 00:00:00 2001 From: Arseny Maslennikov Date: Sun, 15 Oct 2023 11:00:00 +0300 Subject: [PATCH 1/5] seccomp: fix debug logging typo Fixes: da4dc9a67487 ("seccomp: rework how the S[UG]ID filter is installed") --- src/shared/seccomp-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 66c564aea28..afe56d51676 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -2241,7 +2241,7 @@ int seccomp_restrict_suid_sgid(void) { k = seccomp_restrict_sxid(seccomp, S_ISGID); if (k < 0) - log_debug_errno(r, "Failed to add sgid rule for architecture %s, ignoring: %m", + log_debug_errno(k, "Failed to add sgid rule for architecture %s, ignoring: %m", seccomp_arch_to_string(arch)); if (r < 0 && k < 0) From c83f83819388c7e1d318ec1d210a6f7887f8ccd7 Mon Sep 17 00:00:00 2001 From: Arseny Maslennikov Date: Sun, 15 Oct 2023 11:00:00 +0300 Subject: [PATCH 2/5] Update system call tables for Linux 6.6 We are doing this to obtain the definition of fchmodat2. --- src/basic/syscall-list.txt | 2 ++ src/basic/syscalls-alpha.txt | 2 ++ src/basic/syscalls-arc.txt | 2 ++ src/basic/syscalls-arm.txt | 2 ++ src/basic/syscalls-arm64.txt | 2 ++ src/basic/syscalls-i386.txt | 2 ++ src/basic/syscalls-ia64.txt | 2 ++ src/basic/syscalls-loongarch64.txt | 2 ++ src/basic/syscalls-m68k.txt | 2 ++ src/basic/syscalls-mips64.txt | 2 ++ src/basic/syscalls-mips64n32.txt | 2 ++ src/basic/syscalls-mipso32.txt | 2 ++ src/basic/syscalls-parisc.txt | 2 ++ src/basic/syscalls-powerpc.txt | 2 ++ src/basic/syscalls-powerpc64.txt | 2 ++ src/basic/syscalls-riscv32.txt | 2 ++ src/basic/syscalls-riscv64.txt | 2 ++ src/basic/syscalls-s390.txt | 2 ++ src/basic/syscalls-s390x.txt | 2 ++ src/basic/syscalls-sparc.txt | 2 ++ src/basic/syscalls-x86_64.txt | 2 ++ 21 files changed, 42 insertions(+) diff --git a/src/basic/syscall-list.txt b/src/basic/syscall-list.txt index d6d4b065a89..56f3f8aec54 100644 --- a/src/basic/syscall-list.txt +++ b/src/basic/syscall-list.txt @@ -79,6 +79,7 @@ fanotify_mark fchdir fchmod fchmodat +fchmodat2 fchown fchown32 fchownat @@ -202,6 +203,7 @@ lsetxattr lstat lstat64 madvise +map_shadow_stack mbind membarrier memfd_create diff --git a/src/basic/syscalls-alpha.txt b/src/basic/syscalls-alpha.txt index b83350b9b7c..c98df53aff7 100644 --- a/src/basic/syscalls-alpha.txt +++ b/src/basic/syscalls-alpha.txt @@ -79,6 +79,7 @@ fanotify_mark 495 fchdir 13 fchmod 124 fchmodat 461 +fchmodat2 562 fchown 123 fchown32 fchownat 453 @@ -202,6 +203,7 @@ lsetxattr 383 lstat 68 lstat64 426 madvise 75 +map_shadow_stack mbind 429 membarrier 517 memfd_create 512 diff --git a/src/basic/syscalls-arc.txt b/src/basic/syscalls-arc.txt index 171fe487314..cbfaceb26ae 100644 --- a/src/basic/syscalls-arc.txt +++ b/src/basic/syscalls-arc.txt @@ -79,6 +79,7 @@ fanotify_mark 263 fchdir 50 fchmod 52 fchmodat 53 +fchmodat2 452 fchown 55 fchown32 fchownat 54 @@ -202,6 +203,7 @@ lsetxattr 6 lstat lstat64 madvise 233 +map_shadow_stack mbind 235 membarrier 283 memfd_create 279 diff --git a/src/basic/syscalls-arm.txt b/src/basic/syscalls-arm.txt index b1d7d23e17f..513f53a6012 100644 --- a/src/basic/syscalls-arm.txt +++ b/src/basic/syscalls-arm.txt @@ -79,6 +79,7 @@ fanotify_mark 368 fchdir 133 fchmod 94 fchmodat 333 +fchmodat2 452 fchown 95 fchown32 207 fchownat 325 @@ -202,6 +203,7 @@ lsetxattr 227 lstat 107 lstat64 196 madvise 220 +map_shadow_stack mbind 319 membarrier 389 memfd_create 385 diff --git a/src/basic/syscalls-arm64.txt b/src/basic/syscalls-arm64.txt index c910a39ef31..00c48cfb029 100644 --- a/src/basic/syscalls-arm64.txt +++ b/src/basic/syscalls-arm64.txt @@ -79,6 +79,7 @@ fanotify_mark 263 fchdir 50 fchmod 52 fchmodat 53 +fchmodat2 452 fchown 55 fchown32 fchownat 54 @@ -202,6 +203,7 @@ lsetxattr 6 lstat lstat64 madvise 233 +map_shadow_stack mbind 235 membarrier 283 memfd_create 279 diff --git a/src/basic/syscalls-i386.txt b/src/basic/syscalls-i386.txt index 4c71bb30f94..d57abc22476 100644 --- a/src/basic/syscalls-i386.txt +++ b/src/basic/syscalls-i386.txt @@ -79,6 +79,7 @@ fanotify_mark 339 fchdir 133 fchmod 94 fchmodat 306 +fchmodat2 452 fchown 95 fchown32 207 fchownat 298 @@ -202,6 +203,7 @@ lsetxattr 227 lstat 107 lstat64 196 madvise 219 +map_shadow_stack mbind 274 membarrier 375 memfd_create 356 diff --git a/src/basic/syscalls-ia64.txt b/src/basic/syscalls-ia64.txt index 2a4534a950d..851cef0e9b8 100644 --- a/src/basic/syscalls-ia64.txt +++ b/src/basic/syscalls-ia64.txt @@ -79,6 +79,7 @@ fanotify_mark 1324 fchdir 1035 fchmod 1099 fchmodat 1292 +fchmodat2 1476 fchown 1100 fchown32 fchownat 1284 @@ -202,6 +203,7 @@ lsetxattr 1218 lstat 1211 lstat64 madvise 1209 +map_shadow_stack mbind 1259 membarrier 1344 memfd_create 1340 diff --git a/src/basic/syscalls-loongarch64.txt b/src/basic/syscalls-loongarch64.txt index 7f1a0b85cb6..6ed4242010c 100644 --- a/src/basic/syscalls-loongarch64.txt +++ b/src/basic/syscalls-loongarch64.txt @@ -79,6 +79,7 @@ fanotify_mark 263 fchdir 50 fchmod 52 fchmodat 53 +fchmodat2 452 fchown 55 fchown32 fchownat 54 @@ -202,6 +203,7 @@ lsetxattr 6 lstat lstat64 madvise 233 +map_shadow_stack mbind 235 membarrier 283 memfd_create 279 diff --git a/src/basic/syscalls-m68k.txt b/src/basic/syscalls-m68k.txt index c84b45ddfff..b9af39b7a3a 100644 --- a/src/basic/syscalls-m68k.txt +++ b/src/basic/syscalls-m68k.txt @@ -79,6 +79,7 @@ fanotify_mark 338 fchdir 133 fchmod 94 fchmodat 299 +fchmodat2 452 fchown 95 fchown32 207 fchownat 291 @@ -202,6 +203,7 @@ lsetxattr 224 lstat 107 lstat64 196 madvise 238 +map_shadow_stack mbind 268 membarrier 374 memfd_create 353 diff --git a/src/basic/syscalls-mips64.txt b/src/basic/syscalls-mips64.txt index 3a88ca09a7d..d3a43817ea0 100644 --- a/src/basic/syscalls-mips64.txt +++ b/src/basic/syscalls-mips64.txt @@ -79,6 +79,7 @@ fanotify_mark 5296 fchdir 5079 fchmod 5089 fchmodat 5258 +fchmodat2 5452 fchown 5091 fchown32 fchownat 5250 @@ -202,6 +203,7 @@ lsetxattr 5181 lstat 5006 lstat64 madvise 5027 +map_shadow_stack mbind 5227 membarrier 5318 memfd_create 5314 diff --git a/src/basic/syscalls-mips64n32.txt b/src/basic/syscalls-mips64n32.txt index 84b91a0279d..c4ffda7779f 100644 --- a/src/basic/syscalls-mips64n32.txt +++ b/src/basic/syscalls-mips64n32.txt @@ -79,6 +79,7 @@ fanotify_mark 6301 fchdir 6079 fchmod 6089 fchmodat 6262 +fchmodat2 6452 fchown 6091 fchown32 fchownat 6254 @@ -202,6 +203,7 @@ lsetxattr 6181 lstat 6006 lstat64 madvise 6027 +map_shadow_stack mbind 6231 membarrier 6322 memfd_create 6318 diff --git a/src/basic/syscalls-mipso32.txt b/src/basic/syscalls-mipso32.txt index 6c1d8d338e0..2d689a15832 100644 --- a/src/basic/syscalls-mipso32.txt +++ b/src/basic/syscalls-mipso32.txt @@ -79,6 +79,7 @@ fanotify_mark 4337 fchdir 4133 fchmod 4094 fchmodat 4299 +fchmodat2 4452 fchown 4095 fchown32 fchownat 4291 @@ -202,6 +203,7 @@ lsetxattr 4225 lstat 4107 lstat64 4214 madvise 4218 +map_shadow_stack mbind 4268 membarrier 4358 memfd_create 4354 diff --git a/src/basic/syscalls-parisc.txt b/src/basic/syscalls-parisc.txt index f0ba6a26a0f..1491179f98d 100644 --- a/src/basic/syscalls-parisc.txt +++ b/src/basic/syscalls-parisc.txt @@ -79,6 +79,7 @@ fanotify_mark 323 fchdir 133 fchmod 94 fchmodat 286 +fchmodat2 452 fchown 95 fchown32 fchownat 278 @@ -202,6 +203,7 @@ lsetxattr 239 lstat 84 lstat64 198 madvise 119 +map_shadow_stack mbind 260 membarrier 343 memfd_create 340 diff --git a/src/basic/syscalls-powerpc.txt b/src/basic/syscalls-powerpc.txt index 1c14ac06dc4..7bdc0c23f84 100644 --- a/src/basic/syscalls-powerpc.txt +++ b/src/basic/syscalls-powerpc.txt @@ -79,6 +79,7 @@ fanotify_mark 324 fchdir 133 fchmod 94 fchmodat 297 +fchmodat2 452 fchown 95 fchown32 fchownat 289 @@ -202,6 +203,7 @@ lsetxattr 210 lstat 107 lstat64 196 madvise 205 +map_shadow_stack mbind 259 membarrier 365 memfd_create 360 diff --git a/src/basic/syscalls-powerpc64.txt b/src/basic/syscalls-powerpc64.txt index 7c9c691434a..db7c7b5a106 100644 --- a/src/basic/syscalls-powerpc64.txt +++ b/src/basic/syscalls-powerpc64.txt @@ -79,6 +79,7 @@ fanotify_mark 324 fchdir 133 fchmod 94 fchmodat 297 +fchmodat2 452 fchown 95 fchown32 fchownat 289 @@ -202,6 +203,7 @@ lsetxattr 210 lstat 107 lstat64 madvise 205 +map_shadow_stack mbind 259 membarrier 365 memfd_create 360 diff --git a/src/basic/syscalls-riscv32.txt b/src/basic/syscalls-riscv32.txt index b5cf60afafb..7a0f0171c21 100644 --- a/src/basic/syscalls-riscv32.txt +++ b/src/basic/syscalls-riscv32.txt @@ -79,6 +79,7 @@ fanotify_mark 263 fchdir 50 fchmod 52 fchmodat 53 +fchmodat2 452 fchown 55 fchown32 fchownat 54 @@ -202,6 +203,7 @@ lsetxattr 6 lstat lstat64 madvise 233 +map_shadow_stack mbind 235 membarrier 283 memfd_create 279 diff --git a/src/basic/syscalls-riscv64.txt b/src/basic/syscalls-riscv64.txt index f6a8142c967..171b209e2d2 100644 --- a/src/basic/syscalls-riscv64.txt +++ b/src/basic/syscalls-riscv64.txt @@ -79,6 +79,7 @@ fanotify_mark 263 fchdir 50 fchmod 52 fchmodat 53 +fchmodat2 452 fchown 55 fchown32 fchownat 54 @@ -202,6 +203,7 @@ lsetxattr 6 lstat lstat64 madvise 233 +map_shadow_stack mbind 235 membarrier 283 memfd_create 279 diff --git a/src/basic/syscalls-s390.txt b/src/basic/syscalls-s390.txt index cbae37c0c85..73bfb30900d 100644 --- a/src/basic/syscalls-s390.txt +++ b/src/basic/syscalls-s390.txt @@ -79,6 +79,7 @@ fanotify_mark 333 fchdir 133 fchmod 94 fchmodat 299 +fchmodat2 452 fchown 95 fchown32 207 fchownat 291 @@ -202,6 +203,7 @@ lsetxattr 225 lstat 107 lstat64 196 madvise 219 +map_shadow_stack mbind 268 membarrier 356 memfd_create 350 diff --git a/src/basic/syscalls-s390x.txt b/src/basic/syscalls-s390x.txt index 0ffc7209454..12b60a955ff 100644 --- a/src/basic/syscalls-s390x.txt +++ b/src/basic/syscalls-s390x.txt @@ -79,6 +79,7 @@ fanotify_mark 333 fchdir 133 fchmod 94 fchmodat 299 +fchmodat2 452 fchown 207 fchown32 fchownat 291 @@ -202,6 +203,7 @@ lsetxattr 225 lstat 107 lstat64 madvise 219 +map_shadow_stack mbind 268 membarrier 356 memfd_create 350 diff --git a/src/basic/syscalls-sparc.txt b/src/basic/syscalls-sparc.txt index 9ecd646da46..d59eba017df 100644 --- a/src/basic/syscalls-sparc.txt +++ b/src/basic/syscalls-sparc.txt @@ -79,6 +79,7 @@ fanotify_mark 330 fchdir 176 fchmod 124 fchmodat 295 +fchmodat2 452 fchown 123 fchown32 32 fchownat 287 @@ -202,6 +203,7 @@ lsetxattr 170 lstat 40 lstat64 132 madvise 75 +map_shadow_stack mbind 303 membarrier 351 memfd_create 348 diff --git a/src/basic/syscalls-x86_64.txt b/src/basic/syscalls-x86_64.txt index 1f95ea1f6f8..6b708c83bf4 100644 --- a/src/basic/syscalls-x86_64.txt +++ b/src/basic/syscalls-x86_64.txt @@ -79,6 +79,7 @@ fanotify_mark 301 fchdir 81 fchmod 91 fchmodat 268 +fchmodat2 452 fchown 93 fchown32 fchownat 260 @@ -202,6 +203,7 @@ lsetxattr 189 lstat 6 lstat64 madvise 28 +map_shadow_stack 453 mbind 237 membarrier 324 memfd_create 319 From 3677364cc3a2c5429380cfd3a2472e2da87925c4 Mon Sep 17 00:00:00 2001 From: Arseny Maslennikov Date: Sun, 15 Oct 2023 11:00:00 +0300 Subject: [PATCH 3/5] basic/missing_syscall: generate defs for `fchmodat2(2)` We will need this to set seccomp filters on this system call regardless of libseccomp or kernel support. --- src/basic/missing_syscall_def.h | 68 +++++++++++++++++++++++++++++++++ src/basic/missing_syscalls.py | 1 + 2 files changed, 69 insertions(+) diff --git a/src/basic/missing_syscall_def.h b/src/basic/missing_syscall_def.h index 65104090235..f679422a2e9 100644 --- a/src/basic/missing_syscall_def.h +++ b/src/basic/missing_syscall_def.h @@ -246,6 +246,74 @@ assert_cc(__NR_copy_file_range == systemd_NR_copy_file_range); # endif #endif +#ifndef __IGNORE_fchmodat2 +# if defined(__aarch64__) +# define systemd_NR_fchmodat2 452 +# elif defined(__alpha__) +# define systemd_NR_fchmodat2 562 +# elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_fchmodat2 452 +# elif defined(__arm__) +# define systemd_NR_fchmodat2 452 +# elif defined(__i386__) +# define systemd_NR_fchmodat2 452 +# elif defined(__ia64__) +# define systemd_NR_fchmodat2 1476 +# elif defined(__loongarch_lp64) +# define systemd_NR_fchmodat2 452 +# elif defined(__m68k__) +# define systemd_NR_fchmodat2 452 +# elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_fchmodat2 4452 +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_fchmodat2 6452 +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_fchmodat2 5452 +# else +# error "Unknown MIPS ABI" +# endif +# elif defined(__hppa__) +# define systemd_NR_fchmodat2 452 +# elif defined(__powerpc__) +# define systemd_NR_fchmodat2 452 +# elif defined(__riscv) +# if __riscv_xlen == 32 +# define systemd_NR_fchmodat2 452 +# elif __riscv_xlen == 64 +# define systemd_NR_fchmodat2 452 +# else +# error "Unknown RISC-V ABI" +# endif +# elif defined(__s390__) +# define systemd_NR_fchmodat2 452 +# elif defined(__sparc__) +# define systemd_NR_fchmodat2 452 +# elif defined(__x86_64__) +# if defined(__ILP32__) +# define systemd_NR_fchmodat2 (452 | /* __X32_SYSCALL_BIT */ 0x40000000) +# else +# define systemd_NR_fchmodat2 452 +# endif +# elif !defined(missing_arch_template) +# warning "fchmodat2() syscall number is unknown for your architecture" +# endif + +/* may be an (invalid) negative number due to libseccomp, see PR 13319 */ +# if defined __NR_fchmodat2 && __NR_fchmodat2 >= 0 +# if defined systemd_NR_fchmodat2 +assert_cc(__NR_fchmodat2 == systemd_NR_fchmodat2); +# endif +# else +# if defined __NR_fchmodat2 +# undef __NR_fchmodat2 +# endif +# if defined systemd_NR_fchmodat2 && systemd_NR_fchmodat2 >= 0 +# define __NR_fchmodat2 systemd_NR_fchmodat2 +# endif +# endif +#endif + #ifndef __IGNORE_getrandom # if defined(__aarch64__) # define systemd_NR_getrandom 278 diff --git a/src/basic/missing_syscalls.py b/src/basic/missing_syscalls.py index ae0ffda3f0b..3749e89c4e2 100644 --- a/src/basic/missing_syscalls.py +++ b/src/basic/missing_syscalls.py @@ -9,6 +9,7 @@ SYSCALLS = [ 'bpf', 'close_range', 'copy_file_range', + 'fchmodat2', 'getrandom', 'memfd_create', 'mount_setattr', From 6e10405aa25fe5e76b740d9ec59730e3f4470c7a Mon Sep 17 00:00:00 2001 From: Arseny Maslennikov Date: Sun, 15 Oct 2023 11:00:00 +0300 Subject: [PATCH 4/5] seccomp: include `fchmodat2` in `@file-system` --- src/shared/seccomp-util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index afe56d51676..1712f3eff36 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -478,6 +478,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { "fchdir\0" "fchmod\0" "fchmodat\0" + "fchmodat2\0" "fcntl\0" "fcntl64\0" "fgetxattr\0" From 8b45281daa3a87b4b7a3248263cd0ba929d15596 Mon Sep 17 00:00:00 2001 From: Arseny Maslennikov Date: Sun, 15 Oct 2023 11:00:00 +0300 Subject: [PATCH 5/5] seccomp: also check the mode parameter of `fchmodat2(2)` If there is no libseccomp support, just ban the entire syscall instead so wrappers will fall back to older, supported syscalls. Also reflect all of this in `test-seccomp.c`. --- src/shared/seccomp-util.c | 24 +++++++++++++++++++++++- src/test/test-seccomp.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 1712f3eff36..bb970d52647 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -2081,7 +2081,7 @@ int seccomp_protect_hostname(void) { static int seccomp_restrict_sxid(scmp_filter_ctx seccomp, mode_t m) { /* Checks the mode_t parameter of the following system calls: * - * → chmod() + fchmod() + fchmodat() + * → chmod() + fchmod() + fchmodat() + fchmodat2() * → open() + creat() + openat() * → mkdir() + mkdirat() * → mknod() + mknodat() @@ -2124,6 +2124,28 @@ static int seccomp_restrict_sxid(scmp_filter_ctx seccomp, mode_t m) { else any = true; +#if defined(__SNR_fchmodat2) + r = seccomp_rule_add_exact( + seccomp, + SCMP_ACT_ERRNO(EPERM), + SCMP_SYS(fchmodat2), + 1, + SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +#else + /* It looks like this libseccomp does not know about fchmodat2(). + * Pretend the fchmodat2() system call is not supported at all, + * regardless of the kernel version. */ + r = seccomp_rule_add_exact( + seccomp, + SCMP_ACT_ERRNO(ENOSYS), + __NR_fchmodat2, + 0); +#endif + if (r < 0) + log_debug_errno(r, "Failed to add filter for fchmodat2: %m"); + else + any = true; + r = seccomp_rule_add_exact( seccomp, SCMP_ACT_ERRNO(EPERM), diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c index ecf383f43c3..56c4b3fd872 100644 --- a/src/test/test-seccomp.c +++ b/src/test/test-seccomp.c @@ -21,6 +21,7 @@ #include "macro.h" #include "memory-util.h" #include "missing_sched.h" +#include "missing_syscall_def.h" #include "nsflags.h" #include "nulstr-util.h" #include "process-util.h" @@ -1006,6 +1007,23 @@ 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) { + /* 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); + /* 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 +} + TEST(restrict_suid_sgid) { pid_t pid; @@ -1047,6 +1065,11 @@ TEST(restrict_suid_sgid) { assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0); assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISUID, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755, 0) >= 0); + k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID); k = safe_close(k); assert_se(unlink(z) >= 0); @@ -1148,6 +1171,11 @@ TEST(restrict_suid_sgid) { assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM); assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISUID, 0) < 0 && errno == EPERM); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID, 0) < 0 && errno == EPERM); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755, 0) >= 0); + assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM); assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM); assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);