@@ -34,13 +34,29 @@ var (
3434)
3535
3636// hostSupports returns true if apparmor is enabled for the host
37+ // We cannot use containerd implementation because it explicitly prevents it from working inside a container.
3738func hostSupports () bool {
3839 checkAppArmor .Do (func () {
39- // see https://github.com/opencontainers/runc/blob/0d49470392206f40eaab3b2190a57fe7bb3df458/libcontainer/apparmor/apparmor_linux.go
40- if _ , err := os .Stat ("/sys/kernel/security/apparmor" ); err = = nil {
41- buf , err := os . ReadFile ( "/sys/module/apparmor/parameters/enabled" )
42- appArmorSupported = err == nil && len ( buf ) > 1 && buf [ 0 ] == 'Y'
40+ var pth string
41+ if _ , err := os .Stat ("/sys/kernel/security/apparmor" ); err ! = nil {
42+ appArmorSupported = false
43+ return
4344 }
45+ // In some rare circumstances, apparmor may be enabled, but the tooling could be missing
46+ // containerd implementation shells out to aa-parser, so, require it here.
47+ // See https://github.com/containerd/nerdctl/issues/3945 for details.
48+ pth , err := exec .LookPath ("apparmor_parser" )
49+ if err != nil {
50+ appArmorSupported = false
51+ return
52+ }
53+ if _ , err = os .Stat (pth ); err != nil {
54+ appArmorSupported = false
55+ return
56+ }
57+ var buf []byte
58+ buf , err = os .ReadFile ("/sys/module/apparmor/parameters/enabled" )
59+ appArmorSupported = err == nil && len (buf ) == 2 && string (buf ) == "Y\n "
4460 })
4561 return appArmorSupported
4662}
7389func CanApplyExistingProfile () bool {
7490 paramEnabledOnce .Do (func () {
7591 buf , err := os .ReadFile ("/sys/module/apparmor/parameters/enabled" )
76- paramEnabled = err == nil && len (buf ) > 1 && buf [ 0 ] == 'Y'
92+ paramEnabled = err == nil && len (buf ) == 2 && string ( buf ) == "Y \n "
7793 })
7894 return paramEnabled
7995}
0 commit comments