diff --git a/0010-test-seccomp-fix-compilation-on-arm64.patch b/0010-test-seccomp-fix-compilation-on-arm64.patch new file mode 100644 index 0000000..796e243 --- /dev/null +++ b/0010-test-seccomp-fix-compilation-on-arm64.patch @@ -0,0 +1,38 @@ +From dff6c6295b1cb09d6da8ab054e66059e43247ab1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 3 Apr 2019 12:36:03 +0200 +Subject: [PATCH 10/11] test-seccomp: fix compilation on arm64 + +It has no open(). +--- + src/test/test-seccomp.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c +index 8efbecbeff..9b7307cf39 100644 +--- a/src/test/test-seccomp.c ++++ b/src/test/test-seccomp.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -763,9 +764,14 @@ static void test_lock_personality(void) { + + static int real_open(const char *path, int flags, mode_t mode) { + /* glibc internally calls openat() when open() is requested. Let's hence define our own wrapper for +- * testing purposes that calls the real syscall. */ ++ * testing purposes that calls the real syscall, on architectures where SYS_open is defined. On ++ * other architectures, let's just fall back to the glibc call. */ + ++#ifdef SYS_open + return (int) syscall(SYS_open, path, flags, mode); ++#else ++ return open(path, flags, mode); ++#endif + } + + static void test_restrict_suid_sgid(void) { diff --git a/0011-seccomp-rework-how-the-S-UG-ID-filter-is-installed.patch b/0011-seccomp-rework-how-the-S-UG-ID-filter-is-installed.patch new file mode 100644 index 0000000..3f33a83 --- /dev/null +++ b/0011-seccomp-rework-how-the-S-UG-ID-filter-is-installed.patch @@ -0,0 +1,283 @@ +From da4dc9a6748797e804b6bc92ad513d509abf581c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 3 Apr 2019 13:11:00 +0200 +Subject: [PATCH 11/11] seccomp: rework how the S[UG]ID filter is installed + +If we know that a syscall is undefined on the given architecture, don't +even try to add it. + +Try to install the filter even if some syscalls fail. Also use a helper +function to make the whole a bit less magic. + +This allows the S[UG]ID test to pass on arm64. +--- + src/shared/seccomp-util.c | 244 +++++++++++++++++++++----------------- + 1 file changed, 138 insertions(+), 106 deletions(-) + +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index 7a179998bd..65d800c914 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -1803,9 +1803,139 @@ int seccomp_protect_hostname(void) { + return 0; + } + ++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() ++ * → open() + creat() + openat() ++ * → mkdir() + mkdirat() ++ * → mknod() + mknodat() ++ * ++ * Returns error if *everything* failed, and 0 otherwise. ++ */ ++ int r = 0; ++ bool any = false; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(chmod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for chmod: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(fchmod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for fchmod: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(fchmodat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for fchmodat: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mkdir), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for mkdir: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mkdirat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for mkdirat: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mknod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for mknod: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mknodat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for mknodat: %m"); ++ else ++ any = true; ++ ++#if SCMP_SYS(open) > 0 ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(open), ++ 2, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for open: %m"); ++ else ++ any = true; ++#endif ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(openat), ++ 2, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), ++ SCMP_A3(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for openat: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(creat), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for creat: %m"); ++ else ++ any = true; ++ ++ return any ? 0 : r; ++} ++ + int seccomp_restrict_suid_sgid(void) { + uint32_t arch; +- int r; ++ int r, k; + + SECCOMP_FOREACH_LOCAL_ARCH(arch) { + _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL; +@@ -1814,114 +1944,16 @@ int seccomp_restrict_suid_sgid(void) { + if (r < 0) + return r; + +- /* Checks the mode_t parameter of the following system calls: +- * +- * → chmod() + fchmod() + fchmodat() +- * → open() + creat() + openat() +- * → mkdir() + mkdirat() +- * → mknod() + mknodat() +- */ ++ r = seccomp_restrict_sxid(seccomp, S_ISUID); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add suid rule for architecture %s, ignoring: %m", seccomp_arch_to_string(arch)); + +- for (unsigned bit = 0; bit < 2; bit ++) { +- /* Block S_ISUID in the first iteration, S_ISGID in the second */ +- mode_t m = bit == 0 ? S_ISUID : S_ISGID; ++ k = seccomp_restrict_sxid(seccomp, S_ISGID); ++ if (k < 0) ++ log_debug_errno(r, "Failed to add sgid rule for architecture %s, ignoring: %m", seccomp_arch_to_string(arch)); + +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(chmod), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(fchmod), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(fchmodat), +- 1, +- SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(mkdir), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(mkdirat), +- 1, +- SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(mknod), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(mknodat), +- 1, +- SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(open), +- 2, +- SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), +- SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(openat), +- 2, +- SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), +- SCMP_A3(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(creat), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- } +- if (r < 0) { +- log_debug_errno(r, "Failed to add suid/sgid rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch)); ++ if (r < 0 && k < 0) + continue; +- } + + r = seccomp_load(seccomp); + if (IN_SET(r, -EPERM, -EACCES)) diff --git a/systemd.spec b/systemd.spec index f219788..6cbba0b 100644 --- a/systemd.spec +++ b/systemd.spec @@ -53,6 +53,8 @@ GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[ %endif Patch0002: 0002-Revert-units-set-NoNewPrivileges-for-all-long-runnin.patch +Patch0010: 0010-test-seccomp-fix-compilation-on-arm64.patch +Patch0011: 0011-seccomp-rework-how-the-S-UG-ID-filter-is-installed.patch Patch0998: 0998-resolved-create-etc-resolv.conf-symlink-at-runtime.patch