Skip to content

Commit 947293a

Browse files
committed
set default seccomp profile
Signed-off-by: Jessica Frazelle <[email protected]>
1 parent ad56c97 commit 947293a

5 files changed

Lines changed: 374 additions & 3 deletions

File tree

daemon/execdriver/native/create.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ func (d *Driver) createContainer(c *execdriver.Command, hooks execdriver.Hooks)
6969
if err := d.setCapabilities(container, c); err != nil {
7070
return nil, err
7171
}
72+
73+
if c.SeccompProfile == "" {
74+
container.Seccomp = getDefaultSeccompProfile()
75+
}
7276
}
7377
// add CAP_ prefix to all caps for new libcontainer update to match
7478
// the spec format.
@@ -89,6 +93,7 @@ func (d *Driver) createContainer(c *execdriver.Command, hooks execdriver.Hooks)
8993
return nil, err
9094
}
9195
}
96+
9297
if err := execdriver.SetupCgroups(container, c); err != nil {
9398
return nil, err
9499
}

daemon/execdriver/native/seccomp.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import (
1212
"github.com/opencontainers/specs"
1313
)
1414

15+
func getDefaultSeccompProfile() *configs.Seccomp {
16+
return defaultSeccompProfile
17+
}
18+
1519
func loadSeccompProfile(path string) (*configs.Seccomp, error) {
1620
f, err := ioutil.ReadFile(path)
1721
if err != nil {
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
// +build linux
2+
3+
package native
4+
5+
import "github.com/opencontainers/runc/libcontainer/configs"
6+
7+
var defaultSeccompProfile = &configs.Seccomp{
8+
DefaultAction: configs.Allow,
9+
Syscalls: []*configs.Syscall{
10+
{
11+
// Quota and Accounting syscalls which could let containers
12+
// disable their own resource limits or process accounting
13+
Name: "acct",
14+
Action: configs.Errno,
15+
Args: []*configs.Arg{},
16+
},
17+
{
18+
// Prevent containers from using the kernel keyring,
19+
// which is not namespaced
20+
Name: "add_key",
21+
Action: configs.Errno,
22+
Args: []*configs.Arg{},
23+
},
24+
{
25+
// Similar to clock_settime and settimeofday
26+
// Time/Date is not namespaced
27+
Name: "adjtimex",
28+
Action: configs.Errno,
29+
Args: []*configs.Arg{},
30+
},
31+
{
32+
// Time/Date is not namespaced
33+
Name: "clock_settime",
34+
Action: configs.Errno,
35+
Args: []*configs.Arg{},
36+
},
37+
{
38+
// Deny cloning new namespaces
39+
Name: "clone",
40+
Action: configs.Errno,
41+
Args: []*configs.Arg{
42+
{
43+
// flags from sched.h
44+
// CLONE_NEWUTS 0x04000000
45+
// CLONE_NEWIPC 0x08000000
46+
// CLONE_NEWUSER 0x10000000
47+
// CLONE_NEWPID 0x20000000
48+
// CLONE_NEWNET 0x40000000
49+
Index: 0,
50+
Value: uint64(0x04000000),
51+
Op: configs.GreaterThanOrEqualTo,
52+
},
53+
{
54+
// flags from sched.h
55+
// CLONE_NEWNS 0x00020000
56+
Index: 0,
57+
Value: uint64(0x00020000),
58+
Op: configs.EqualTo,
59+
},
60+
},
61+
},
62+
{
63+
// Deny manipulation and functions on kernel modules.
64+
Name: "create_module",
65+
Action: configs.Errno,
66+
Args: []*configs.Arg{},
67+
},
68+
{
69+
// Deny manipulation and functions on kernel modules.
70+
Name: "delete_module",
71+
Action: configs.Errno,
72+
Args: []*configs.Arg{},
73+
},
74+
{
75+
// Deny retrieval of exported kernel and module symbols
76+
Name: "get_kernel_syms",
77+
Action: configs.Errno,
78+
Args: []*configs.Arg{},
79+
},
80+
{
81+
// Terrifying syscalls that modify kernel memory and NUMA settings.
82+
// They're gated by CAP_SYS_NICE,
83+
// which we do not retain by default in containers.
84+
Name: "get_mempolicy",
85+
Action: configs.Errno,
86+
Args: []*configs.Arg{},
87+
},
88+
{
89+
// Deny getting the list of robust futexes
90+
Name: "get_robust_list",
91+
Action: configs.Errno,
92+
Args: []*configs.Arg{},
93+
},
94+
{
95+
// Deny manipulation and functions on kernel modules.
96+
Name: "init_module",
97+
Action: configs.Errno,
98+
Args: []*configs.Arg{},
99+
},
100+
{
101+
// Prevent containers from modifying kernel I/O privilege levels.
102+
// Already restricted as containers drop CAP_SYS_RAWIO by default.
103+
Name: "ioperm",
104+
Action: configs.Errno,
105+
Args: []*configs.Arg{},
106+
},
107+
{
108+
// Prevent containers from modifying kernel I/O privilege levels.
109+
// Already restricted as containers drop CAP_SYS_RAWIO by default.
110+
Name: "iopl",
111+
Action: configs.Errno,
112+
Args: []*configs.Arg{},
113+
},
114+
{
115+
// Sister syscall of kexec_load that does the same thing,
116+
// slightly different arguments
117+
Name: "kexec_file_load",
118+
Action: configs.Errno,
119+
Args: []*configs.Arg{},
120+
},
121+
{
122+
// Deny loading a new kernel for later execution
123+
Name: "kexec_load",
124+
Action: configs.Errno,
125+
Args: []*configs.Arg{},
126+
},
127+
{
128+
// Prevent containers from using the kernel keyring,
129+
// which is not namespaced
130+
Name: "keyctl",
131+
Action: configs.Errno,
132+
Args: []*configs.Arg{},
133+
},
134+
{
135+
// Tracing/profiling syscalls,
136+
// which could leak a lot of information on the host
137+
Name: "lookup_dcookie",
138+
Action: configs.Errno,
139+
Args: []*configs.Arg{},
140+
},
141+
{
142+
// Terrifying syscalls that modify kernel memory and NUMA settings.
143+
// They're gated by CAP_SYS_NICE,
144+
// which we do not retain by default in containers.
145+
Name: "mbind",
146+
Action: configs.Errno,
147+
Args: []*configs.Arg{},
148+
},
149+
{
150+
// Terrifying syscalls that modify kernel memory and NUMA settings.
151+
// They're gated by CAP_SYS_NICE,
152+
// which we do not retain by default in containers.
153+
Name: "migrate_pages",
154+
Action: configs.Errno,
155+
Args: []*configs.Arg{},
156+
},
157+
{
158+
// Old syscall only used in 16-bit code,
159+
// and a potential information leak
160+
Name: "modify_ldt",
161+
Action: configs.Errno,
162+
Args: []*configs.Arg{},
163+
},
164+
{
165+
// Deny mount
166+
Name: "mount",
167+
Action: configs.Errno,
168+
Args: []*configs.Arg{},
169+
},
170+
{
171+
// Terrifying syscalls that modify kernel memory and NUMA settings.
172+
// They're gated by CAP_SYS_NICE,
173+
// which we do not retain by default in containers.
174+
Name: "move_pages",
175+
Action: configs.Errno,
176+
Args: []*configs.Arg{},
177+
},
178+
{
179+
// Deny interaction with the kernel nfs daemon
180+
Name: "nfsservctl",
181+
Action: configs.Errno,
182+
Args: []*configs.Arg{},
183+
},
184+
{
185+
// Cause of an old container breakout,
186+
// might as well restrict it to be on the safe side
187+
Name: "open_by_handle_at",
188+
Action: configs.Errno,
189+
Args: []*configs.Arg{},
190+
},
191+
{
192+
// Tracing/profiling syscalls,
193+
// which could leak a lot of information on the host
194+
Name: "perf_event_open",
195+
Action: configs.Errno,
196+
Args: []*configs.Arg{},
197+
},
198+
{
199+
// Prevent container from enabling BSD emulation.
200+
// Not inherently dangerous, but poorly tested,
201+
// potential for a lot of kernel vulns in this.
202+
Name: "personality",
203+
Action: configs.Errno,
204+
Args: []*configs.Arg{},
205+
},
206+
{
207+
// Deny pivot_root
208+
Name: "pivot_root",
209+
Action: configs.Errno,
210+
Args: []*configs.Arg{},
211+
},
212+
{
213+
// Already blocked by dropping CAP_PTRACE
214+
Name: "ptrace",
215+
Action: configs.Errno,
216+
Args: []*configs.Arg{},
217+
},
218+
{
219+
// Deny manipulation and functions on kernel modules.
220+
Name: "query_module",
221+
Action: configs.Errno,
222+
Args: []*configs.Arg{},
223+
},
224+
{
225+
// Quota and Accounting syscalls which could let containers
226+
// disable their own resource limits or process accounting
227+
Name: "quotactl",
228+
Action: configs.Errno,
229+
Args: []*configs.Arg{},
230+
},
231+
{
232+
// Probably a bad idea to let containers reboot the host
233+
Name: "reboot",
234+
Action: configs.Errno,
235+
Args: []*configs.Arg{},
236+
},
237+
{
238+
// Probably a bad idea to let containers restart
239+
Name: "restart_syscall",
240+
Action: configs.Errno,
241+
Args: []*configs.Arg{},
242+
},
243+
{
244+
// Prevent containers from using the kernel keyring,
245+
// which is not namespaced
246+
Name: "request_key",
247+
Action: configs.Errno,
248+
Args: []*configs.Arg{},
249+
},
250+
{
251+
// meta, deny seccomp
252+
Name: "seccomp",
253+
Action: configs.Errno,
254+
Args: []*configs.Arg{},
255+
},
256+
{
257+
// Terrifying syscalls that modify kernel memory and NUMA settings.
258+
// They're gated by CAP_SYS_NICE,
259+
// which we do not retain by default in containers.
260+
Name: "set_mempolicy",
261+
Action: configs.Errno,
262+
Args: []*configs.Arg{},
263+
},
264+
{
265+
// deny associating a thread with a namespace
266+
Name: "setns",
267+
Action: configs.Errno,
268+
Args: []*configs.Arg{},
269+
},
270+
{
271+
// Deny setting the list of robust futexes
272+
Name: "set_robust_list",
273+
Action: configs.Errno,
274+
Args: []*configs.Arg{},
275+
},
276+
{
277+
// Time/Date is not namespaced
278+
Name: "settimeofday",
279+
Action: configs.Errno,
280+
Args: []*configs.Arg{},
281+
},
282+
{
283+
// Deny start/stop swapping to file/device
284+
Name: "swapon",
285+
Action: configs.Errno,
286+
Args: []*configs.Arg{},
287+
},
288+
{
289+
// Deny start/stop swapping to file/device
290+
Name: "swapoff",
291+
Action: configs.Errno,
292+
Args: []*configs.Arg{},
293+
},
294+
{
295+
// Deny read/write system parameters
296+
Name: "_sysctl",
297+
Action: configs.Errno,
298+
Args: []*configs.Arg{},
299+
},
300+
{
301+
// Deny umount
302+
Name: "umount2",
303+
Action: configs.Errno,
304+
Args: []*configs.Arg{},
305+
},
306+
{
307+
// Same as clone
308+
Name: "unshare",
309+
Action: configs.Errno,
310+
Args: []*configs.Arg{},
311+
},
312+
{
313+
// Older syscall related to shared libraries, unused for a long time
314+
Name: "uselib",
315+
Action: configs.Errno,
316+
Args: []*configs.Arg{},
317+
},
318+
},
319+
}

integration-cli/docker_cli_run_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,18 +2858,25 @@ func (s *DockerSuite) TestRunUnshareProc(c *check.C) {
28582858
testRequires(c, Apparmor, DaemonIsLinux, NotUserNamespace)
28592859

28602860
name := "acidburn"
2861-
if out, _, err := dockerCmdWithError("run", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "--mount-proc=/proc", "mount"); err == nil || !strings.Contains(out, "Permission denied") {
2861+
out, _, err := dockerCmdWithError("run", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "--mount-proc=/proc", "mount")
2862+
if err == nil ||
2863+
!(strings.Contains(strings.ToLower(out), "permission denied") ||
2864+
strings.Contains(strings.ToLower(out), "operation not permitted")) {
28622865
c.Fatalf("unshare with --mount-proc should have failed with permission denied, got: %s, %v", out, err)
28632866
}
28642867

28652868
name = "cereal"
2866-
if out, _, err := dockerCmdWithError("run", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc"); err == nil || !strings.Contains(out, "Permission denied") {
2869+
out, _, err = dockerCmdWithError("run", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc")
2870+
if err == nil ||
2871+
!(strings.Contains(strings.ToLower(out), "permission denied") ||
2872+
strings.Contains(strings.ToLower(out), "operation not permitted")) {
28672873
c.Fatalf("unshare and mount of /proc should have failed with permission denied, got: %s, %v", out, err)
28682874
}
28692875

28702876
/* Ensure still fails if running privileged with the default policy */
28712877
name = "crashoverride"
2872-
if out, _, err := dockerCmdWithError("run", "--privileged", "--security-opt", "apparmor:docker-default", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc"); err == nil || !(strings.Contains(strings.ToLower(out), "permission denied") || strings.Contains(strings.ToLower(out), "operation not permitted")) {
2878+
out, _, err = dockerCmdWithError("run", "--privileged", "--security-opt", "apparmor:docker-default", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc")
2879+
if err == nil || !(strings.Contains(strings.ToLower(out), "permission denied") || strings.Contains(strings.ToLower(out), "operation not permitted")) {
28732880
c.Fatalf("privileged unshare with apparmor should have failed with permission denied, got: %s, %v", out, err)
28742881
}
28752882
}

0 commit comments

Comments
 (0)