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
}