11// +build linux
22
33/*
4+ Copyright The docker Authors.
5+ Copyright The Moby Authors.
46 Copyright The containerd Authors.
57
68 Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,6 +24,7 @@ import (
2224 "bufio"
2325 "fmt"
2426 "io"
27+ "io/ioutil"
2528 "os"
2629 "os/exec"
2730 "path"
@@ -32,6 +35,10 @@ import (
3235 "github.com/pkg/errors"
3336)
3437
38+ // NOTE: This code is copied from <github.com/docker/docker/profiles/apparmor>.
39+ // If you plan to make any changes, please make sure they are also sent
40+ // upstream.
41+
3542const dir = "/etc/apparmor.d"
3643
3744const defaultTemplate = `
@@ -48,6 +55,14 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) {
4855 capability,
4956 file,
5057 umount,
58+ {{if ge .Version 208096}}
59+ # Host (privileged) processes may send signals to container processes.
60+ signal (receive) peer=unconfined,
61+ # Manager may send signals to container processes.
62+ signal (receive) peer={{.DaemonProfile}},
63+ # Container processes may send signals amongst themselves.
64+ signal (send,receive) peer={{.Name}},
65+ {{end}}
5166
5267 deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir)
5368 # deny write to files not in /proc/<number>/** or /proc/sys/**
@@ -76,10 +91,23 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) {
7691`
7792
7893type data struct {
79- Name string
80- Imports []string
81- InnerImports []string
82- Version int
94+ Name string
95+ Imports []string
96+ InnerImports []string
97+ DaemonProfile string
98+ Version int
99+ }
100+
101+ func cleanProfileName (profile string ) string {
102+ // Normally profiles are suffixed by " (enforce)". AppArmor profiles cannot
103+ // contain spaces so this doesn't restrict daemon profile names.
104+ if parts := strings .SplitN (profile , " " , 2 ); len (parts ) >= 1 {
105+ profile = parts [0 ]
106+ }
107+ if profile == "" {
108+ profile = "unconfined"
109+ }
110+ return profile
83111}
84112
85113func loadData (name string ) (* data , error ) {
@@ -100,6 +128,16 @@ func loadData(name string) (*data, error) {
100128 return nil , errors .Wrap (err , "get apparmor_parser version" )
101129 }
102130 p .Version = ver
131+
132+ // Figure out the daemon profile.
133+ currentProfile , err := ioutil .ReadFile ("/proc/self/attr/current" )
134+ if err != nil {
135+ // If we couldn't get the daemon profile, assume we are running
136+ // unconfined which is generally the default.
137+ currentProfile = nil
138+ }
139+ p .DaemonProfile = cleanProfileName (string (currentProfile ))
140+
103141 return & p , nil
104142}
105143
0 commit comments