[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