mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Merge pull request #11190 from cyphar/expose-path-sanitisation-wrappers
Expose the getResourcePath and getRootResourcePath wrappers.
This commit is contained in:
		
						commit
						d2f0b9ed97
					
				
					 4 changed files with 75 additions and 29 deletions
				
			
		| 
						 | 
				
			
			@ -32,7 +32,6 @@ import (
 | 
			
		|||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
	"github.com/docker/docker/pkg/progressreader"
 | 
			
		||||
	"github.com/docker/docker/pkg/stringid"
 | 
			
		||||
	"github.com/docker/docker/pkg/symlink"
 | 
			
		||||
	"github.com/docker/docker/pkg/system"
 | 
			
		||||
	"github.com/docker/docker/pkg/tarsum"
 | 
			
		||||
	"github.com/docker/docker/pkg/urlutil"
 | 
			
		||||
| 
						 | 
				
			
			@ -653,14 +652,12 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec
 | 
			
		|||
		err        error
 | 
			
		||||
		destExists = true
 | 
			
		||||
		origPath   = path.Join(b.contextPath, orig)
 | 
			
		||||
		destPath   = path.Join(container.RootfsPath(), dest)
 | 
			
		||||
		destPath   string
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if destPath != container.RootfsPath() {
 | 
			
		||||
		destPath, err = symlink.FollowSymlinkInScope(destPath, container.RootfsPath())
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	destPath, err = container.GetResourcePath(dest)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Preserve the trailing '/'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -210,12 +210,37 @@ func (container *Container) LogEvent(action string) {
 | 
			
		|||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (container *Container) getResourcePath(path string) (string, error) {
 | 
			
		||||
// Evaluates `path` in the scope of the container's basefs, with proper path
 | 
			
		||||
// sanitisation. Symlinks are all scoped to the basefs of the container, as
 | 
			
		||||
// though the container's basefs was `/`.
 | 
			
		||||
//
 | 
			
		||||
// The basefs of a container is the host-facing path which is bind-mounted as
 | 
			
		||||
// `/` inside the container. This method is essentially used to access a
 | 
			
		||||
// particular path inside the container as though you were a process in that
 | 
			
		||||
// container.
 | 
			
		||||
//
 | 
			
		||||
// NOTE: The returned path is *only* safely scoped inside the container's basefs
 | 
			
		||||
//       if no component of the returned path changes (such as a component
 | 
			
		||||
//       symlinking to a different path) between using this method and using the
 | 
			
		||||
//       path. See symlink.FollowSymlinkInScope for more details.
 | 
			
		||||
func (container *Container) GetResourcePath(path string) (string, error) {
 | 
			
		||||
	cleanPath := filepath.Join("/", path)
 | 
			
		||||
	return symlink.FollowSymlinkInScope(filepath.Join(container.basefs, cleanPath), container.basefs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (container *Container) getRootResourcePath(path string) (string, error) {
 | 
			
		||||
// Evaluates `path` in the scope of the container's root, with proper path
 | 
			
		||||
// sanitisation. Symlinks are all scoped to the root of the container, as
 | 
			
		||||
// though the container's root was `/`.
 | 
			
		||||
//
 | 
			
		||||
// The root of a container is the host-facing configuration metadata directory.
 | 
			
		||||
// Only use this method to safely access the container's `container.json` or
 | 
			
		||||
// other metadata files. If in doubt, use container.GetResourcePath.
 | 
			
		||||
//
 | 
			
		||||
// NOTE: The returned path is *only* safely scoped inside the container's root
 | 
			
		||||
//       if no component of the returned path changes (such as a component
 | 
			
		||||
//       symlinking to a different path) between using this method and using the
 | 
			
		||||
//       path. See symlink.FollowSymlinkInScope for more details.
 | 
			
		||||
func (container *Container) GetRootResourcePath(path string) (string, error) {
 | 
			
		||||
	cleanPath := filepath.Join("/", path)
 | 
			
		||||
	return symlink.FollowSymlinkInScope(filepath.Join(container.root, cleanPath), container.root)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -514,7 +539,7 @@ func (streamConfig *StreamConfig) StderrLogPipe() io.ReadCloser {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (container *Container) buildHostnameFile() error {
 | 
			
		||||
	hostnamePath, err := container.getRootResourcePath("hostname")
 | 
			
		||||
	hostnamePath, err := container.GetRootResourcePath("hostname")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -528,7 +553,7 @@ func (container *Container) buildHostnameFile() error {
 | 
			
		|||
 | 
			
		||||
func (container *Container) buildHostsFiles(IP string) error {
 | 
			
		||||
 | 
			
		||||
	hostsPath, err := container.getRootResourcePath("hosts")
 | 
			
		||||
	hostsPath, err := container.GetRootResourcePath("hosts")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -894,7 +919,7 @@ func (container *Container) Unmount() error {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (container *Container) logPath(name string) (string, error) {
 | 
			
		||||
	return container.getRootResourcePath(fmt.Sprintf("%s-%s.log", container.ID, name))
 | 
			
		||||
	return container.GetRootResourcePath(fmt.Sprintf("%s-%s.log", container.ID, name))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (container *Container) ReadLog(name string) (io.Reader, error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -906,11 +931,11 @@ func (container *Container) ReadLog(name string) (io.Reader, error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (container *Container) hostConfigPath() (string, error) {
 | 
			
		||||
	return container.getRootResourcePath("hostconfig.json")
 | 
			
		||||
	return container.GetRootResourcePath("hostconfig.json")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (container *Container) jsonPath() (string, error) {
 | 
			
		||||
	return container.getRootResourcePath("config.json")
 | 
			
		||||
	return container.GetRootResourcePath("config.json")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This method must be exported to be used from the lxc template
 | 
			
		||||
| 
						 | 
				
			
			@ -980,7 +1005,7 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) {
 | 
			
		|||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	basePath, err := container.getResourcePath(resource)
 | 
			
		||||
	basePath, err := container.GetResourcePath(resource)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1082,7 +1107,7 @@ func (container *Container) setupContainerDns() error {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	container.ResolvConfPath, err = container.getRootResourcePath("resolv.conf")
 | 
			
		||||
	container.ResolvConfPath, err = container.GetRootResourcePath("resolv.conf")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1243,7 +1268,7 @@ func (container *Container) initializeNetworking() error {
 | 
			
		|||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		hostsPath, err := container.getRootResourcePath("hosts")
 | 
			
		||||
		hostsPath, err := container.GetRootResourcePath("hosts")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1374,7 +1399,7 @@ func (container *Container) setupWorkingDirectory() error {
 | 
			
		|||
	if container.Config.WorkingDir != "" {
 | 
			
		||||
		container.Config.WorkingDir = path.Clean(container.Config.WorkingDir)
 | 
			
		||||
 | 
			
		||||
		pth, err := container.getResourcePath(container.Config.WorkingDir)
 | 
			
		||||
		pth, err := container.GetResourcePath(container.Config.WorkingDir)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ func (container *Container) createVolumes() error {
 | 
			
		|||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		realPath, err := container.getResourcePath(path)
 | 
			
		||||
		realPath, err := container.GetResourcePath(path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -320,7 +320,7 @@ func (container *Container) mountVolumes() error {
 | 
			
		|||
			return fmt.Errorf("could not find volume for %s:%s, impossible to mount", source, dest)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		destPath, err := container.getResourcePath(dest)
 | 
			
		||||
		destPath, err := container.GetResourcePath(dest)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +331,7 @@ func (container *Container) mountVolumes() error {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	for _, mnt := range container.specialMounts() {
 | 
			
		||||
		destPath, err := container.getResourcePath(mnt.Destination)
 | 
			
		||||
		destPath, err := container.GetResourcePath(mnt.Destination)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -344,7 +344,7 @@ func (container *Container) mountVolumes() error {
 | 
			
		|||
 | 
			
		||||
func (container *Container) unmountVolumes() {
 | 
			
		||||
	for dest := range container.Volumes {
 | 
			
		||||
		destPath, err := container.getResourcePath(dest)
 | 
			
		||||
		destPath, err := container.GetResourcePath(dest)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logrus.Errorf("error while unmounting volumes %s: %v", destPath, err)
 | 
			
		||||
			continue
 | 
			
		||||
| 
						 | 
				
			
			@ -356,7 +356,7 @@ func (container *Container) unmountVolumes() {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	for _, mnt := range container.specialMounts() {
 | 
			
		||||
		destPath, err := container.getResourcePath(mnt.Destination)
 | 
			
		||||
		destPath, err := container.GetResourcePath(mnt.Destination)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logrus.Errorf("error while unmounting volumes %s: %v", destPath, err)
 | 
			
		||||
			continue
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,14 +115,38 @@ func (v *Volume) FromDisk() error {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (v *Volume) jsonPath() (string, error) {
 | 
			
		||||
	return v.getRootResourcePath("config.json")
 | 
			
		||||
}
 | 
			
		||||
func (v *Volume) getRootResourcePath(path string) (string, error) {
 | 
			
		||||
	cleanPath := filepath.Join("/", path)
 | 
			
		||||
	return symlink.FollowSymlinkInScope(filepath.Join(v.configPath, cleanPath), v.configPath)
 | 
			
		||||
	return v.GetRootResourcePath("config.json")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *Volume) getResourcePath(path string) (string, error) {
 | 
			
		||||
// Evalutes `path` in the scope of the volume's root path, with proper path
 | 
			
		||||
// sanitisation. Symlinks are all scoped to the root of the volume, as
 | 
			
		||||
// though the volume's root was `/`.
 | 
			
		||||
//
 | 
			
		||||
// The volume's root path is the host-facing path of the root of the volume's
 | 
			
		||||
// mountpoint inside a container.
 | 
			
		||||
//
 | 
			
		||||
// NOTE: The returned path is *only* safely scoped inside the volume's root
 | 
			
		||||
//       if no component of the returned path changes (such as a component
 | 
			
		||||
//       symlinking to a different path) between using this method and using the
 | 
			
		||||
//       path. See symlink.FollowSymlinkInScope for more details.
 | 
			
		||||
func (v *Volume) GetResourcePath(path string) (string, error) {
 | 
			
		||||
	cleanPath := filepath.Join("/", path)
 | 
			
		||||
	return symlink.FollowSymlinkInScope(filepath.Join(v.Path, cleanPath), v.Path)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Evalutes `path` in the scope of the volume's config path, with proper path
 | 
			
		||||
// sanitisation. Symlinks are all scoped to the root of the config path, as
 | 
			
		||||
// though the config path was `/`.
 | 
			
		||||
//
 | 
			
		||||
// The config path of a volume is not exposed to the container and is just used
 | 
			
		||||
// to store volume configuration options and other internal information. If in
 | 
			
		||||
// doubt, you probably want to just use v.GetResourcePath.
 | 
			
		||||
//
 | 
			
		||||
// NOTE: The returned path is *only* safely scoped inside the volume's config
 | 
			
		||||
//       path if no component of the returned path changes (such as a component
 | 
			
		||||
//       symlinking to a different path) between using this method and using the
 | 
			
		||||
//       path. See symlink.FollowSymlinkInScope for more details.
 | 
			
		||||
func (v *Volume) GetRootResourcePath(path string) (string, error) {
 | 
			
		||||
	cleanPath := filepath.Join("/", path)
 | 
			
		||||
	return symlink.FollowSymlinkInScope(filepath.Join(v.configPath, cleanPath), v.configPath)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue