volumes: be more tolerant and fix infinite loop

Make Podman more tolerant when parsing image volumes during container
creation and further fix an infinite loop when checking them.

Consider `VOLUME ['/etc/foo', '/etc/bar']` in a Containerfile.  While
it looks correct to the human eye, the single quotes are wrong and yield
the two volumes to be `[/etc/foo,` and `/etc/bar]` in Podman and Docker.

When running the container, it'll create a directory `bar]` in `/etc`
and a directory `[` in `/` with two subdirectories `etc/foo,`.  This
behavior is surprising to me but how Docker behaves.  We may improve on
that in the future.  Note that the correct way to syntax for volumes in
a Containerfile is `VOLUME /A /B /C` or `VOLUME ["/A", "/B", "/C"]`;
single quotes are not supported.

This change restores this behavior without breaking container creation
or ending up in an infinite loop.

BZ: https://bugzilla.redhat.com/show_bug.cgi?id=2014149
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2021-10-27 17:30:37 +02:00
parent 979b631228
commit c5f0a5d788
3 changed files with 10 additions and 4 deletions

View File

@ -161,7 +161,7 @@ func isPathOnBindMount(c *Container, containerPath string) bool {
if cleanedContainerPath == filepath.Clean(m.Destination) {
return true
}
for dest := m.Destination; dest != "/"; dest = filepath.Dir(dest) {
for dest := m.Destination; dest != "/" && dest != "."; dest = filepath.Dir(dest) {
if cleanedContainerPath == dest {
return true
}

View File

@ -214,9 +214,6 @@ func getImageVolumes(ctx context.Context, img *libimage.Image, s *specgen.SpecGe
}
for volume := range inspect.Config.Volumes {
logrus.Debugf("Image has volume at %q", volume)
if err = parse.ValidateVolumeCtrDir(volume); err != nil {
return nil, nil, err
}
cleanDest := filepath.Clean(volume)
switch mode {
case "", "anonymous":

View File

@ -39,6 +39,7 @@ EOF
cat >$dockerfile <<EOF
FROM $IMAGE
RUN echo $rand_content > /$rand_filename
VOLUME ['/etc/foo', '/etc/bar']
EOF
run_podman buildx build --load -t build_test --format=docker $tmpdir
@ -47,6 +48,14 @@ EOF
run_podman run --rm build_test cat /$rand_filename
is "$output" "$rand_content" "reading generated file in image"
# Make sure the volumes are created at surprising yet Docker-compatible
# destinations (see bugzilla.redhat.com/show_bug.cgi?id=2014149).
run_podman run --rm build_test find /[ /etc/bar\] -print
is "$output" "/\[
/\[/etc
/\[/etc/foo,
/etc/bar]" "weird VOLUME gets converted to directories with brackets and comma"
run_podman rmi -f build_test
}