daemon: containerExtractToDir: combine checks for read-only target

Combine the check for read-only volume paths and the container's rootFS
to be read-only into a single check.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-01-04 23:34:53 +01:00
parent 0530750d7e
commit ca0158b235
2 changed files with 25 additions and 34 deletions

View File

@@ -126,18 +126,11 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path
return errdefs.InvalidParameter(errors.New("extraction point is not a directory"))
}
// Need to check if the path is in a volume. If it is, it cannot be in a
// read-only volume. If it is not in a volume, the container cannot be
// configured with a read-only rootfs.
toVolume, err := checkIfPathIsInAVolume(container, absPath)
if err != nil {
// Check that the destination is not a read-only filesystem.
if err := checkWritablePath(container, absPath); err != nil {
return err
}
if !toVolume && container.HostConfig.ReadonlyRootfs {
return errdefs.InvalidParameter(errors.New("container rootfs is marked read-only"))
}
options := daemon.defaultTarCopyOptions(noOverwriteDirNonDir)
if copyUIDGID {
@@ -161,19 +154,22 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path
return nil
}
// checkIfPathIsInAVolume checks if the path is in a volume. If it is, it
// cannot be in a read-only volume. If it is not in a volume, the container
// cannot be configured with a read-only rootfs.
func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) {
var toVolume bool
// checkWritablePath checks if the path is in a writable location inside the
// container. If the path is within a location mounted from a volume, it checks
// if the volume is mounted read-only. If it is not in a volume, it checks whether
// the container's rootfs is mounted read-only.
func checkWritablePath(ctr *container.Container, absPath string) error {
parser := volumemounts.NewParser()
for _, mnt := range container.MountPoints {
if toVolume = parser.HasResource(mnt, absPath); toVolume {
for _, mnt := range ctr.MountPoints {
if isVolumePath := parser.HasResource(mnt, absPath); isVolumePath {
if mnt.RW {
break
return nil
}
return false, errdefs.InvalidParameter(errors.New("mounted volume is marked read-only"))
return errdefs.InvalidParameter(errors.New("mounted volume is marked read-only"))
}
}
return toVolume, nil
if ctr.HostConfig.ReadonlyRootfs {
return errdefs.InvalidParameter(errors.New("container rootfs is marked read-only"))
}
return nil
}

View File

@@ -229,18 +229,11 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path
}
}
// Make it an absolute path.
absPath = filepath.Join(string(filepath.Separator), baseRel)
toVolume, err := checkIfPathIsInAVolume(container, absPath)
if err != nil {
if err := checkWritablePath(container, absPath); err != nil {
return err
}
if !toVolume && container.HostConfig.ReadonlyRootfs {
return errdefs.InvalidParameter(errors.New("container rootfs is marked read-only"))
}
options := daemon.defaultTarCopyOptions(noOverwriteDirNonDir)
if err := chrootarchive.UntarWithRoot(content, resolvedPath, options, container.BaseFS); err != nil {
return err
@@ -324,14 +317,16 @@ func (daemon *Daemon) containerCopy(container *container.Container, resource str
return reader, nil
}
// checkIfPathIsInAVolume checks if the path is in a volume. If it is, it
// cannot be in a read-only volume. If it is not in a volume, the container
// cannot be configured with a read-only rootfs.
// checkWritablePath is a no-op on Windows, which does not support read-only
// rootFS for containers, does not support read-only volumes, or extracting
// to a mount point inside a volume.
//
// This is a no-op on Windows which does not support read-only volumes, or
// extracting to a mount point inside a volume. TODO Windows: FIXME Post-TP5
func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) {
return false, nil
// TODO(thaJeztah): add check for writable path once windows supports read-only rootFS and (read-only) volumes during copy
//
// - e5261d6e4a1e96d4c0fa4b4480042046b695eda1 added "FIXME Post-TP4 / TP5"; check whether this would be possible to implement on Windows.
// - e5261d6e4a1e96d4c0fa4b4480042046b695eda1 added "or extracting to a mount point inside a volume"; check whether this is is still true, and adjust this check accordingly
func checkWritablePath(_ *container.Container, _ string) error {
return nil
}
// isOnlineFSOperationPermitted returns an error if an online filesystem operation