Pass root to chroot to for chroot Untar

This is useful for preventing CVE-2018-15664 where a malicious container
process can take advantage of a race on symlink resolution/sanitization.

Before this change chrootarchive would chroot to the destination
directory which is attacker controlled. With this patch we always chroot
to the container's root which is not attacker controlled.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff
2019-05-30 11:15:09 -07:00
parent 8d760280a2
commit d089b63937
5 changed files with 132 additions and 12 deletions

View File

@@ -31,11 +31,12 @@ type archiver interface {
}
// helper functions to extract or archive
func extractArchive(i interface{}, src io.Reader, dst string, opts *archive.TarOptions) error {
func extractArchive(i interface{}, src io.Reader, dst string, opts *archive.TarOptions, root string) error {
if ea, ok := i.(extractor); ok {
return ea.ExtractArchive(src, dst, opts)
}
return chrootarchive.Untar(src, dst, opts)
return chrootarchive.UntarWithRoot(src, dst, opts, root)
}
func archivePath(i interface{}, src string, opts *archive.TarOptions) (io.ReadCloser, error) {
@@ -367,7 +368,7 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path
}
}
if err := extractArchive(driver, content, resolvedPath, options); err != nil {
if err := extractArchive(driver, content, resolvedPath, options, container.BaseFS.Path()); err != nil {
return err
}