|
@@ -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
|
|
|
}
|