github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/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 return err 88 } 89 90 if err := aaparser.LoadProfile(profilePath); err != nil { 91 return err 92 } 93 94 return nil 95 } 96 97 // IsLoaded checks if a passed profile has been loaded into the kernel. 98 func IsLoaded(name string) error { 99 file, err := os.Open("/sys/kernel/security/apparmor/profiles") 100 if err != nil { 101 return err 102 } 103 defer file.Close() 104 105 r := bufio.NewReader(file) 106 for { 107 p, err := r.ReadString('\n') 108 if err != nil { 109 return err 110 } 111 if strings.HasPrefix(p, name+" ") { 112 return nil 113 } 114 } 115 }