github.com/skanehira/moby@v17.12.1-ce-rc2+incompatible/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 "text/template" 13 14 "github.com/docker/docker/pkg/aaparser" 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 := template.New("apparmor_profile").Parse(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 return compiled.Execute(out, p) 58 } 59 60 // macrosExists checks if the passed macro exists. 61 func macroExists(m string) bool { 62 _, err := os.Stat(path.Join(profileDirectory, m)) 63 return err == nil 64 } 65 66 // InstallDefault generates a default profile in a temp directory determined by 67 // os.TempDir(), then loads the profile into the kernel using 'apparmor_parser'. 68 func InstallDefault(name string) error { 69 p := profileData{ 70 Name: name, 71 } 72 73 // Install to a temporary directory. 74 f, err := ioutil.TempFile("", name) 75 if err != nil { 76 return err 77 } 78 profilePath := f.Name() 79 80 defer f.Close() 81 defer os.Remove(profilePath) 82 83 if err := p.generateDefault(f); err != nil { 84 return err 85 } 86 87 return aaparser.LoadProfile(profilePath) 88 } 89 90 // IsLoaded checks if a profile with the given name has been loaded into the 91 // kernel. 92 func IsLoaded(name string) (bool, error) { 93 file, err := os.Open("/sys/kernel/security/apparmor/profiles") 94 if err != nil { 95 return false, err 96 } 97 defer file.Close() 98 99 r := bufio.NewReader(file) 100 for { 101 p, err := r.ReadString('\n') 102 if err == io.EOF { 103 break 104 } 105 if err != nil { 106 return false, err 107 } 108 if strings.HasPrefix(p, name+" ") { 109 return true, nil 110 } 111 } 112 113 return false, nil 114 }