diff --git a/cmd/rootlesskit/main.go b/cmd/rootlesskit/main.go index e0bd133c..c1e060f7 100644 --- a/cmd/rootlesskit/main.go +++ b/cmd/rootlesskit/main.go @@ -15,7 +15,6 @@ import ( "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" - "github.com/rootless-containers/rootlesskit/v2/cmd/rootlesskit/unshare" "github.com/rootless-containers/rootlesskit/v2/pkg/child" "github.com/rootless-containers/rootlesskit/v2/pkg/common" "github.com/rootless-containers/rootlesskit/v2/pkg/copyup/tmpfssymlink" @@ -42,10 +41,6 @@ const ( ) func main() { - if checkUnshareHelper() { - unshare.Main() - return - } iAmActivationHelper := checkActivationHelper() iAmChild := os.Getenv(pipeFDEnvKey) != "" id := "parent" @@ -706,7 +701,3 @@ func createActivationOpts(clicontext *cli.Context) (activation.Opt, error) { } return opt, nil } - -func checkUnshareHelper() bool { - return filepath.Base(os.Args[0]) == "unshare" -} diff --git a/cmd/rootlesskit/unshare/unshare.go b/cmd/rootlesskit/unshare/unshare.go deleted file mode 100644 index 1db6c83a..00000000 --- a/cmd/rootlesskit/unshare/unshare.go +++ /dev/null @@ -1,53 +0,0 @@ -package unshare - -import ( - "errors" - "fmt" - "os" - "os/exec" - "syscall" - - "github.com/rootless-containers/rootlesskit/v2/pkg/common" - "github.com/rootless-containers/rootlesskit/v2/pkg/version" - "github.com/urfave/cli/v2" -) - -func Main() { - app := cli.NewApp() - app.Name = "unshare" - app.HideHelpCommand = true - app.Version = version.Version - app.Usage = "Reimplementation of unshare(1)" - app.UsageText = "unshare [global options] [arguments...]" - app.Flags = append(app.Flags, &cli.BoolFlag{ - Name: "n,net", - Usage: "unshare network namespace", - }) - app.Action = action - if err := app.Run(os.Args); err != nil { - fmt.Fprintf(os.Stderr, "[rootlesskit:unshare] error: %v\n", err) - // propagate the exit code - code, ok := common.GetExecExitStatus(err) - if !ok { - code = 1 - } - os.Exit(code) - } -} - -func action(clicontext *cli.Context) error { - ctx := clicontext.Context - if clicontext.NArg() < 1 { - return errors.New("no command specified") - } - cmdFlags := clicontext.Args().Slice() - cmd := exec.CommandContext(ctx, cmdFlags[0], cmdFlags[1:]...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.SysProcAttr = &syscall.SysProcAttr{} - if clicontext.Bool("n") { - cmd.SysProcAttr.Cloneflags |= syscall.CLONE_NEWNET - } - return cmd.Run() -} diff --git a/pkg/child/child.go b/pkg/child/child.go index d32cb675..a7440c41 100644 --- a/pkg/child/child.go +++ b/pkg/child/child.go @@ -583,19 +583,13 @@ func NewNetNsWithPathWithoutEnter(p string) error { if err := os.WriteFile(p, nil, 0400); err != nil { return err } - selfExe, err := os.Executable() + tempNS, err := ns.TempNetNS() if err != nil { return err } - // this is hard (not impossible though) to reimplement in Go: https://github.com/cloudflare/slirpnetstack/commit/d7766a8a77f0093d3cb7a94bd0ccbe3f67d411ba - cmd := exec.Command("unshare", "-n", "mount", "--bind", "/proc/self/ns/net", p) - // Use our own implementation of unshare that is embedded in RootlessKit, so as to - // avoid /etc/apparmor.d/unshare-userns-restrict on Ubuntu 25.04. - // https://github.com/rootless-containers/rootlesskit/issues/494 - cmd.Path = selfExe - out, err := cmd.CombinedOutput() - if err != nil { - return fmt.Errorf("failed to execute %v: %w (out=%q)", cmd.Args, err, string(out)) - } - return nil + defer tempNS.Close() + tempNSPath := tempNS.Path() + return ns.WithNetNSPath(tempNSPath, func(_ ns.NetNS) error { + return unix.Mount(tempNSPath, p, "", unix.MS_BIND, "") + }) }