helper: block more unusual/privileged syscalls
These are toggled by F_EXT and exposed as SyscallPolicy.Compat in the Go interface. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
efacaa40fa
commit
37780456a7
@ -28,7 +28,7 @@ struct f_syscall_act {
|
|||||||
#define LEN(arr) (sizeof(arr) / sizeof((arr)[0]))
|
#define LEN(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
|
|
||||||
#define SECCOMP_RULESET_ADD(ruleset) do { \
|
#define SECCOMP_RULESET_ADD(ruleset) do { \
|
||||||
F_println("adding seccomp ruleset \"" #ruleset "\""); \
|
F_println("adding seccomp ruleset \"" #ruleset "\""); \
|
||||||
for (int i = 0; i < LEN(ruleset); i++) { \
|
for (int i = 0; i < LEN(ruleset); i++) { \
|
||||||
assert(ruleset[i].m_errno == EPERM || ruleset[i].m_errno == ENOSYS); \
|
assert(ruleset[i].m_errno == EPERM || ruleset[i].m_errno == ENOSYS); \
|
||||||
\
|
\
|
||||||
@ -89,6 +89,31 @@ int32_t f_export_bpf(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts o
|
|||||||
{SCMP_SYS(migrate_pages), EPERM},
|
{SCMP_SYS(migrate_pages), EPERM},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// fortify: project-specific extensions
|
||||||
|
struct f_syscall_act deny_common_ext[] = {
|
||||||
|
// system calls for changing the system clock
|
||||||
|
{SCMP_SYS(adjtimex), EPERM},
|
||||||
|
{SCMP_SYS(clock_adjtime), EPERM},
|
||||||
|
{SCMP_SYS(clock_adjtime64), EPERM},
|
||||||
|
{SCMP_SYS(clock_settime), EPERM},
|
||||||
|
{SCMP_SYS(clock_settime64), EPERM},
|
||||||
|
{SCMP_SYS(settimeofday), EPERM},
|
||||||
|
|
||||||
|
// loading and unloading of kernel modules
|
||||||
|
{SCMP_SYS(delete_module), EPERM},
|
||||||
|
{SCMP_SYS(finit_module), EPERM},
|
||||||
|
{SCMP_SYS(init_module), EPERM},
|
||||||
|
|
||||||
|
// system calls for rebooting and reboot preparation
|
||||||
|
{SCMP_SYS(kexec_file_load), EPERM},
|
||||||
|
{SCMP_SYS(kexec_load), EPERM},
|
||||||
|
{SCMP_SYS(reboot), EPERM},
|
||||||
|
|
||||||
|
// system calls for enabling/disabling swap devices
|
||||||
|
{SCMP_SYS(swapoff), EPERM},
|
||||||
|
{SCMP_SYS(swapon), EPERM},
|
||||||
|
};
|
||||||
|
|
||||||
struct f_syscall_act deny_ns[] = {
|
struct f_syscall_act deny_ns[] = {
|
||||||
// Don't allow subnamespace setups:
|
// Don't allow subnamespace setups:
|
||||||
{SCMP_SYS(unshare), EPERM},
|
{SCMP_SYS(unshare), EPERM},
|
||||||
@ -126,6 +151,34 @@ int32_t f_export_bpf(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts o
|
|||||||
{SCMP_SYS(mount_setattr), ENOSYS},
|
{SCMP_SYS(mount_setattr), ENOSYS},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// fortify: project-specific extensions
|
||||||
|
struct f_syscall_act deny_ns_ext[] = {
|
||||||
|
// changing file ownership
|
||||||
|
{SCMP_SYS(chown), EPERM},
|
||||||
|
{SCMP_SYS(chown32), EPERM},
|
||||||
|
{SCMP_SYS(fchown), EPERM},
|
||||||
|
{SCMP_SYS(fchown32), EPERM},
|
||||||
|
{SCMP_SYS(fchownat), EPERM},
|
||||||
|
{SCMP_SYS(lchown), EPERM},
|
||||||
|
{SCMP_SYS(lchown32), EPERM},
|
||||||
|
|
||||||
|
// system calls for changing user ID and group ID credentials
|
||||||
|
{SCMP_SYS(setgid), EPERM},
|
||||||
|
{SCMP_SYS(setgid32), EPERM},
|
||||||
|
{SCMP_SYS(setgroups), EPERM},
|
||||||
|
{SCMP_SYS(setgroups32), EPERM},
|
||||||
|
{SCMP_SYS(setregid), EPERM},
|
||||||
|
{SCMP_SYS(setregid32), EPERM},
|
||||||
|
{SCMP_SYS(setresgid), EPERM},
|
||||||
|
{SCMP_SYS(setresgid32), EPERM},
|
||||||
|
{SCMP_SYS(setresuid), EPERM},
|
||||||
|
{SCMP_SYS(setresuid32), EPERM},
|
||||||
|
{SCMP_SYS(setreuid), EPERM},
|
||||||
|
{SCMP_SYS(setreuid32), EPERM},
|
||||||
|
{SCMP_SYS(setuid), EPERM},
|
||||||
|
{SCMP_SYS(setuid32), EPERM},
|
||||||
|
};
|
||||||
|
|
||||||
struct f_syscall_act deny_tty[] = {
|
struct f_syscall_act deny_tty[] = {
|
||||||
// Don't allow faking input to the controlling tty (CVE-2017-5226)
|
// Don't allow faking input to the controlling tty (CVE-2017-5226)
|
||||||
{SCMP_SYS(ioctl), EPERM, &SCMP_A1(SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int)TIOCSTI)},
|
{SCMP_SYS(ioctl), EPERM, &SCMP_A1(SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int)TIOCSTI)},
|
||||||
@ -145,6 +198,22 @@ int32_t f_export_bpf(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts o
|
|||||||
{SCMP_SYS(ptrace), EPERM}
|
{SCMP_SYS(ptrace), EPERM}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct f_syscall_act deny_emu[] = {
|
||||||
|
// modify_ldt is a historic source of interesting information leaks,
|
||||||
|
// so it's disabled as a hardening measure.
|
||||||
|
// However, it is required to run old 16-bit applications
|
||||||
|
// as well as some Wine patches, so it's allowed in multiarch.
|
||||||
|
{SCMP_SYS(modify_ldt), EPERM},
|
||||||
|
};
|
||||||
|
|
||||||
|
// fortify: project-specific extensions
|
||||||
|
struct f_syscall_act deny_emu_ext[] = {
|
||||||
|
{SCMP_SYS(subpage_prot), ENOSYS},
|
||||||
|
{SCMP_SYS(switch_endian), ENOSYS},
|
||||||
|
{SCMP_SYS(vm86), ENOSYS},
|
||||||
|
{SCMP_SYS(vm86old), ENOSYS},
|
||||||
|
};
|
||||||
|
|
||||||
// Blocklist all but unix, inet, inet6 and netlink
|
// Blocklist all but unix, inet, inet6 and netlink
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -199,26 +268,11 @@ int32_t f_export_bpf(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts o
|
|||||||
if (opts & F_DENY_NS) SECCOMP_RULESET_ADD(deny_ns);
|
if (opts & F_DENY_NS) SECCOMP_RULESET_ADD(deny_ns);
|
||||||
if (opts & F_DENY_TTY) SECCOMP_RULESET_ADD(deny_tty);
|
if (opts & F_DENY_TTY) SECCOMP_RULESET_ADD(deny_tty);
|
||||||
if (opts & F_DENY_DEVEL) SECCOMP_RULESET_ADD(deny_devel);
|
if (opts & F_DENY_DEVEL) SECCOMP_RULESET_ADD(deny_devel);
|
||||||
|
if (!allow_multiarch) SECCOMP_RULESET_ADD(deny_emu);
|
||||||
if (!allow_multiarch) {
|
if (opts & F_EXT) {
|
||||||
F_println("disabling modify_ldt");
|
SECCOMP_RULESET_ADD(deny_common_ext);
|
||||||
|
if (opts & F_DENY_NS) SECCOMP_RULESET_ADD(deny_ns_ext);
|
||||||
// modify_ldt is a historic source of interesting information leaks,
|
if (!allow_multiarch) SECCOMP_RULESET_ADD(deny_emu_ext);
|
||||||
// so it's disabled as a hardening measure.
|
|
||||||
// However, it is required to run old 16-bit applications
|
|
||||||
// as well as some Wine patches, so it's allowed in multiarch.
|
|
||||||
ret = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(modify_ldt), 0);
|
|
||||||
|
|
||||||
// See above for the meaning of EFAULT.
|
|
||||||
if (ret == -EFAULT) {
|
|
||||||
// call fmsg here?
|
|
||||||
res = 4;
|
|
||||||
goto out;
|
|
||||||
} else if (ret < 0) {
|
|
||||||
res = 5;
|
|
||||||
errno = -ret;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Socket filtering doesn't work on e.g. i386, so ignore failures here
|
// Socket filtering doesn't work on e.g. i386, so ignore failures here
|
||||||
|
@ -8,13 +8,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
F_DENY_NS = 1 << 0,
|
F_EXT = 1 << 0,
|
||||||
F_DENY_TTY = 1 << 1,
|
F_DENY_NS = 1 << 1,
|
||||||
F_DENY_DEVEL = 1 << 2,
|
F_DENY_TTY = 1 << 2,
|
||||||
F_MULTIARCH = 1 << 3,
|
F_DENY_DEVEL = 1 << 3,
|
||||||
F_LINUX32 = 1 << 4,
|
F_MULTIARCH = 1 << 4,
|
||||||
F_CAN = 1 << 5,
|
F_LINUX32 = 1 << 5,
|
||||||
F_BLUETOOTH = 1 << 6,
|
F_CAN = 1 << 6,
|
||||||
|
F_BLUETOOTH = 1 << 7,
|
||||||
} f_syscall_opts;
|
} f_syscall_opts;
|
||||||
|
|
||||||
extern void F_println(char *v);
|
extern void F_println(char *v);
|
||||||
|
@ -9,10 +9,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SyscallPolicy struct {
|
type SyscallPolicy struct {
|
||||||
|
// disable fortify extensions
|
||||||
|
Compat bool `json:"compat"`
|
||||||
|
// deny development syscalls
|
||||||
DenyDevel bool `json:"deny_devel"`
|
DenyDevel bool `json:"deny_devel"`
|
||||||
|
// deny multiarch/emulation syscalls
|
||||||
Multiarch bool `json:"multiarch"`
|
Multiarch bool `json:"multiarch"`
|
||||||
Linux32 bool `json:"linux32"`
|
// allow PER_LINUX32
|
||||||
Can bool `json:"can"`
|
Linux32 bool `json:"linux32"`
|
||||||
|
// allow AF_CAN
|
||||||
|
Can bool `json:"can"`
|
||||||
|
// allow AF_BLUETOOTH
|
||||||
Bluetooth bool `json:"bluetooth"`
|
Bluetooth bool `json:"bluetooth"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +60,7 @@ func (c *Config) resolveSeccomp() (*os.File, error) {
|
|||||||
o syscallOpts
|
o syscallOpts
|
||||||
d string
|
d string
|
||||||
}{
|
}{
|
||||||
|
{!c.Syscall.Compat, flagExt, "fortify"},
|
||||||
{!c.UserNS, flagDenyNS, "denyns"},
|
{!c.UserNS, flagDenyNS, "denyns"},
|
||||||
{c.NewSession, flagDenyTTY, "denytty"},
|
{c.NewSession, flagDenyTTY, "denytty"},
|
||||||
{c.Syscall.DenyDevel, flagDenyDevel, "denydevel"},
|
{c.Syscall.DenyDevel, flagDenyDevel, "denydevel"},
|
||||||
|
@ -30,6 +30,7 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
flagExt syscallOpts = C.F_EXT
|
||||||
flagDenyNS syscallOpts = C.F_DENY_NS
|
flagDenyNS syscallOpts = C.F_DENY_NS
|
||||||
flagDenyTTY syscallOpts = C.F_DENY_TTY
|
flagDenyTTY syscallOpts = C.F_DENY_TTY
|
||||||
flagDenyDevel syscallOpts = C.F_DENY_DEVEL
|
flagDenyDevel syscallOpts = C.F_DENY_DEVEL
|
||||||
|
Loading…
Reference in New Issue
Block a user