mirror of
https://github.com/systemd/systemd.git
synced 2024-10-30 23:21:22 +03:00
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.
This commit is contained in:
parent
dff6c6295b
commit
da4dc9a674
@ -1803,28 +1803,18 @@ int seccomp_protect_hostname(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int seccomp_restrict_suid_sgid(void) {
|
||||
uint32_t arch;
|
||||
int r;
|
||||
|
||||
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
|
||||
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
|
||||
|
||||
r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
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;
|
||||
int r = 0;
|
||||
bool any = false;
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1833,7 +1823,9 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
log_debug_errno(r, "Failed to add filter for chmod: %m");
|
||||
else
|
||||
any = true;
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1842,7 +1834,9 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
log_debug_errno(r, "Failed to add filter for fchmod: %m");
|
||||
else
|
||||
any = true;
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1851,7 +1845,9 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
log_debug_errno(r, "Failed to add filter for fchmodat: %m");
|
||||
else
|
||||
any = true;
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1860,7 +1856,9 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
log_debug_errno(r, "Failed to add filter for mkdir: %m");
|
||||
else
|
||||
any = true;
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1869,7 +1867,9 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
log_debug_errno(r, "Failed to add filter for mkdirat: %m");
|
||||
else
|
||||
any = true;
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1878,7 +1878,9 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
log_debug_errno(r, "Failed to add filter for mknod: %m");
|
||||
else
|
||||
any = true;
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1887,8 +1889,11 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
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),
|
||||
@ -1897,7 +1902,10 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT),
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
log_debug_errno(r, "Failed to add filter for open: %m");
|
||||
else
|
||||
any = true;
|
||||
#endif
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1907,7 +1915,9 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT),
|
||||
SCMP_A3(SCMP_CMP_MASKED_EQ, m, m));
|
||||
if (r < 0)
|
||||
break;
|
||||
log_debug_errno(r, "Failed to add filter for openat: %m");
|
||||
else
|
||||
any = true;
|
||||
|
||||
r = seccomp_rule_add_exact(
|
||||
seccomp,
|
||||
@ -1916,12 +1926,34 @@ int seccomp_restrict_suid_sgid(void) {
|
||||
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));
|
||||
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, k;
|
||||
|
||||
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
|
||||
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
|
||||
|
||||
r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
if (r < 0 && k < 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
r = seccomp_load(seccomp);
|
||||
if (IN_SET(r, -EPERM, -EACCES))
|
||||
|
Loading…
Reference in New Issue
Block a user