فهرست منبع

Merge pull request #18178 from jfrazelle/apparmor-we-meet-again

Fix docker-default profile handing signals
Jess Frazelle 9 سال پیش
والد
کامیت
e852959fad
4فایلهای تغییر یافته به همراه73 افزوده شده و 30 حذف شده
  1. 3 30
      contrib/apparmor/main.go
  2. 5 0
      contrib/apparmor/template.go
  3. 20 0
      daemon/execdriver/native/apparmor.go
  4. 45 0
      pkg/aaparser/aaparser.go

+ 3 - 30
contrib/apparmor/main.go

@@ -4,11 +4,10 @@ import (
 	"fmt"
 	"log"
 	"os"
-	"os/exec"
 	"path"
-	"strconv"
-	"strings"
 	"text/template"
+
+	"github.com/docker/docker/pkg/aaparser"
 )
 
 type profileData struct {
@@ -24,33 +23,7 @@ func main() {
 	// parse the arg
 	apparmorProfilePath := os.Args[1]
 
-	// get the apparmor_version version
-	cmd := exec.Command("/sbin/apparmor_parser", "--version")
-
-	output, err := cmd.CombinedOutput()
-	if err != nil {
-		log.Fatalf("getting apparmor_parser version failed: %s (%s)", err, output)
-	}
-
-	// parse the version from the output
-	// output is in the form of the following:
-	// AppArmor parser version 2.9.1
-	// Copyright (C) 1999-2008 Novell Inc.
-	// Copyright 2009-2012 Canonical Ltd.
-	lines := strings.SplitN(string(output), "\n", 2)
-	words := strings.Split(lines[0], " ")
-	version := words[len(words)-1]
-	// split by major minor version
-	v := strings.Split(version, ".")
-	if len(v) < 2 {
-		log.Fatalf("parsing major minor version failed for %q", version)
-	}
-
-	majorVersion, err := strconv.Atoi(v[0])
-	if err != nil {
-		log.Fatal(err)
-	}
-	minorVersion, err := strconv.Atoi(v[1])
+	majorVersion, minorVersion, err := aaparser.GetVersion()
 	if err != nil {
 		log.Fatal(err)
 	}

+ 5 - 0
contrib/apparmor/template.go

@@ -33,14 +33,19 @@ profile /usr/bin/docker (attach_disconnected, complain) {
   @{DOCKER_GRAPH_PATH}/linkgraph.db k,
   @{DOCKER_GRAPH_PATH}/network/files/boltdb.db k,
   @{DOCKER_GRAPH_PATH}/network/files/local-kv.db k,
+  @{DOCKER_GRAPH_PATH}/[0-9]*.[0-9]*/linkgraph.db k,
 
   # For non-root client use:
   /dev/urandom r,
+  /dev/null rw,
+  /dev/pts/[0-9]* rw,
   /run/docker.sock rw,
   /proc/** r,
+  /proc/[0-9]*/attr/exec w,
   /sys/kernel/mm/hugepages/ r,
   /etc/localtime r,
   /etc/ld.so.cache r,
+  /etc/passwd r,
 
 {{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}}
   ptrace peer=@{profile_name},

+ 20 - 0
daemon/execdriver/native/apparmor.go

@@ -12,6 +12,7 @@ import (
 	"strings"
 	"text/template"
 
+	"github.com/docker/docker/pkg/aaparser"
 	"github.com/opencontainers/runc/libcontainer/apparmor"
 )
 
@@ -21,8 +22,11 @@ const (
 
 type data struct {
 	Name         string
+	ExecPath     string
 	Imports      []string
 	InnerImports []string
+	MajorVersion int
+	MinorVersion int
 }
 
 const baseTemplate = `
@@ -55,6 +59,14 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) {
   deny /sys/fs/cg[^r]*/** wklx,
   deny /sys/firmware/efi/efivars/** rwklx,
   deny /sys/kernel/security/** rwklx,
+
+{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}}
+  # docker daemon confinement requires explict allow rule for signal
+  signal (receive) set=(kill,term) peer={{.ExecPath}},
+
+  # suppress ptrace denails when using 'docker ps'
+  ptrace (trace,read) peer=docker-default,
+{{end}}{{end}}
 }
 `
 
@@ -74,6 +86,14 @@ func generateProfile(out io.Writer) error {
 	if abstractionsExists() {
 		data.InnerImports = append(data.InnerImports, "#include <abstractions/base>")
 	}
+	data.MajorVersion, data.MinorVersion, err = aaparser.GetVersion()
+	if err != nil {
+		return err
+	}
+	data.ExecPath, err = exec.LookPath("docker")
+	if err != nil {
+		return err
+	}
 	if err := compiled.Execute(out, data); err != nil {
 		return err
 	}

+ 45 - 0
pkg/aaparser/aaparser.go

@@ -0,0 +1,45 @@
+package aaparser
+
+import (
+	"fmt"
+	"log"
+	"os/exec"
+	"strconv"
+	"strings"
+)
+
+// GetVersion returns the major and minor version of apparmor_parser
+func GetVersion() (int, int, error) {
+	// get the apparmor_version version
+	cmd := exec.Command("apparmor_parser", "--version")
+
+	output, err := cmd.CombinedOutput()
+	if err != nil {
+		log.Fatalf("getting apparmor_parser version failed: %s (%s)", err, output)
+	}
+
+	// parse the version from the output
+	// output is in the form of the following:
+	// AppArmor parser version 2.9.1
+	// Copyright (C) 1999-2008 Novell Inc.
+	// Copyright 2009-2012 Canonical Ltd.
+	lines := strings.SplitN(string(output), "\n", 2)
+	words := strings.Split(lines[0], " ")
+	version := words[len(words)-1]
+	// split by major minor version
+	v := strings.Split(version, ".")
+	if len(v) < 2 {
+		return -1, -1, fmt.Errorf("parsing major minor version failed for %q", version)
+	}
+
+	majorVersion, err := strconv.Atoi(v[0])
+	if err != nil {
+		return -1, -1, err
+	}
+	minorVersion, err := strconv.Atoi(v[1])
+	if err != nil {
+		return -1, -1, err
+	}
+
+	return majorVersion, minorVersion, nil
+}