[lxc-devel] [lxd/master] Add shift protection support

stgraber on Github lxc-bot at linuxcontainers.org
Wed Dec 12 20:28:40 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20181212/2bf0a438/attachment.bin>
-------------- next part --------------
From a49ae38a410aa03d2c38f2ebc2e3d1d232b959d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 12 Dec 2018 14:48:14 -0500
Subject: [PATCH 1/2] lxd/containers: Drop needless function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container.go     | 1 -
 lxd/container_lxc.go | 6 +-----
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/lxd/container.go b/lxd/container.go
index d9ca44c7bb..23432e4718 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -615,7 +615,6 @@ type container interface {
 	IsSnapshot() bool
 	IsStateful() bool
 	IsNesting() bool
-	IsDeleteProtected() bool
 
 	// Hooks
 	OnStart() error
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index f0b665083a..774c35324b 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -3409,7 +3409,7 @@ func (c *containerLXC) Delete() error {
 
 	logger.Info("Deleting container", ctxMap)
 
-	if c.IsDeleteProtected() && !c.IsSnapshot() {
+	if shared.IsTrue(c.expandedConfig["security.protection.delete"]) && !c.IsSnapshot() {
 		err := fmt.Errorf("Container is protected")
 		logger.Warn("Failed to delete container", log.Ctx{"name": c.Name(), "err": err})
 		return err
@@ -8524,10 +8524,6 @@ func (c *containerLXC) IsSnapshot() bool {
 	return c.cType == db.CTypeSnapshot
 }
 
-func (c *containerLXC) IsDeleteProtected() bool {
-	return shared.IsTrue(c.expandedConfig["security.protection.delete"])
-}
-
 // Various property query functions
 func (c *containerLXC) Architecture() int {
 	return c.architecture

From c3404b7aaee0648418c9935d0ee3fbab6af79c76 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 12 Dec 2018 15:27:42 -0500
Subject: [PATCH 2/2] Implement shift protection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #5349

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/api-extensions.md   |  4 ++++
 doc/containers.md       |  1 +
 lxd/container_lxc.go    |  8 ++++++++
 scripts/bash/lxd-client |  4 ++--
 shared/container.go     |  1 +
 shared/version/api.go   |  1 +
 test/suites/security.sh | 31 ++++++++++++++++++++++++++-----
 7 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index d95aa2fce6..12656d6d30 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -668,3 +668,7 @@ joining server).
 Enable image replication across the nodes in the cluster.
 A new cluster.images_minimal_replica configuration key was introduced can be used
 to specify to the minimal numbers of nodes for image replication.
+
+## container\_protection\_shift
+Enables setting the `security.protection.shift` option which prevents containers
+from having their filesystem shifted.
diff --git a/doc/containers.md b/doc/containers.md
index 1ffa09448d..4881681949 100644
--- a/doc/containers.md
+++ b/doc/containers.md
@@ -73,6 +73,7 @@ security.idmap.size                     | integer   | -                 | no
 security.nesting                        | boolean   | false             | yes           | -                                    | Support running lxd (nested) inside the container
 security.privileged                     | boolean   | false             | no            | -                                    | Runs the container in privileged mode
 security.protection.delete              | boolean   | false             | yes           | container\_protection\_delete        | Prevents the container from being deleted
+security.protection.shift               | boolean   | false             | yes           | container\_protection\_shift         | Prevents the container's filesystem from being uid/gid shifted on startup
 security.syscalls.blacklist             | string    | -                 | no            | container\_syscall\_filtering        | A '\n' separated list of syscalls to blacklist
 security.syscalls.blacklist\_compat     | boolean   | false             | no            | container\_syscall\_filtering        | On x86\_64 this enables blocking of compat\_\* syscalls, it is a no-op on other arches
 security.syscalls.blacklist\_default    | boolean   | true              | no            | container\_syscall\_filtering        | Enables the default syscall blacklist
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 774c35324b..852c4618dd 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1953,6 +1953,10 @@ func (c *containerLXC) startCommon() (string, error) {
 	}
 
 	if !reflect.DeepEqual(idmap, lastIdmap) {
+		if shared.IsTrue(c.expandedConfig["security.protection.shift"]) {
+			return "", fmt.Errorf("Container is protected against filesystem shifting")
+		}
+
 		logger.Debugf("Container idmap changed, remapping")
 		c.updateProgress("Remapping container filesystem")
 
@@ -4998,6 +5002,10 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 	}
 
 	if idmap != nil {
+		if !c.IsSnapshot() && shared.IsTrue(c.expandedConfig["security.protection.shift"]) {
+			return fmt.Errorf("Container is protected against filesystem shifting")
+		}
+
 		var err error
 
 		if c.Storage().GetStorageType() == storageTypeZfs {
diff --git a/scripts/bash/lxd-client b/scripts/bash/lxd-client
index 39d3f35fc7..69420a6d4a 100644
--- a/scripts/bash/lxd-client
+++ b/scripts/bash/lxd-client
@@ -88,8 +88,8 @@ _have lxc && {
       raw.seccomp security.idmap.base security.idmap.isolated \
       security.idmap.size security.devlxd security.devlxd.images \
       security.nesting security.privileged security.protection.delete \
-      security.syscalls.blacklist security.syscalls.blacklist_compat \
-      security.syscalls.blacklist_default \
+      security.protection.shift security.syscalls.blacklist \
+      security.syscalls.blacklist_compat security.syscalls.blacklist_default \
       volatile.apply_quota volatile.apply_template volatile.base_image \
       volatile.idmap.base volatile.idmap.next volatile.last_state.idmap \
       volatile.last_state.power user.meta-data user.network-config \
diff --git a/shared/container.go b/shared/container.go
index cbcd2497cd..266c48fca0 100644
--- a/shared/container.go
+++ b/shared/container.go
@@ -256,6 +256,7 @@ var KnownContainerConfigKeys = map[string]func(value string) error{
 	"security.devlxd.images": IsBool,
 
 	"security.protection.delete": IsBool,
+	"security.protection.shift":  IsBool,
 
 	"security.idmap.base":     IsUint32,
 	"security.idmap.isolated": IsBool,
diff --git a/shared/version/api.go b/shared/version/api.go
index 12c3f56b6d..429133dbc2 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -135,6 +135,7 @@ var APIExtensions = []string{
 	"container_copy_project",
 	"clustering_server_address",
 	"clustering_image_replication",
+	"container_protection_shift",
 }
 
 // APIExtensionsCount returns the number of available API extensions.
diff --git a/test/suites/security.sh b/test/suites/security.sh
index b5bfa06aad..9a1459e9cd 100644
--- a/test/suites/security.sh
+++ b/test/suites/security.sh
@@ -112,22 +112,43 @@ test_security_protection() {
   ensure_import_testimage
   ensure_has_localhost_remote "${LXD_ADDR}"
 
-  lxc launch testimage c1
-  lxc stop c1 --force
+  # Test deletion protecton
+  lxc init testimage c1
   lxc snapshot c1
   lxc delete c1
 
   lxc profile set default security.protection.delete true
 
-  lxc launch testimage c1
-  lxc stop c1 --force
+  lxc init testimage c1
   lxc snapshot c1
   lxc delete c1/snap0
   ! lxc delete c1
 
-  # override setting
   lxc config set c1 security.protection.delete false
   lxc delete c1
 
   lxc profile unset default security.protection.delete
+
+  # Test shifting protection
+  lxc init testimage c1
+  lxc start c1
+  lxc stop c1 --force
+
+  lxc profile set default security.protection.shift true
+  lxc start c1
+  lxc stop c1 --force
+
+  ! lxc publish c1 --alias=protected
+  lxc snapshot c1
+  lxc publish c1/snap0 --alias=protected
+  lxc image delete protected
+
+  lxc config set c1 security.privileged true
+  ! lxc start c1
+  lxc config set c1 security.protection.shift false
+  lxc start c1
+  lxc stop c1 --force
+
+  lxc delete c1
+  lxc profile unset default security.protection.shift
 }


More information about the lxc-devel mailing list