@@ -34,13 +34,29 @@ var (
34
34
)
35
35
36
36
// 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.
37
38
func hostSupports () bool {
38
39
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
43
44
}
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 "
44
60
})
45
61
return appArmorSupported
46
62
}
73
89
func CanApplyExistingProfile () bool {
74
90
paramEnabledOnce .Do (func () {
75
91
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 "
77
93
})
78
94
return paramEnabled
79
95
}
0 commit comments