diff --git a/pkg/parent/parent.go b/pkg/parent/parent.go index e19ee0a4..3d559e87 100644 --- a/pkg/parent/parent.go +++ b/pkg/parent/parent.go @@ -190,6 +190,7 @@ func Parent(opt Opt) error { cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", opt.ParentEGIDEnvKey, os.Getegid())) } if err := cmd.Start(); err != nil { + warnOnChildStartFailure(err) return fmt.Errorf("failed to start the child: %w", err) } diff --git a/pkg/parent/warn.go b/pkg/parent/warn.go index 67987377..113c6f55 100644 --- a/pkg/parent/warn.go +++ b/pkg/parent/warn.go @@ -1,12 +1,14 @@ package parent import ( + "errors" "os" "strconv" "strings" "github.com/moby/sys/mountinfo" "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) func warnPropagation(propagation string) { @@ -57,3 +59,46 @@ func warnSysctl() { } } } + +func warnOnChildStartFailure(childStartErr error) { + if errors.Is(childStartErr, unix.EACCES) { + // apparmor_restrict_unprivileged_userns is available since Ubuntu 23.10. + // Enabled by default since Ubuntu 24.04. + // https://github.com/containerd/nerdctl/issues/2847 + b, err := os.ReadFile("/proc/sys/kernel/apparmor_restrict_unprivileged_userns") + if err == nil { + s := strings.TrimSpace(string(b)) + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + logrus.WithError(err).Warnf("Failed to parse /proc/sys/kernel/apparmor_restrict_unprivileged_userns (%q)", s) + } else if i == 1 { + logrus.WithError(childStartErr).Warnf("This error might have happened because /proc/sys/kernel/apparmor_restrict_unprivileged_userns is set to 1") + selfExe, err := os.Executable() + if err != nil { + selfExe = "/usr/local/bin/rootlesskit" + logrus.WithError(err).Warnf("Failed to detect the path of the rootlesskit binary, assuming it to be %q", selfExe) + } + profileName := strings.ReplaceAll(strings.TrimPrefix(selfExe, "/"), "/", ".") + const tmpl = ` + +########## BEGIN ########## +cat <, +include + +%s flags=(unconfined) { + userns, + + # Site-specific additions and overrides. See local/README for details. + include if exists +} +EOT +sudo systemctl restart apparmor.service +########## END ########## +` + logrus.Warnf("Hint: try running the following commands:\n"+tmpl+"\n", profileName, selfExe, profileName) + } + } + } +}