[lxc-devel] [lxd/master] Apparmor cleanup ahead of forkproxy support

stgraber on Github lxc-bot at linuxcontainers.org
Wed Aug 26 03:10:01 UTC 2020


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/20200825/31fdbc51/attachment-0001.bin>
-------------- next part --------------
From 27483f1c63f149140c585460d82e016505050b60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 14 Aug 2020 15:46:11 -0400
Subject: [PATCH 1/5] lxd/apparmor: Simplify profile name generation
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/apparmor/apparmor.go        | 23 +++++++++++++++++++++++
 lxd/apparmor/instance.go        | 32 +++-----------------------------
 lxd/apparmor/network_dnsmasq.go | 23 ++---------------------
 lxd/apparmor/network_forkdns.go | 23 ++---------------------
 4 files changed, 30 insertions(+), 71 deletions(-)

diff --git a/lxd/apparmor/apparmor.go b/lxd/apparmor/apparmor.go
index 374a7ca756..ffb9491f56 100644
--- a/lxd/apparmor/apparmor.go
+++ b/lxd/apparmor/apparmor.go
@@ -1,7 +1,9 @@
 package apparmor
 
 import (
+	"crypto/sha256"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -234,3 +236,24 @@ func getCacheDir(state *state.State) (string, error) {
 
 	return strings.TrimSpace(output), nil
 }
+
+// profileName handles generating valid profile names.
+func profileName(prefix string, name string) string {
+	separators := 1
+	if len(prefix) > 0 {
+		separators = 2
+	}
+
+	// Max length in AppArmor is 253 chars.
+	if len(name)+len(prefix)+3+separators >= 253 {
+		hash := sha256.New()
+		io.WriteString(hash, name)
+		name = fmt.Sprintf("%x", hash.Sum(nil))
+	}
+
+	if len(prefix) > 0 {
+		return fmt.Sprintf("lxd_%s-%s", prefix, name)
+	}
+
+	return fmt.Sprintf("lxd-%s", name)
+}
diff --git a/lxd/apparmor/instance.go b/lxd/apparmor/instance.go
index 1944f7bb4b..497132776b 100644
--- a/lxd/apparmor/instance.go
+++ b/lxd/apparmor/instance.go
@@ -1,9 +1,7 @@
 package apparmor
 
 import (
-	"crypto/sha256"
 	"fmt"
-	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -28,15 +26,7 @@ type instance interface {
 func InstanceProfileName(inst instance) string {
 	path := shared.VarPath("")
 	name := fmt.Sprintf("%s_<%s>", project.Instance(inst.Project(), inst.Name()), path)
-
-	// Max length in AppArmor is 253 chars.
-	if len(name)+4 >= 253 {
-		hash := sha256.New()
-		io.WriteString(hash, name)
-		name = fmt.Sprintf("%x", hash.Sum(nil))
-	}
-
-	return fmt.Sprintf("lxd-%s", name)
+	return profileName("", name)
 }
 
 // InstanceNamespaceName returns the instance's AppArmor namespace.
@@ -44,29 +34,13 @@ func InstanceNamespaceName(inst instance) string {
 	// Unlike in profile names, / isn't an allowed character so replace with a -.
 	path := strings.Replace(strings.Trim(shared.VarPath(""), "/"), "/", "-", -1)
 	name := fmt.Sprintf("%s_<%s>", project.Instance(inst.Project(), inst.Name()), path)
-
-	// Max length in AppArmor is 253 chars.
-	if len(name)+4 >= 253 {
-		hash := sha256.New()
-		io.WriteString(hash, name)
-		name = fmt.Sprintf("%x", hash.Sum(nil))
-	}
-
-	return fmt.Sprintf("lxd-%s", name)
+	return profileName("", name)
 }
 
 // instanceProfileFilename returns the name of the on-disk profile name.
 func instanceProfileFilename(inst instance) string {
 	name := project.Instance(inst.Project(), inst.Name())
-
-	// Max length in AppArmor is 253 chars.
-	if len(name)+4 >= 253 {
-		hash := sha256.New()
-		io.WriteString(hash, name)
-		name = fmt.Sprintf("%x", hash.Sum(nil))
-	}
-
-	return fmt.Sprintf("lxd-%s", name)
+	return profileName("", name)
 }
 
 // InstanceLoad ensures that the instances's policy is loaded into the kernel so the it can boot.
diff --git a/lxd/apparmor/network_dnsmasq.go b/lxd/apparmor/network_dnsmasq.go
index f411627753..7fec180d52 100644
--- a/lxd/apparmor/network_dnsmasq.go
+++ b/lxd/apparmor/network_dnsmasq.go
@@ -1,9 +1,7 @@
 package apparmor
 
 import (
-	"crypto/sha256"
 	"fmt"
-	"io"
 	"strings"
 	"text/template"
 
@@ -92,27 +90,10 @@ func dnsmasqProfile(state *state.State, n network) (string, error) {
 func DnsmasqProfileName(n network) string {
 	path := shared.VarPath("")
 	name := fmt.Sprintf("%s_<%s>", n.Name(), path)
-
-	// Max length in AppArmor is 253 chars.
-	if len(name)+12 >= 253 {
-		hash := sha256.New()
-		io.WriteString(hash, name)
-		name = fmt.Sprintf("%x", hash.Sum(nil))
-	}
-
-	return fmt.Sprintf("lxd_dnsmasq-%s", name)
+	return profileName("dnsmasq", name)
 }
 
 // dnsmasqProfileFilename returns the name of the on-disk profile name.
 func dnsmasqProfileFilename(n network) string {
-	name := n.Name()
-
-	// Max length in AppArmor is 253 chars.
-	if len(name)+12 >= 253 {
-		hash := sha256.New()
-		io.WriteString(hash, name)
-		name = fmt.Sprintf("%x", hash.Sum(nil))
-	}
-
-	return fmt.Sprintf("lxd_dnsmasq-%s", name)
+	return profileName("dnsmasq", n.Name())
 }
diff --git a/lxd/apparmor/network_forkdns.go b/lxd/apparmor/network_forkdns.go
index 8aaf43f8e2..040caf84aa 100644
--- a/lxd/apparmor/network_forkdns.go
+++ b/lxd/apparmor/network_forkdns.go
@@ -1,9 +1,7 @@
 package apparmor
 
 import (
-	"crypto/sha256"
 	"fmt"
-	"io"
 	"strings"
 	"text/template"
 
@@ -73,27 +71,10 @@ func forkdnsProfile(state *state.State, n network) (string, error) {
 func ForkdnsProfileName(n network) string {
 	path := shared.VarPath("")
 	name := fmt.Sprintf("%s_<%s>", n.Name(), path)
-
-	// Max length in AppArmor is 253 chars.
-	if len(name)+12 >= 253 {
-		hash := sha256.New()
-		io.WriteString(hash, name)
-		name = fmt.Sprintf("%x", hash.Sum(nil))
-	}
-
-	return fmt.Sprintf("lxd_forkdns-%s", name)
+	return profileName("forkdns", name)
 }
 
 // forkdnsProfileFilename returns the name of the on-disk profile name.
 func forkdnsProfileFilename(n network) string {
-	name := n.Name()
-
-	// Max length in AppArmor is 253 chars.
-	if len(name)+12 >= 253 {
-		hash := sha256.New()
-		io.WriteString(hash, name)
-		name = fmt.Sprintf("%x", hash.Sum(nil))
-	}
-
-	return fmt.Sprintf("lxd_forkdns-%s", name)
+	return profileName("forkdns", n.Name())
 }

From dadf92f91fceb102eb512c0be11041afe7d1add3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 25 Aug 2020 22:12:59 -0400
Subject: [PATCH 2/5] lxd/device: Export Name and Config
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/device/device_common.go | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lxd/device/device_common.go b/lxd/device/device_common.go
index dcd59092f9..4de9509d01 100644
--- a/lxd/device/device_common.go
+++ b/lxd/device/device_common.go
@@ -42,6 +42,16 @@ func (d *deviceCommon) init(inst instance.Instance, state *state.State, name str
 	d.volatileSet = volatileSet
 }
 
+// Name returns the name of the device.
+func (d *deviceCommon) Name() string {
+	return d.name
+}
+
+// Config returns the config for the device.
+func (d *deviceCommon) Config() deviceConfig.Device {
+	return d.config
+}
+
 // Add returns nil error as majority of devices don't need to do any host-side setup.
 func (d *deviceCommon) Add() error {
 	return nil

From 32bfa9dcd7d7dccf8568673e73f61b71907227e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 25 Aug 2020 22:26:29 -0400
Subject: [PATCH 3/5] lxd/apparmor: Shrink instance interface
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/apparmor/instance.go | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/lxd/apparmor/instance.go b/lxd/apparmor/instance.go
index 497132776b..1ae6f64b80 100644
--- a/lxd/apparmor/instance.go
+++ b/lxd/apparmor/instance.go
@@ -17,8 +17,6 @@ import (
 type instance interface {
 	Project() string
 	Name() string
-	IsNesting() bool
-	IsPrivileged() bool
 	ExpandedConfig() map[string]string
 }
 
@@ -138,9 +136,9 @@ func instanceProfile(state *state.State, inst instance) (string, error) {
 		"feature_cgroup2":  state.OS.CGInfo.Layout == cgroup.CgroupsUnified || state.OS.CGInfo.Layout == cgroup.CgroupsHybrid,
 		"feature_stacking": state.OS.AppArmorStacking && !state.OS.AppArmorStacked,
 		"namespace":        InstanceNamespaceName(inst),
-		"nesting":          inst.IsNesting(),
+		"nesting":          shared.IsTrue(inst.ExpandedConfig()["security.nesting"]),
 		"name":             InstanceProfileName(inst),
-		"unprivileged":     !inst.IsPrivileged() || state.OS.RunningInUserNS,
+		"unprivileged":     !shared.IsTrue(inst.ExpandedConfig()["security.privileged"]) || state.OS.RunningInUserNS,
 		"raw":              rawContent,
 	})
 	if err != nil {

From 49612407f0036a826169ec13eb7f6da11e23b862 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 25 Aug 2020 22:40:01 -0400
Subject: [PATCH 4/5] lxd/apparmor/forkdns: Alignment
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/apparmor/network_forkdns.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/apparmor/network_forkdns.go b/lxd/apparmor/network_forkdns.go
index 040caf84aa..650eaea2bd 100644
--- a/lxd/apparmor/network_forkdns.go
+++ b/lxd/apparmor/network_forkdns.go
@@ -39,7 +39,7 @@ profile "{{ .name }}" flags=(attach_disconnected,mediate_deleted) {
   /snap/lxd/*/bin/lxd                 mr,
 
   # Snap-specific libraries
-  /snap/lxd/*/lib/**.so*                  mr,
+  /snap/lxd/*/lib/**.so*              mr,
 {{- end }}
 }
 `))

From d5d720600402b42b8f4c84b9859dc14b35be99cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 25 Aug 2020 23:07:08 -0400
Subject: [PATCH 5/5] lxd/apparmor/forkdns: Support LD_LIBRARY_PATH
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/apparmor/network_forkdns.go | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lxd/apparmor/network_forkdns.go b/lxd/apparmor/network_forkdns.go
index 650eaea2bd..b9e66f9791 100644
--- a/lxd/apparmor/network_forkdns.go
+++ b/lxd/apparmor/network_forkdns.go
@@ -2,6 +2,7 @@ package apparmor
 
 import (
 	"fmt"
+	"os"
 	"strings"
 	"text/template"
 
@@ -41,6 +42,13 @@ profile "{{ .name }}" flags=(attach_disconnected,mediate_deleted) {
   # Snap-specific libraries
   /snap/lxd/*/lib/**.so*              mr,
 {{- end }}
+
+{{if .libraryPath -}}
+  # Entries from LD_LIBRARY_PATH
+{{range $index, $element := .libraryPath}}
+  {{$element}}/** mr,
+{{- end }}
+{{- end }}
 }
 `))
 
@@ -59,6 +67,7 @@ func forkdnsProfile(state *state.State, n network) (string, error) {
 		"varPath":     shared.VarPath(""),
 		"rootPath":    rootPath,
 		"snap":        shared.InSnap(),
+		"libraryPath": strings.Split(os.Getenv("LD_LIBRARY_PATH"), ":"),
 	})
 	if err != nil {
 		return "", err


More information about the lxc-devel mailing list