From 633d5f1f8b8844d6e2fb3e2593768360c889ed76 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 18 May 2022 11:34:13 +0200 Subject: fix --init with /dev bind mount The init binary until now has been bind-mounted to /dev/init which breaks when bind-mounting to /dev. Instead mount the init to /run/podman-init. The reasoning for using /run is that it is already used for other runtime data such as secrets. Fixes: #14251 Signed-off-by: Valentin Rothberg --- docs/source/markdown/podman-create.1.md | 2 ++ docs/source/markdown/podman-run.1.md | 2 ++ libpod/define/container.go | 2 ++ libpod/diff.go | 23 ++++++++++++----------- pkg/specgen/generate/oci.go | 2 +- pkg/specgen/generate/storage.go | 6 ++---- test/e2e/run_test.go | 8 +++++--- 7 files changed, 26 insertions(+), 19 deletions(-) diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index c63e8814b..009209343 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -460,6 +460,8 @@ content that disappears when the container is stopped. #### **--init** Run an init inside the container that forwards signals and reaps processes. +The container-init binary is mounted at `/run/podman-init`. +Mounting over `/run` will hence break container execution. #### **--init-ctr**=*type* (pods only) diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 9d9394020..a16ee9394 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -498,6 +498,8 @@ content that disappears when the container is stopped. #### **--init** Run an init inside the container that forwards signals and reaps processes. +The container-init binary is mounted at `/run/podman-init`. +Mounting over `/run` will hence break container execution. #### **--init-path**=*path* diff --git a/libpod/define/container.go b/libpod/define/container.go index bb44a6a4a..ba939578f 100644 --- a/libpod/define/container.go +++ b/libpod/define/container.go @@ -35,4 +35,6 @@ const ( // OneShotInitContainer is a container that only runs as init once // and is then deleted. OneShotInitContainer = "once" + // ContainerInitPath is the default path of the mounted container init. + ContainerInitPath = "/run/podman-init" ) diff --git a/libpod/diff.go b/libpod/diff.go index 794b26b48..86fa063ec 100644 --- a/libpod/diff.go +++ b/libpod/diff.go @@ -8,17 +8,18 @@ import ( ) var initInodes = map[string]bool{ - "/dev": true, - "/etc/hostname": true, - "/etc/hosts": true, - "/etc/resolv.conf": true, - "/proc": true, - "/run": true, - "/run/notify": true, - "/run/.containerenv": true, - "/run/secrets": true, - "/sys": true, - "/etc/mtab": true, + "/dev": true, + "/etc/hostname": true, + "/etc/hosts": true, + "/etc/resolv.conf": true, + "/proc": true, + "/run": true, + "/run/notify": true, + "/run/.containerenv": true, + "/run/secrets": true, + define.ContainerInitPath: true, + "/sys": true, + "/etc/mtab": true, } // GetDiff returns the differences between the two images, layers, or containers diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index 081df0441..dda2de6e4 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -128,7 +128,7 @@ func makeCommand(s *specgen.SpecGenerator, imageData *libimage.ImageData, rtc *c if initPath == "" { return nil, errors.Errorf("no path to init binary found but container requested an init") } - finalCommand = append([]string{"/dev/init", "--"}, finalCommand...) + finalCommand = append([]string{define.ContainerInitPath, "--"}, finalCommand...) } return finalCommand, nil diff --git a/pkg/specgen/generate/storage.go b/pkg/specgen/generate/storage.go index f30fc4671..0a4d03780 100644 --- a/pkg/specgen/generate/storage.go +++ b/pkg/specgen/generate/storage.go @@ -20,9 +20,7 @@ import ( "github.com/sirupsen/logrus" ) -var ( - errDuplicateDest = errors.Errorf("duplicate mount destination") -) +var errDuplicateDest = errors.Errorf("duplicate mount destination") // Produce final mounts and named volumes for a container func finalizeMounts(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, img *libimage.Image) ([]spec.Mount, []*specgen.NamedVolume, []*specgen.OverlayVolume, error) { @@ -359,7 +357,7 @@ func getVolumesFrom(volumesFrom []string, runtime *libpod.Runtime) (map[string]s // This does *NOT* modify the container command - that must be done elsewhere. func addContainerInitBinary(s *specgen.SpecGenerator, path string) (spec.Mount, error) { mount := spec.Mount{ - Destination: "/dev/init", + Destination: define.ContainerInitPath, Type: define.TypeBind, Source: path, Options: []string{define.TypeBind, "ro"}, diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 182ae1888..828e92170 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/containers/common/pkg/cgroups" + "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/rootless" . "github.com/containers/podman/v4/test/utils" "github.com/containers/storage/pkg/stringid" @@ -286,19 +287,20 @@ var _ = Describe("Podman run", func() { result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() - Expect(conData[0]).To(HaveField("Path", "/dev/init")) + Expect(conData[0]).To(HaveField("Path", define.ContainerInitPath)) Expect(conData[0].Config.Annotations).To(HaveKeyWithValue("io.podman.annotations.init", "TRUE")) }) It("podman run a container with --init and --init-path", func() { - session := podmanTest.Podman([]string{"run", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"}) + // Also bind-mount /dev (#14251). + session := podmanTest.Podman([]string{"run", "-v", "/dev:/dev", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", "test"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() - Expect(conData[0]).To(HaveField("Path", "/dev/init")) + Expect(conData[0]).To(HaveField("Path", define.ContainerInitPath)) Expect(conData[0].Config.Annotations).To(HaveKeyWithValue("io.podman.annotations.init", "TRUE")) }) -- cgit v1.2.3-54-g00ecf