diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 1121806d5ed7..16a796233956 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -493,8 +493,8 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions, "Make containers root filesystem read-only", ) createFlags.BoolVar( - &cf.ReadOnlyTmpFS, - "read-only-tmpfs", true, + &cf.ReadWriteTmpFS, + "read-write-tmpfs", true, "When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp", ) requiresFlagName := "requires" diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index a4f94616c7d9..cb3e766b5f32 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -287,7 +287,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c PublishAll: cc.HostConfig.PublishAllPorts, Quiet: false, ReadOnly: cc.HostConfig.ReadonlyRootfs, - ReadOnlyTmpFS: true, // podman default + ReadWriteTmpFS: true, // podman default Rm: cc.HostConfig.AutoRemove, SecurityOpt: cc.HostConfig.SecurityOpt, StopSignal: cc.Config.StopSignal, diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index 89d2e5515038..6e96cb5c0fac 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -111,6 +111,9 @@ func create(cmd *cobra.Command, args []string) error { return err } + if cmd.Flags().Changed("read-write-tmpfs") && !cliVals.ReadOnly { + return errors.New("--read-write-tmpfs is only used if --read-write=true") + } // Check if initctr is used with --pod and the value is correct if initctr := InitContainerType; cmd.Flags().Changed("init-ctr") { if !cmd.Flags().Changed("pod") { diff --git a/cmd/podman/utils/alias.go b/cmd/podman/utils/alias.go index 4d5b625d02b9..b04d476c229e 100644 --- a/cmd/podman/utils/alias.go +++ b/cmd/podman/utils/alias.go @@ -31,6 +31,8 @@ func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName { name = "os" case "override-variant": name = "variant" + case "read-only-tmpfs": + name = "read-write-tmpfs" } return pflag.NormalizedName(name) } diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index 2a0f3b738a5f..0904558aa931 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -851,9 +851,9 @@ By default a container will have its root filesystem writable allowing processes to write files anywhere. By specifying the `--read-only` flag the container will have its root filesystem mounted as read only prohibiting any writes. -#### **--read-only-tmpfs** +#### **--read-write-tmpfs** -If container is running in --read-only mode, then mount a read-write tmpfs on /run, /tmp, and /var/tmp. The default is *true* +If container is running in --read-only mode, then mount a read-write tmpfs on /run, /tmp, and /var/tmp. When false, Podman the entire container has no tmpfs that are read/write unless specified on the command line. Podman mounts /dev, /dev/mqueue, /dev/pts, /dev/shm as read only. The default is *true* #### **--replace** diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 239cf3b832c0..71959e977689 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -891,9 +891,9 @@ By default a container will have its root filesystem writable allowing processes to write files anywhere. By specifying the **--read-only** flag, the container will have its root filesystem mounted as read only prohibiting any writes. -#### **--read-only-tmpfs** +#### **--read-write-tmpfs** -If container is running in **--read-only** mode, then mount a read-write tmpfs on _/run_, _/tmp_, and _/var/tmp_. The default is **true**. +If container is running in --read-only mode, then mount a read-write tmpfs on /run, /tmp, and /var/tmp. When false, Podman the entire container has no tmpfs that are read/write unless specified on the command line. Podman mounts /dev, /dev/mqueue, /dev/pts, /dev/shm as read only. The default is *true* #### **--replace** diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go index 7922db4e6f61..b924f9d0db13 100644 --- a/pkg/domain/entities/pods.go +++ b/pkg/domain/entities/pods.go @@ -226,7 +226,7 @@ type ContainerCreateOptions struct { Pull string Quiet bool ReadOnly bool - ReadOnlyTmpFS bool + ReadWriteTmpFS bool Restart string Replace bool Requires []string diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index 945c994ea8a8..29b67e877d39 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -182,8 +182,6 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt if err != nil { return nil, err } - // Remove the default /dev/shm mount to ensure we overwrite it - g.RemoveMount("/dev/shm") g.HostSpecific = true addCgroup := true @@ -430,5 +428,18 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt } setProcOpts(s, &g) + if s.ReadOnlyTmpFS { + for n, m := range configSpec.Mounts { + switch m.Destination { + case "/dev", "/dev/shm", "/dev/mqueue", "/dev/pts": + m.Options = append(m.Options, "ro") + configSpec.Mounts[n] = m + } + } + } else { + // Remove the default /dev/shm mount to ensure we overwrite it + g.RemoveMount("/dev/shm") + } + return configSpec, nil } diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index 7f6f79b8739a..229949301593 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -367,6 +367,9 @@ type ContainerSecurityConfig struct { // ReadOnlyFilesystem indicates that everything will be mounted // as read-only ReadOnlyFilesystem bool `json:"read_only_filesystem,omitempty"` + // ReadOnlyTmpfs indicates that tmpfs will be mounted + // as read-only + ReadOnlyTmpFS bool `json:"read_only_tmpfs,omitempty"` // Umask is the umask the init process of the container will be run with. Umask string `json:"umask,omitempty"` // ProcOpts are the options used for the proc mount. diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 17699a0380f8..993125d86c28 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -522,6 +522,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions s.CapDrop = c.CapDrop s.Privileged = c.Privileged s.ReadOnlyFilesystem = c.ReadOnly + s.ReadOnlyTmpFS = !c.ReadWriteTmpFS s.ConmonPidFile = c.ConmonPIDFile s.DependencyContainers = c.Requires @@ -529,9 +530,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions // TODO // outside of specgen and oci though // defaults to true, check spec/storage - // s.readonly = c.ReadOnlyTmpFS - // TODO convert to map? - // check if key=value and convert sysmap := make(map[string]string) for _, ctl := range c.Sysctl { splitCtl := strings.SplitN(ctl, "=", 2) @@ -590,7 +588,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions // Only add read-only tmpfs mounts in case that we are read-only and the // read-only tmpfs flag has been set. - mounts, volumes, overlayVolumes, imageVolumes, err := parseVolumes(c.Volume, c.Mount, c.TmpFS, c.ReadOnlyTmpFS && c.ReadOnly) + mounts, volumes, overlayVolumes, imageVolumes, err := parseVolumes(c.Volume, c.Mount, c.TmpFS, c.ReadWriteTmpFS && c.ReadOnly) if err != nil { return err } diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go index 2bd79b186ab9..bb0f966e0016 100644 --- a/pkg/specgenutil/volumes.go +++ b/pkg/specgenutil/volumes.go @@ -26,7 +26,7 @@ var ( // Does not handle image volumes, init, and --volumes-from flags. // Can also add tmpfs mounts from read-only tmpfs. // TODO: handle options parsing/processing via containers/storage/pkg/mount -func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bool) ([]spec.Mount, []*specgen.NamedVolume, []*specgen.OverlayVolume, []*specgen.ImageVolume, error) { +func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, readWriteTmpfs bool) ([]spec.Mount, []*specgen.NamedVolume, []*specgen.OverlayVolume, []*specgen.ImageVolume, error) { // Get mounts from the --mounts flag. unifiedMounts, unifiedVolumes, unifiedImageVolumes, err := getMounts(mountFlag) if err != nil { @@ -68,10 +68,10 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo } // If requested, add tmpfs filesystems for read-only containers. - if addReadOnlyTmpfs { - readonlyTmpfs := []string{"/tmp", "/var/tmp", "/run"} + if readWriteTmpfs { + tmpfs := []string{"/tmp", "/var/tmp", "/run"} options := []string{"rw", "rprivate", "nosuid", "nodev", "tmpcopyup"} - for _, dest := range readonlyTmpfs { + for _, dest := range tmpfs { if _, ok := unifiedMounts[dest]; ok { continue }