Skip to content

Commit e26ac75

Browse files
smcvalexlarsson
authored andcommitted
run: Add an errno value to seccomp filters
At the moment, if we block a syscall we always make it fail with EPERM, but this is risky: user-space libraries can start to use new replacements for old syscalls at any time, and will often treat EPERM as a fatal error. For new syscalls, we should make the syscall fail with ENOSYS, which is indistinguishable from running on an older kernel and will cause fallback to an older implementation, for example clone3() to clone(). In future we should probably move from EPERM to ENOSYS for some of the syscalls we already block, but for now keep the status quo. This is a prerequisite for fixing the vulnerability tracked as GHSA-67h7-w3jq-vh4q. Signed-off-by: Simon McVittie <smcv@collabora.com>
1 parent 9914dff commit e26ac75

File tree

1 file changed

+36
-26
lines changed

1 file changed

+36
-26
lines changed

Diff for: common/flatpak-run.c

+36-26
Original file line numberDiff line numberDiff line change
@@ -2897,61 +2897,63 @@ setup_seccomp (FlatpakBwrap *bwrap,
28972897
struct
28982898
{
28992899
int scall;
2900+
int errnum;
29002901
struct scmp_arg_cmp *arg;
29012902
} syscall_blocklist[] = {
29022903
/* Block dmesg */
2903-
{SCMP_SYS (syslog)},
2904+
{SCMP_SYS (syslog), EPERM},
29042905
/* Useless old syscall */
2905-
{SCMP_SYS (uselib)},
2906+
{SCMP_SYS (uselib), EPERM},
29062907
/* Don't allow disabling accounting */
2907-
{SCMP_SYS (acct)},
2908+
{SCMP_SYS (acct), EPERM},
29082909
/* 16-bit code is unnecessary in the sandbox, and modify_ldt is a
29092910
historic source of interesting information leaks. */
2910-
{SCMP_SYS (modify_ldt)},
2911+
{SCMP_SYS (modify_ldt), EPERM},
29112912
/* Don't allow reading current quota use */
2912-
{SCMP_SYS (quotactl)},
2913+
{SCMP_SYS (quotactl), EPERM},
29132914

29142915
/* Don't allow access to the kernel keyring */
2915-
{SCMP_SYS (add_key)},
2916-
{SCMP_SYS (keyctl)},
2917-
{SCMP_SYS (request_key)},
2916+
{SCMP_SYS (add_key), EPERM},
2917+
{SCMP_SYS (keyctl), EPERM},
2918+
{SCMP_SYS (request_key), EPERM},
29182919

29192920
/* Scary VM/NUMA ops */
2920-
{SCMP_SYS (move_pages)},
2921-
{SCMP_SYS (mbind)},
2922-
{SCMP_SYS (get_mempolicy)},
2923-
{SCMP_SYS (set_mempolicy)},
2924-
{SCMP_SYS (migrate_pages)},
2921+
{SCMP_SYS (move_pages), EPERM},
2922+
{SCMP_SYS (mbind), EPERM},
2923+
{SCMP_SYS (get_mempolicy), EPERM},
2924+
{SCMP_SYS (set_mempolicy), EPERM},
2925+
{SCMP_SYS (migrate_pages), EPERM},
29252926

29262927
/* Don't allow subnamespace setups: */
2927-
{SCMP_SYS (unshare)},
2928-
{SCMP_SYS (mount)},
2929-
{SCMP_SYS (pivot_root)},
2928+
{SCMP_SYS (unshare), EPERM},
2929+
{SCMP_SYS (mount), EPERM},
2930+
{SCMP_SYS (pivot_root), EPERM},
29302931
#if defined(__s390__) || defined(__s390x__) || defined(__CRIS__)
29312932
/* Architectures with CONFIG_CLONE_BACKWARDS2: the child stack
29322933
* and flags arguments are reversed so the flags come second */
2933-
{SCMP_SYS (clone), &SCMP_A1 (SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)},
2934+
{SCMP_SYS (clone), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)},
29342935
#else
29352936
/* Normally the flags come first */
2936-
{SCMP_SYS (clone), &SCMP_A0 (SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)},
2937+
{SCMP_SYS (clone), EPERM, &SCMP_A0 (SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)},
29372938
#endif
29382939

29392940
/* Don't allow faking input to the controlling tty (CVE-2017-5226) */
2940-
{SCMP_SYS (ioctl), &SCMP_A1 (SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int) TIOCSTI)},
2941+
{SCMP_SYS (ioctl), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int) TIOCSTI)},
29412942
};
29422943

29432944
struct
29442945
{
29452946
int scall;
2947+
int errnum;
29462948
struct scmp_arg_cmp *arg;
29472949
} syscall_nondevel_blocklist[] = {
29482950
/* Profiling operations; we expect these to be done by tools from outside
29492951
* the sandbox. In particular perf has been the source of many CVEs.
29502952
*/
2951-
{SCMP_SYS (perf_event_open)},
2953+
{SCMP_SYS (perf_event_open), EPERM},
29522954
/* Don't allow you to switch to bsd emulation or whatnot */
2953-
{SCMP_SYS (personality), &SCMP_A0 (SCMP_CMP_NE, allowed_personality)},
2954-
{SCMP_SYS (ptrace)}
2955+
{SCMP_SYS (personality), EPERM, &SCMP_A0 (SCMP_CMP_NE, allowed_personality)},
2956+
{SCMP_SYS (ptrace), EPERM}
29552957
};
29562958
/* Blocklist all but unix, inet, inet6 and netlink */
29572959
struct
@@ -3035,10 +3037,14 @@ setup_seccomp (FlatpakBwrap *bwrap,
30353037
for (i = 0; i < G_N_ELEMENTS (syscall_blocklist); i++)
30363038
{
30373039
int scall = syscall_blocklist[i].scall;
3040+
int errnum = syscall_blocklist[i].errnum;
3041+
3042+
g_return_val_if_fail (errnum == EPERM || errnum == ENOSYS, FALSE);
3043+
30383044
if (syscall_blocklist[i].arg)
3039-
r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (EPERM), scall, 1, *syscall_blocklist[i].arg);
3045+
r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (errnum), scall, 1, *syscall_blocklist[i].arg);
30403046
else
3041-
r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (EPERM), scall, 0);
3047+
r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (errnum), scall, 0);
30423048
if (r < 0 && r == -EFAULT /* unknown syscall */)
30433049
return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Failed to block syscall %d"), scall);
30443050
}
@@ -3048,10 +3054,14 @@ setup_seccomp (FlatpakBwrap *bwrap,
30483054
for (i = 0; i < G_N_ELEMENTS (syscall_nondevel_blocklist); i++)
30493055
{
30503056
int scall = syscall_nondevel_blocklist[i].scall;
3057+
int errnum = syscall_nondevel_blocklist[i].errnum;
3058+
3059+
g_return_val_if_fail (errnum == EPERM || errnum == ENOSYS, FALSE);
3060+
30513061
if (syscall_nondevel_blocklist[i].arg)
3052-
r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (EPERM), scall, 1, *syscall_nondevel_blocklist[i].arg);
3062+
r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (errnum), scall, 1, *syscall_nondevel_blocklist[i].arg);
30533063
else
3054-
r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (EPERM), scall, 0);
3064+
r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (errnum), scall, 0);
30553065

30563066
if (r < 0 && r == -EFAULT /* unknown syscall */)
30573067
return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Failed to block syscall %d"), scall);

0 commit comments

Comments
 (0)