Add better support for unbindable volume mounts

Allow users to specify unbindable on volume command line

Switch internal mounts to rprivate to help prevent leaks.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2020-10-29 13:31:55 -04:00
parent 2aaa036f56
commit 3ee44d942e
7 changed files with 24 additions and 22 deletions

View File

@ -313,7 +313,7 @@ func getBindMount(args []string) (spec.Mount, error) {
} }
setExec = true setExec = true
newMount.Options = append(newMount.Options, kv[0]) newMount.Options = append(newMount.Options, kv[0])
case "shared", "rshared", "private", "rprivate", "slave", "rslave", "Z", "z": case "shared", "rshared", "private", "rprivate", "slave", "rslave", "unbindable", "runbindable", "Z", "z":
newMount.Options = append(newMount.Options, kv[0]) newMount.Options = append(newMount.Options, kv[0])
case "bind-propagation": case "bind-propagation":
if len(kv) == 1 { if len(kv) == 1 {

View File

@ -541,7 +541,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· ro, readonly: true or false (default). · ro, readonly: true or false (default).
· bind-propagation: shared, slave, private, rshared, rslave, or rprivate(default). See also mount(2). · bind-propagation: shared, slave, private, unbindable, rshared, rslave, runbindable, or rprivate(default). See also mount(2).
. bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive. . bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive.
@ -962,7 +962,7 @@ The _options_ is a comma delimited list and can be:
* **rw**|**ro** * **rw**|**ro**
* **z**|**Z** * **z**|**Z**
* [**r**]**shared**|[**r**]**slave**|[**r**]**private** * [**r**]**shared**|[**r**]**slave**|[**r**]**private**[**r**]**unbindable**
* [**r**]**bind** * [**r**]**bind**
* [**no**]**exec** * [**no**]**exec**
* [**no**]**dev** * [**no**]**dev**
@ -1048,13 +1048,14 @@ visible on host and vice versa. Making a volume `slave` enables only one
way mount propagation and that is mounts done on host under that volume way mount propagation and that is mounts done on host under that volume
will be visible inside container but not the other way around. <sup>[[1]](#Footnote1)</sup> will be visible inside container but not the other way around. <sup>[[1]](#Footnote1)</sup>
To control mount propagation property of volume one can use `:[r]shared`, To control mount propagation property of a volume one can use the [**r**]**shared**,
`:[r]slave` or `:[r]private` propagation flag. Propagation property can [**r**]**slave**, [**r**]**private** or the [**r**]**unbindable** propagation flag.
be specified only for bind mounted volumes and not for internal volumes or Propagation property can be specified only for bind mounted volumes and not for
named volumes. For mount propagation to work source mount point (mount point internal volumes or named volumes. For mount propagation to work the source mount
where source dir is mounted on) has to have right propagation properties. For point (the mount point where source dir is mounted on) has to have the right propagation
shared volumes, source mount point has to be shared. And for slave volumes, properties. For shared volumes, the source mount point has to be shared. And for
source mount has to be either shared or slave. <sup>[[1]](#Footnote1)</sup> slave volumes, the source mount point has to be either shared or slave.
<sup>[[1]](#Footnote1)</sup>
If you want to recursively mount a volume and all of its submounts into a If you want to recursively mount a volume and all of its submounts into a
container, then you can use the `rbind` option. By default the bind option is container, then you can use the `rbind` option. By default the bind option is

View File

@ -567,7 +567,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· ro, readonly: true or false (default). · ro, readonly: true or false (default).
· bind-propagation: shared, slave, private, rshared, rslave, or rprivate(default). See also mount(2). · bind-propagation: shared, slave, private, unbindable, rshared, rslave, runbindable, or rprivate(default). See also mount(2).
. bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive. . bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive.
@ -1015,7 +1015,7 @@ The _options_ is a comma delimited list and can be: <sup>[[1]](#Footnote1)</sup>
* **rw**|**ro** * **rw**|**ro**
* **z**|**Z** * **z**|**Z**
* [**r**]**shared**|[**r**]**slave**|[**r**]**private** * [**r**]**shared**|[**r**]**slave**|[**r**]**private**[**r**]**unbindable**
* [**r**]**bind** * [**r**]**bind**
* [**no**]**exec** * [**no**]**exec**
* [**no**]**dev** * [**no**]**dev**
@ -1099,12 +1099,13 @@ way mount propagation and that is mounts done on host under that volume
will be visible inside container but not the other way around. <sup>[[1]](#Footnote1)</sup> will be visible inside container but not the other way around. <sup>[[1]](#Footnote1)</sup>
To control mount propagation property of volume one can use [**r**]**shared**, To control mount propagation property of volume one can use [**r**]**shared**,
[**r**]**slave** or [**r**]**private** propagation flag. Propagation property can [**r**]**slave**, [**r**]**private** or [**r**]**unbindable** propagation flag.
be specified only for bind mounted volumes and not for internal volumes or Propagation property can be specified only for bind mounted volumes and not for
named volumes. For mount propagation to work source mount point (mount point internal volumes or named volumes. For mount propagation to work source mount
where source dir is mounted on) has to have right propagation properties. For point (mount point where source dir is mounted on) has to have right propagation
shared volumes, source mount point has to be shared. And for slave volumes, properties. For shared volumes, source mount point has to be shared. And for
source mount has to be either shared or slave. <sup>[[1]](#Footnote1)</sup> slave volumes, source mount has to be either shared or slave.
<sup>[[1]](#Footnote1)</sup>
If you want to recursively mount a volume and all of its submounts into a If you want to recursively mount a volume and all of its submounts into a
container, then you can use the **rbind** option. By default the bind option is container, then you can use the **rbind** option. By default the bind option is

View File

@ -270,7 +270,7 @@ func parseMountOptionsForInspect(options []string, mount *define.InspectMount) {
isRW = false isRW = false
case "rw": case "rw":
// Do nothing, silently discard // Do nothing, silently discard
case "shared", "slave", "private", "rshared", "rslave", "rprivate": case "shared", "slave", "private", "rshared", "rslave", "rprivate", "unbindable", "runbindable":
mountProp = opt mountProp = opt
case "z", "Z": case "z", "Z":
zZ = opt zZ = opt

View File

@ -344,7 +344,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
Type: "bind", Type: "bind",
Source: srcPath, Source: srcPath,
Destination: dstPath, Destination: dstPath,
Options: []string{"bind", "private"}, Options: []string{"bind", "rprivate"},
} }
if c.IsReadOnly() && dstPath != "/dev/shm" { if c.IsReadOnly() && dstPath != "/dev/shm" {
newMount.Options = append(newMount.Options, "ro", "nosuid", "noexec", "nodev") newMount.Options = append(newMount.Options, "ro", "nosuid", "noexec", "nodev")

View File

@ -445,7 +445,7 @@ func getBindMount(args []string) (spec.Mount, error) {
} }
setExec = true setExec = true
newMount.Options = append(newMount.Options, kv[0]) newMount.Options = append(newMount.Options, kv[0])
case "shared", "rshared", "private", "rprivate", "slave", "rslave", "Z", "z": case "shared", "rshared", "private", "rprivate", "slave", "rslave", "unbindable", "runbindable", "Z", "z":
newMount.Options = append(newMount.Options, kv[0]) newMount.Options = append(newMount.Options, kv[0])
case "bind-propagation": case "bind-propagation":
if len(kv) == 1 { if len(kv) == 1 {

View File

@ -57,7 +57,7 @@ func ProcessOptions(options []string, isTmpfs bool, sourcePath string) ([]string
return nil, errors.Wrapf(ErrDupeMntOption, "only one of 'rw' and 'ro' can be used") return nil, errors.Wrapf(ErrDupeMntOption, "only one of 'rw' and 'ro' can be used")
} }
foundWrite = true foundWrite = true
case "private", "rprivate", "slave", "rslave", "shared", "rshared": case "private", "rprivate", "slave", "rslave", "shared", "rshared", "unbindable", "runbindable":
if foundProp { if foundProp {
return nil, errors.Wrapf(ErrDupeMntOption, "only one root propagation mode can be used") return nil, errors.Wrapf(ErrDupeMntOption, "only one root propagation mode can be used")
} }