diff --git a/contrib/apparmor/template.go b/contrib/apparmor/template.go index 5869cffaa..76fd34811 100644 --- a/contrib/apparmor/template.go +++ b/contrib/apparmor/template.go @@ -29,6 +29,8 @@ import ( "path" "strings" "text/template" + + "github.com/containerd/log" ) // NOTE: This code is copied from . @@ -57,6 +59,10 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) { signal (receive) peer={{.DaemonProfile}}, # Container processes may send signals amongst themselves. signal (send,receive) peer={{.Name}}, +{{if .RootlessKit}} + # https://github.com/containerd/nerdctl/issues/2730 + signal (receive) peer={{.RootlessKit}}, +{{end}} deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir) # deny write to files not in /proc//** or /proc/sys/** @@ -90,6 +96,7 @@ type data struct { Imports []string InnerImports []string DaemonProfile string + RootlessKit string } func cleanProfileName(profile string) string { @@ -125,6 +132,16 @@ func loadData(name string) (*data, error) { } p.DaemonProfile = cleanProfileName(string(currentProfile)) + // If we were running in Rootless mode, we could read `/proc/$(cat ${ROOTLESSKIT_STATE_DIR}/child_pid)/exe`, + // but `nerdctl apparmor load` has to be executed as the root. + // So, do not check ${ROOTLESSKIT_STATE_DIR} (nor EUID) here. + p.RootlessKit, err = exec.LookPath("rootlesskit") + if err != nil { + log.L.WithError(err).Debug("apparmor: failed to determine the RootlessKit binary path") + p.RootlessKit = "" + } + log.L.Debugf("apparmor: RootlessKit=%q", p.RootlessKit) + return &p, nil }