github.com/hms58/moby@v1.13.1/profiles/apparmor/apparmor.go (about) 1 // +build linux 2 3 package apparmor 4 5 import ( 6 "bufio" 7 "io" 8 "io/ioutil" 9 "os" 10 "path" 11 "strings" 12 13 "github.com/docker/docker/pkg/aaparser" 14 "github.com/docker/docker/utils/templates" 15 ) 16 17 var ( 18 // profileDirectory is the file store for apparmor profiles and macros. 19 profileDirectory = "/etc/apparmor.d" 20 ) 21 22 // profileData holds information about the given profile for generation. 23 type profileData struct { 24 // Name is profile name. 25 Name string 26 // Imports defines the apparmor functions to import, before defining the profile. 27 Imports []string 28 // InnerImports defines the apparmor functions to import in the profile. 29 InnerImports []string 30 // Version is the {major, minor, patch} version of apparmor_parser as a single number. 31 Version int 32 } 33 34 // generateDefault creates an apparmor profile from ProfileData. 35 func (p *profileData) generateDefault(out io.Writer) error { 36 compiled, err := templates.NewParse("apparmor_profile", baseTemplate) 37 if err != nil { 38 return err 39 } 40 41 if macroExists("tunables/global") { 42 p.Imports = append(p.Imports, "#include <tunables/global>") 43 } else { 44 p.Imports = append(p.Imports, "@{PROC}=/proc/") 45 } 46 47 if macroExists("abstractions/base") { 48 p.InnerImports = append(p.InnerImports, "#include <abstractions/base>") 49 } 50 51 ver, err := aaparser.GetVersion() 52 if err != nil { 53 return err 54 } 55 p.Version = ver 56 57 if err := compiled.Execute(out, p); err != nil { 58 return err 59 } 60 return nil 61 } 62 63 // macrosExists checks if the passed macro exists. 64 func macroExists(m string) bool { 65 _, err := os.Stat(path.Join(profileDirectory, m)) 66 return err == nil 67 } 68 69 // InstallDefault generates a default profile in a temp directory determined by 70 // os.TempDir(), then loads the profile into the kernel using 'apparmor_parser'. 71 func InstallDefault(name string) error { 72 p := profileData{ 73 Name: name, 74 } 75 76 // Install to a temporary directory. 77 f, err := ioutil.TempFile("", name) 78 if err != nil { 79 return err 80 } 81 profilePath := f.Name() 82 83 defer f.Close() 84 defer os.Remove(profilePath) 85 86 if err := p.generateDefault(f); err != nil { 87 f.Close() 88 return err 89 } 90 91 if err := aaparser.LoadProfile(profilePath); err != nil { 92 return err 93 } 94 95 return nil 96 } 97 98 // IsLoaded checks if a profile with the given name has been loaded into the 99 // kernel. 100 func IsLoaded(name string) (bool, error) { 101 file, err := os.Open("/sys/kernel/security/apparmor/profiles") 102 if err != nil { 103 return false, err 104 } 105 defer file.Close() 106 107 r := bufio.NewReader(file) 108 for { 109 p, err := r.ReadString('\n') 110 if err == io.EOF { 111 break 112 } 113 if err != nil { 114 return false, err 115 } 116 if strings.HasPrefix(p, name+" ") { 117 return true, nil 118 } 119 } 120 121 return false, nil 122 }