commit:     296415fa509175fd0253091697d1eec1fcf462df
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Sat Feb 24 15:48:45 2024 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Sat Feb 24 15:48:45 2024 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=296415fa

sys-apps/systemd: backport fchmodat2 support to 254.9

Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 .../systemd/files/systemd-254.9-fchmodat2.patch    | 255 +++++++++++++++++++++
 ...ystemd-254.9.ebuild => systemd-254.9-r1.ebuild} |   1 +
 2 files changed, 256 insertions(+)

diff --git a/sys-apps/systemd/files/systemd-254.9-fchmodat2.patch 
b/sys-apps/systemd/files/systemd-254.9-fchmodat2.patch
new file mode 100644
index 000000000000..27bdd121aa60
--- /dev/null
+++ b/sys-apps/systemd/files/systemd-254.9-fchmodat2.patch
@@ -0,0 +1,255 @@
+From 3d93b69fa558b33f1f2b52305fa4c2d836789394 Mon Sep 17 00:00:00 2001
+From: Arseny Maslennikov <ars...@altlinux.org>
+Date: Sun, 15 Oct 2023 11:00:00 +0300
+Subject: [PATCH 1/3] 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.
+
+(cherry picked from commit 3677364cc3a2c5429380cfd3a2472e2da87925c4)
+---
+ 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 402fdd00dc..b5beb434db 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 5ccf02adec..00f72dc7a8 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',
+-- 
+2.43.0
+
+
+From c1ffd32c642dcadb844b149fcc0c6fe0dbe8a292 Mon Sep 17 00:00:00 2001
+From: Arseny Maslennikov <ars...@altlinux.org>
+Date: Sun, 15 Oct 2023 11:00:00 +0300
+Subject: [PATCH 2/3] seccomp: include `fchmodat2` in `@file-system`
+
+(cherry picked from commit 6e10405aa25fe5e76b740d9ec59730e3f4470c7a)
+---
+ 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 bd9660cb35..a9c6279b18 100644
+--- a/src/shared/seccomp-util.c
++++ b/src/shared/seccomp-util.c
+@@ -468,6 +468,7 @@ const SyscallFilterSet 
syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
+                 "fchdir\0"
+                 "fchmod\0"
+                 "fchmodat\0"
++                "fchmodat2\0"
+                 "fcntl\0"
+                 "fcntl64\0"
+                 "fgetxattr\0"
+-- 
+2.43.0
+
+
+From da6ec29e7f755e14655132b4e0b04f463f40af3e Mon Sep 17 00:00:00 2001
+From: Arseny Maslennikov <ars...@altlinux.org>
+Date: Sun, 15 Oct 2023 11:00:00 +0300
+Subject: [PATCH 3/3] 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`.
+
+(cherry picked from commit 8b45281daa3a87b4b7a3248263cd0ba929d15596)
+---
+ 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 a9c6279b18..12fd95d95b 100644
+--- a/src/shared/seccomp-util.c
++++ b/src/shared/seccomp-util.c
+@@ -2038,7 +2038,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()
+@@ -2081,6 +2081,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 2d06098ddd..3a73262a8b 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"
+@@ -1003,6 +1004,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;
+ 
+@@ -1044,6 +1062,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);
+@@ -1145,6 +1168,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);
+-- 
+2.43.0
+

diff --git a/sys-apps/systemd/systemd-254.9.ebuild 
b/sys-apps/systemd/systemd-254.9-r1.ebuild
similarity index 99%
rename from sys-apps/systemd/systemd-254.9.ebuild
rename to sys-apps/systemd/systemd-254.9-r1.ebuild
index c12a9240f822..b9a20c537da3 100644
--- a/sys-apps/systemd/systemd-254.9.ebuild
+++ b/sys-apps/systemd/systemd-254.9-r1.ebuild
@@ -242,6 +242,7 @@ src_prepare() {
        local PATCHES=(
                "${FILESDIR}/systemd-253-initrd-generators.patch"
                "${FILESDIR}/254-PrivateDevices-userdbd.patch"
+               "${FILESDIR}/systemd-254.9-fchmodat2.patch"
        )
 
        if ! use vanilla; then

Reply via email to