]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/nspawn/nspawn-seccomp.c
2 This file is part of systemd.
4 Copyright 2016 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include <linux/netlink.h>
22 #include <sys/capability.h>
23 #include <sys/types.h>
32 #include "seccomp-util.h"
35 #include "nspawn-seccomp.h"
39 static int seccomp_add_default_syscall_filter(scmp_filter_ctx ctx
,
40 uint64_t cap_list_retain
) {
47 { 0, SCMP_SYS(_sysctl
) }, /* obsolete syscall */
48 { 0, SCMP_SYS(add_key
) }, /* keyring is not namespaced */
49 { 0, SCMP_SYS(afs_syscall
) }, /* obsolete syscall */
50 { 0, SCMP_SYS(bdflush
) },
54 { 0, SCMP_SYS(break) }, /* obsolete syscall */
55 { 0, SCMP_SYS(create_module
) }, /* obsolete syscall */
56 { 0, SCMP_SYS(ftime
) }, /* obsolete syscall */
57 { 0, SCMP_SYS(get_kernel_syms
) }, /* obsolete syscall */
58 { 0, SCMP_SYS(getpmsg
) }, /* obsolete syscall */
59 { 0, SCMP_SYS(gtty
) }, /* obsolete syscall */
60 #ifdef __NR_kexec_file_load
61 { 0, SCMP_SYS(kexec_file_load
) },
63 { 0, SCMP_SYS(kexec_load
) },
64 { 0, SCMP_SYS(keyctl
) }, /* keyring is not namespaced */
65 { 0, SCMP_SYS(lock
) }, /* obsolete syscall */
66 { 0, SCMP_SYS(lookup_dcookie
) },
67 { 0, SCMP_SYS(mpx
) }, /* obsolete syscall */
68 { 0, SCMP_SYS(nfsservctl
) }, /* obsolete syscall */
69 { 0, SCMP_SYS(open_by_handle_at
) },
70 { 0, SCMP_SYS(perf_event_open
) },
71 { 0, SCMP_SYS(prof
) }, /* obsolete syscall */
72 { 0, SCMP_SYS(profil
) }, /* obsolete syscall */
73 { 0, SCMP_SYS(putpmsg
) }, /* obsolete syscall */
74 { 0, SCMP_SYS(query_module
) }, /* obsolete syscall */
75 { 0, SCMP_SYS(quotactl
) },
76 { 0, SCMP_SYS(request_key
) }, /* keyring is not namespaced */
77 { 0, SCMP_SYS(security
) }, /* obsolete syscall */
78 { 0, SCMP_SYS(sgetmask
) }, /* obsolete syscall */
79 { 0, SCMP_SYS(ssetmask
) }, /* obsolete syscall */
80 { 0, SCMP_SYS(stty
) }, /* obsolete syscall */
81 { 0, SCMP_SYS(swapoff
) },
82 { 0, SCMP_SYS(swapon
) },
83 { 0, SCMP_SYS(sysfs
) }, /* obsolete syscall */
84 { 0, SCMP_SYS(tuxcall
) }, /* obsolete syscall */
85 { 0, SCMP_SYS(ulimit
) }, /* obsolete syscall */
86 { 0, SCMP_SYS(uselib
) }, /* obsolete syscall */
87 { 0, SCMP_SYS(ustat
) }, /* obsolete syscall */
88 { 0, SCMP_SYS(vserver
) }, /* obsolete syscall */
89 { CAP_SYSLOG
, SCMP_SYS(syslog
) },
90 { CAP_SYS_MODULE
, SCMP_SYS(delete_module
) },
91 { CAP_SYS_MODULE
, SCMP_SYS(finit_module
) },
92 { CAP_SYS_MODULE
, SCMP_SYS(init_module
) },
93 { CAP_SYS_PACCT
, SCMP_SYS(acct
) },
94 { CAP_SYS_PTRACE
, SCMP_SYS(process_vm_readv
) },
95 { CAP_SYS_PTRACE
, SCMP_SYS(process_vm_writev
) },
96 { CAP_SYS_PTRACE
, SCMP_SYS(ptrace
) },
97 { CAP_SYS_RAWIO
, SCMP_SYS(ioperm
) },
98 { CAP_SYS_RAWIO
, SCMP_SYS(iopl
) },
99 { CAP_SYS_RAWIO
, SCMP_SYS(pciconfig_iobase
) },
100 { CAP_SYS_RAWIO
, SCMP_SYS(pciconfig_read
) },
101 { CAP_SYS_RAWIO
, SCMP_SYS(pciconfig_write
) },
102 #ifdef __NR_s390_pci_mmio_read
103 { CAP_SYS_RAWIO
, SCMP_SYS(s390_pci_mmio_read
) },
105 #ifdef __NR_s390_pci_mmio_write
106 { CAP_SYS_RAWIO
, SCMP_SYS(s390_pci_mmio_write
) },
108 { CAP_SYS_TIME
, SCMP_SYS(adjtimex
) },
109 { CAP_SYS_TIME
, SCMP_SYS(clock_adjtime
) },
110 { CAP_SYS_TIME
, SCMP_SYS(clock_settime
) },
111 { CAP_SYS_TIME
, SCMP_SYS(settimeofday
) },
112 { CAP_SYS_TIME
, SCMP_SYS(stime
) },
115 for (i
= 0; i
< ELEMENTSOF(blacklist
); i
++) {
116 if (blacklist
[i
].capability
!= 0 && (cap_list_retain
& (1ULL << blacklist
[i
].capability
)))
119 r
= seccomp_rule_add(ctx
, SCMP_ACT_ERRNO(EPERM
), blacklist
[i
].syscall_num
, 0);
121 continue; /* unknown syscall */
123 log_error_errno(r
, "Failed to block syscall: %m");
131 int setup_seccomp(uint64_t cap_list_retain
) {
132 scmp_filter_ctx seccomp
;
135 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
139 r
= seccomp_add_secondary_archs(seccomp
);
141 log_error_errno(r
, "Failed to add secondary archs to seccomp filter: %m");
145 r
= seccomp_add_default_syscall_filter(seccomp
, cap_list_retain
);
150 Audit is broken in containers, much of the userspace audit
151 hookup will fail if running inside a container. We don't
152 care and just turn off creation of audit sockets.
154 This will make socket(AF_NETLINK, *, NETLINK_AUDIT) fail
155 with EAFNOSUPPORT which audit userspace uses as indication
156 that audit is disabled in the kernel.
159 r
= seccomp_rule_add(
161 SCMP_ACT_ERRNO(EAFNOSUPPORT
),
164 SCMP_A0(SCMP_CMP_EQ
, AF_NETLINK
),
165 SCMP_A2(SCMP_CMP_EQ
, NETLINK_AUDIT
));
167 log_error_errno(r
, "Failed to add audit seccomp rule: %m");
171 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
173 log_error_errno(r
, "Failed to unset NO_NEW_PRIVS: %m");
177 r
= seccomp_load(seccomp
);
179 log_debug_errno(r
, "Kernel is probably not configured with CONFIG_SECCOMP. Disabling seccomp audit filter: %m");
184 log_error_errno(r
, "Failed to install seccomp audit filter: %m");
189 seccomp_release(seccomp
);
195 int setup_seccomp(uint64_t cap_list_retain
) {