Merge pull request #4467 from cyphar/apparmor-update-profile

apparmor: handle signal mediation
This commit is contained in:
Akihiro Suda 2021-03-09 10:55:01 +09:00 committed by GitHub
commit 9ec2778950
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 4 deletions

View File

@ -1,6 +1,8 @@
// +build linux // +build linux
/* /*
Copyright The docker Authors.
Copyright The Moby Authors.
Copyright The containerd Authors. Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -22,6 +24,7 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@ -32,6 +35,10 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// NOTE: This code is copied from <github.com/docker/docker/profiles/apparmor>.
// If you plan to make any changes, please make sure they are also sent
// upstream.
const dir = "/etc/apparmor.d" const dir = "/etc/apparmor.d"
const defaultTemplate = ` const defaultTemplate = `
@ -48,6 +55,14 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) {
capability, capability,
file, file,
umount, umount,
{{if ge .Version 208096}}
# Host (privileged) processes may send signals to container processes.
signal (receive) peer=unconfined,
# Manager may send signals to container processes.
signal (receive) peer={{.DaemonProfile}},
# Container processes may send signals amongst themselves.
signal (send,receive) peer={{.Name}},
{{end}}
deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir) deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir)
# deny write to files not in /proc/<number>/** or /proc/sys/** # deny write to files not in /proc/<number>/** or /proc/sys/**
@ -79,9 +94,22 @@ type data struct {
Name string Name string
Imports []string Imports []string
InnerImports []string InnerImports []string
DaemonProfile string
Version int Version int
} }
func cleanProfileName(profile string) string {
// Normally profiles are suffixed by " (enforce)". AppArmor profiles cannot
// contain spaces so this doesn't restrict daemon profile names.
if parts := strings.SplitN(profile, " ", 2); len(parts) >= 1 {
profile = parts[0]
}
if profile == "" {
profile = "unconfined"
}
return profile
}
func loadData(name string) (*data, error) { func loadData(name string) (*data, error) {
p := data{ p := data{
Name: name, Name: name,
@ -100,6 +128,16 @@ func loadData(name string) (*data, error) {
return nil, errors.Wrap(err, "get apparmor_parser version") return nil, errors.Wrap(err, "get apparmor_parser version")
} }
p.Version = ver p.Version = ver
// Figure out the daemon profile.
currentProfile, err := ioutil.ReadFile("/proc/self/attr/current")
if err != nil {
// If we couldn't get the daemon profile, assume we are running
// unconfined which is generally the default.
currentProfile = nil
}
p.DaemonProfile = cleanProfileName(string(currentProfile))
return &p, nil return &p, nil
} }

View File

@ -0,0 +1,18 @@
// +build linux
package apparmor
import (
"testing"
"gotest.tools/v3/assert"
)
func TestCleanProfileName(t *testing.T) {
assert.Equal(t, cleanProfileName(""), "unconfined")
assert.Equal(t, cleanProfileName("unconfined"), "unconfined")
assert.Equal(t, cleanProfileName("unconfined (enforce)"), "unconfined")
assert.Equal(t, cleanProfileName("docker-default"), "docker-default")
assert.Equal(t, cleanProfileName("foo"), "foo")
assert.Equal(t, cleanProfileName("foo (enforce)"), "foo")
}