From ca7d5c77c29de1b95e8c749c089c7b1dd2cc047d Mon Sep 17 00:00:00 2001 From: Xianglin Gao Date: Mon, 12 Dec 2016 15:55:17 +0800 Subject: [PATCH] Do not load ocid-default if configured apparmor profile is set up. Signed-off-by: Xianglin Gao --- server/apparmor/apparmor_supported.go | 66 +++++++++++++------------ server/apparmor/apparmor_unsupported.go | 5 +- server/container_create.go | 12 +++-- server/server.go | 8 +-- 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/server/apparmor/apparmor_supported.go b/server/apparmor/apparmor_supported.go index ff9205ad..d765c9de 100644 --- a/server/apparmor/apparmor_supported.go +++ b/server/apparmor/apparmor_supported.go @@ -4,14 +4,13 @@ package apparmor import ( "bufio" + "fmt" "io" "io/ioutil" "os" "path" "strings" - "time" - "github.com/Sirupsen/logrus" "github.com/docker/docker/utils/templates" "github.com/opencontainers/runc/libcontainer/apparmor" ) @@ -19,9 +18,6 @@ import ( const ( // profileDirectory is the file store for apparmor profiles and macros. profileDirectory = "/etc/apparmor.d" - - // readConfigTimeout is the timeout of reading apparmor profiles. - readConfigTimeout = 10 ) // profileData holds information about the given profile for generation. @@ -36,13 +32,26 @@ type profileData struct { Version int } -// LoadDefaultAppArmorProfile loads default apparmor profile, if it is not loaded. -func LoadDefaultAppArmorProfile() { - if !IsLoaded(DefaultApparmorProfile) { +// EnsureDefaultApparmorProfile loads default apparmor profile, if it is not loaded. +func EnsureDefaultApparmorProfile() error { + if apparmor.IsEnabled() { + loaded, err := IsLoaded(DefaultApparmorProfile) + if err != nil { + return fmt.Errorf("Could not check if %s AppArmor profile was loaded: %s", DefaultApparmorProfile, err) + } + + // Nothing to do. + if loaded { + return nil + } + + // Load the profile. if err := InstallDefault(DefaultApparmorProfile); err != nil { - logrus.Errorf("AppArmor enabled on system but the %s profile could not be loaded:%v", DefaultApparmorProfile, err) + return fmt.Errorf("AppArmor enabled on system but the %s profile could not be loaded.", DefaultApparmorProfile) } } + + return nil } // IsEnabled returns true if apparmor is enabled for the host. @@ -77,35 +86,30 @@ func InstallDefault(name string) error { return LoadProfile(f.Name()) } -// IsLoaded checks if a passed profile has been loaded into the kernel. -func IsLoaded(name string) bool { +// IsLoaded checks if a profile with the given name has been loaded into the +// kernel. +func IsLoaded(name string) (bool, error) { file, err := os.Open("/sys/kernel/security/apparmor/profiles") if err != nil { - return false + return false, err } defer file.Close() - ch := make(chan bool, 1) - - go func() { - r := bufio.NewReader(file) - for { - p, err := r.ReadString('\n') - if err != nil { - ch <- false - } - if strings.HasPrefix(p, name+" ") { - ch <- true - } + r := bufio.NewReader(file) + for { + p, err := r.ReadString('\n') + if err == io.EOF { + break + } + if err != nil { + return false, err + } + if strings.HasPrefix(p, name+" ") { + return true, nil } - }() - - select { - case <-time.After(time.Duration(readConfigTimeout) * time.Second): - return false - case enabled := <-ch: - return enabled } + + return false, nil } // generateDefault creates an apparmor profile from ProfileData. diff --git a/server/apparmor/apparmor_unsupported.go b/server/apparmor/apparmor_unsupported.go index b4c107c0..fbd1d87a 100644 --- a/server/apparmor/apparmor_unsupported.go +++ b/server/apparmor/apparmor_unsupported.go @@ -7,8 +7,9 @@ func IsEnabled() bool { return false } -// LoadDefaultAppArmorProfile dose nothing, when build without apparmor build tag. -func LoadDefaultAppArmorProfile() { +// EnsureDefaultApparmorProfile dose nothing, when build without apparmor build tag. +func EnsureDefaultApparmorProfile() error { + return nil } // GetProfileNameFromPodAnnotations dose nothing, when build without apparmor build tag. diff --git a/server/container_create.go b/server/container_create.go index ed7faa7c..6a5b93fb 100644 --- a/server/container_create.go +++ b/server/container_create.go @@ -188,6 +188,13 @@ func (s *Server) createSandboxContainer(containerID string, containerName string if s.appArmorEnabled { appArmorProfileName := s.getAppArmorProfileName(sb.annotations, metadata.GetName()) if appArmorProfileName != "" { + // reload default apparmor profile if it is unloaded. + if s.appArmorProfile == apparmor.DefaultApparmorProfile { + if err := apparmor.EnsureDefaultApparmorProfile(); err != nil { + return nil, err + } + } + specgen.SetProcessApparmorProfile(appArmorProfileName) } } @@ -393,11 +400,6 @@ func (s *Server) getAppArmorProfileName(annotations map[string]string, ctrName s } if profile == apparmor.ProfileRuntimeDefault { - // reload default apparmor profile if it is unloaded. - if s.appArmorProfile == apparmor.DefaultApparmorProfile { - apparmor.LoadDefaultAppArmorProfile() - } - // If the value is runtime/default, then return default profile. return s.appArmorProfile } diff --git a/server/server.go b/server/server.go index 42d7fcac..b2066f76 100644 --- a/server/server.go +++ b/server/server.go @@ -287,6 +287,7 @@ func New(config *Config) (*Server, error) { }, seccompEnabled: seccompEnabled(), appArmorEnabled: apparmor.IsEnabled(), + appArmorProfile: config.ApparmorProfile, } seccompProfile, err := ioutil.ReadFile(config.SeccompProfile) if err != nil { @@ -298,10 +299,11 @@ func New(config *Config) (*Server, error) { } s.seccompProfile = seccompConfig - if s.appArmorEnabled { - apparmor.LoadDefaultAppArmorProfile() + if s.appArmorEnabled && s.appArmorProfile == apparmor.DefaultApparmorProfile { + if err := apparmor.EnsureDefaultApparmorProfile(); err != nil { + return nil, fmt.Errorf("ensuring the default apparmor profile is installed failed: %v", err) + } } - s.appArmorProfile = config.ApparmorProfile s.podIDIndex = truncindex.NewTruncIndex([]string{}) s.podNameIndex = registrar.NewRegistrar()