The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2041

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
In particular,

* make the default seccomp config optional
* add a knob to block x32 syscalls on amd64 (enabled by default)
* add a way for users to inject their own seccomp stuff

Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
From 5b04f732976ff84ea54ee828274ef88aad066796 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.ander...@canonical.com>
Date: Mon, 23 May 2016 09:40:06 -0600
Subject: [PATCH] add some seccomp knobs

In particular,

* make the default seccomp config optional
* add a knob to block x32 syscalls on amd64 (enabled by default)
* add a way for users to inject their own seccomp stuff

Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
---
 doc/configuration.md |  3 ++
 lxd/container.go     |  6 ++++
 lxd/container_lxc.go | 10 +++---
 lxd/seccomp.go       | 92 +++++++++++++++++++++++++++++++++++++++++++++++++---
 test/suites/basic.sh | 11 +++++++
 5 files changed, 114 insertions(+), 8 deletions(-)

diff --git a/doc/configuration.md b/doc/configuration.md
index 9c94db7..d4a1afb 100644
--- a/doc/configuration.md
+++ b/doc/configuration.md
@@ -83,9 +83,12 @@ limits.processes            | integer   | - (max)       | 
yes           | Maximu
 linux.kernel\_modules       | string    | -             | yes           | 
Comma separated list of kernel modules to load before starting the container
 raw.apparmor                | blob      | -             | yes           | 
Apparmor profile entries to be appended to the generated profile
 raw.lxc                     | blob      | -             | no            | Raw 
LXC configuration to be appended to the generated one
+raw.seccomp                 | blob      | -             | no            | Raw 
LXC seccomp profile string to append to the generated one
 security.nesting            | boolean   | false         | yes           | 
Support running lxd (nested) inside the container
 security.privileged         | boolean   | false         | no            | Runs 
the container in privileged mode
 user.\*                     | string    | -             | n/a           | Free 
form user key/value storage (can be used in search)
+security.syscalls.default   | boolean   | true          | no            | 
Enables the default syscall blacklist
+security.syscalls.compat    | boolean   | true          | no            | On 
x86\_64 this enables blocking of compat\_\* syscalls, it is a no-op on other 
arches
 
 The following volatile keys are currently internally used by LXD:
 
diff --git a/lxd/container.go b/lxd/container.go
index 9c196ca..7da08ec 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -109,10 +109,16 @@ func containerValidConfigKey(key string, value string) 
error {
                return isBool(key, value)
        case "security.nesting":
                return isBool(key, value)
+       case "security.syscalls.default":
+               return isBool(key, value)
+       case "security.syscalls.compat":
+               return isBool(key, value)
        case "raw.apparmor":
                return nil
        case "raw.lxc":
                return lxcValidConfig(value)
+       case "raw.seccomp":
+               return nil
        case "volatile.apply_template":
                return nil
        case "volatile.base_image":
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 6aa3510..0cccd49 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -466,10 +466,12 @@ func (c *containerLXC) initLXC() error {
                }
        }
 
-       // Setup Seccomp
-       err = lxcSetConfigItem(cc, "lxc.seccomp", SeccompProfilePath(c))
-       if err != nil {
-               return err
+       // Setup Seccomp if necessary
+       if ContainerNeedsSeccomp(c) {
+               err = lxcSetConfigItem(cc, "lxc.seccomp", SeccompProfilePath(c))
+               if err != nil {
+                       return err
+               }
        }
 
        // Setup idmap
diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index 11817a9..9e4a18d 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -8,9 +8,12 @@ import (
        "github.com/lxc/lxd/shared"
 )
 
-const DEFAULT_SECCOMP_POLICY = `
+const SECCOMP_HEADER = `
 2
 blacklist
+`
+
+const DEFAULT_SECCOMP_POLICY = `
 reject_force_umount  # comment this to allow umount -f;  not recommended
 [all]
 kexec_load errno 1
@@ -19,16 +22,93 @@ init_module errno 1
 finit_module errno 1
 delete_module errno 1
 `
-
+const COMPAT_BLOCKING_POLICY = `
+[x86_64]
+compat_sys_rt_sigaction
+stub_x32_rt_sigreturn
+compat_sys_ioctl
+compat_sys_readv
+compat_sys_writev
+compat_sys_recvfrom
+compat_sys_sendmsg
+compat_sys_recvmsg
+stub_x32_execve
+compat_sys_ptrace
+compat_sys_rt_sigpending
+compat_sys_rt_sigtimedwait
+compat_sys_rt_sigqueueinfo
+compat_sys_sigaltstack
+compat_sys_timer_create
+compat_sys_mq_notify
+compat_sys_kexec_load
+compat_sys_waitid
+compat_sys_set_robust_list
+compat_sys_get_robust_list
+compat_sys_vmsplice
+compat_sys_move_pages
+compat_sys_preadv64
+compat_sys_pwritev64
+compat_sys_rt_tgsigqueueinfo
+compat_sys_recvmmsg
+compat_sys_sendmmsg
+compat_sys_process_vm_readv
+compat_sys_process_vm_writev
+compat_sys_setsockopt
+compat_sys_getsockopt
+compat_sys_io_setup
+compat_sys_io_submit
+stub_x32_execveat
+`
 var seccompPath = shared.VarPath("security", "seccomp")
 
 func SeccompProfilePath(c container) string {
        return path.Join(seccompPath, c.Name())
 }
 
+func ContainerNeedsSeccomp(c container) bool {
+       config := c.ExpandedConfig()
+
+       /* these are enabled by default, so if the keys aren't present, that
+        * means "true"
+        */
+       default_, ok := config["security.syscalls.default"]
+       if !ok || shared.IsTrue(default_) {
+               return true
+       }
+
+       compat, ok := config["security.syscalls.compat"]
+       if !ok || shared.IsTrue(compat) {
+               return true
+       }
+
+       raw := config["raw.seccomp"]
+       if raw != "" {
+               return true
+       }
+
+       return false
+}
+
 func getSeccompProfileContent(c container) string {
-       /* for now there are no seccomp knobs. */
-       return DEFAULT_SECCOMP_POLICY
+       config := c.ExpandedConfig()
+       policy := SECCOMP_HEADER
+
+       default_, ok := config["security.syscalls.default"]
+       if !ok || shared.IsTrue(default_) {
+               policy += DEFAULT_SECCOMP_POLICY
+       }
+
+       compat, ok := config["security.syscalls.compat"]
+       if !ok || shared.IsTrue(compat) {
+               policy += COMPAT_BLOCKING_POLICY
+       }
+
+       raw := config["raw.seccomp"]
+       if raw != "" {
+               policy += raw
+       }
+
+       return policy
 }
 
 func SeccompCreateProfile(c container) error {
@@ -38,6 +118,10 @@ func SeccompCreateProfile(c container) error {
         * the mtime on the file for any compiler purpose, so let's just write
         * out the profile.
         */
+       if !ContainerNeedsSeccomp(c) {
+               return nil
+       }
+
        profile := getSeccompProfileContent(c)
        if err := os.MkdirAll(seccompPath, 0700); err != nil {
                return err
diff --git a/test/suites/basic.sh b/test/suites/basic.sh
index b2f3eef..df52e82 100644
--- a/test/suites/basic.sh
+++ b/test/suites/basic.sh
@@ -250,6 +250,17 @@ test_basic_usage() {
   lxc delete lxd-apparmor-test
   [ ! -f "${LXD_DIR}/security/apparmor/profiles/lxd-lxd-apparmor-test" ]
 
+  lxc launch testimage lxd-seccomp-test
+  init=$(lxc info lxd-seccomp-test | grep Pid | cut -f2 -d" ")
+  [ "$(grep Seccomp /proc/${init}/status | cut -f2)" -eq "2" ]
+  lxc stop --force lxd-seccomp-test
+  lxc config set testimage security.syscalls.default false
+  lxc config set testimage security.syscalls.compat false
+  lxc start lxd-seccomp-test
+  init=$(lxc info lxd-seccomp-test | grep Pid | cut -f2 -d" ")
+  [ "$(grep Seccomp /proc/${init}/status | cut -f2)" -eq "0" ]
+  lxc stop --force lxd-seccomp-test
+
   # make sure that privileged containers are not world-readable
   lxc profile create unconfined
   lxc profile set unconfined security.privileged true
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to