rootfs

package
v1.260801.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 1, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package rootfs provides rooted filesystem operations for paths that are not fully trusted, such as filenames, directory components, or manifest entries that come from a repository checkout or a remote API response.

Every operation is anchored to a trusted root chosen by the operator (for example a --out-dir flag, a manifest directory, or the resolved .asc directory). Paths are validated lexically so absolute paths, volume or UNC-style changes, and parent traversal are rejected, and filesystem access refuses to follow symlinks for any component below the root. Writes stage through unpredictable, exclusive, no-follow temporary files so a pre-created symlink cannot redirect them.

Roots created with AllowingInternalSymlinks relax only the parent-component rule, accepting a symlinked directory whose target stays inside the root; a symlinked final component is always refused.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrEscapesRoot reports a path that does not stay beneath the trusted root.
	ErrEscapesRoot = errors.New("path escapes trusted root")
	// ErrSymlink reports a path component that is a symlink below the trusted root.
	ErrSymlink = errors.New("refusing to follow symlink")
)

Functions

func ValidateRelative

func ValidateRelative(name string) error

ValidateRelative reports whether name is safe to join onto a trusted root. Both Unix and Windows separator conventions are considered so a repository can not smuggle a drive-relative, UNC-style, or backslash-traversing path past validation on a different host platform.

func ValidateRelativeAllowingTraversal

func ValidateRelativeAllowingTraversal(name string) error

ValidateRelativeAllowingTraversal rejects absolute, drive-relative and UNC-style paths but permits ".." segments, for callers that resolve a path against a base directory below the root and then confirm containment of the joined result with Resolve.

Types

type Root

type Root struct {
	// contains filtered or unexported fields
}

Root is a trusted directory anchor for rooted filesystem operations.

func New

func New(path string) (Root, error)

New returns a Root anchored at path. The root itself is operator-selected and may live outside the current repository; only paths below it are constrained.

func (r Root) AllowingInternalSymlinks() Root

AllowingInternalSymlinks returns a copy of the root that accepts a symlinked directory component below the root when that component resolves back inside the root, and still rejects one that escapes.

Use it only where symlinked directories inside the root are an established, supported layout. A symlinked final component is still refused.

func (Root) AppendFile

func (r Root) AppendFile(name string, data []byte, perm os.FileMode) error

AppendFile appends data to a file beneath the root, creating it when missing, without following a final or parent symlink.

func (Root) CheckContained

func (r Root) CheckContained(name string) error

CheckContained verifies that name stays beneath the root and that neither its parent components nor its final component is a symlink below the root.

func (Root) CheckParents

func (r Root) CheckParents(name string) error

CheckParents verifies that name stays beneath the root and that every component below the root leading to it is acceptable under the root's symlink policy. The final component is not inspected.

func (Root) CheckWriteFilePreservingMode

func (r Root) CheckWriteFilePreservingMode(name string) error

CheckWriteFilePreservingMode performs the non-mutating checks required before WriteFilePreservingMode replaces an existing file. Missing destinations are accepted; callers can use this to preflight a multi-file plan before its first write.

func (Root) CreateNewFile

func (r Root) CreateNewFile(name string, data []byte, perm os.FileMode) error

CreateNewFile writes data to a new file beneath the root and fails when the destination already exists.

func (Root) MkdirAll

func (r Root) MkdirAll(name string, perm os.FileMode) error

MkdirAll creates name and any missing parents beneath the root, rejecting any existing component that is a symlink or not a directory.

func (Root) OpenFile

func (r Root) OpenFile(name string) (*os.File, error)

OpenFile opens an existing regular file beneath the root without following symlinks in the final component or in any component below the root.

func (Root) Path

func (r Root) Path() string

Path returns the absolute trusted root path.

func (Root) ReadFile

func (r Root) ReadFile(name string) ([]byte, error)

ReadFile reads a regular file beneath the root without following symlinks.

func (Root) ReadFileOptional

func (r Root) ReadFileOptional(name string) ([]byte, bool, error)

ReadFileOptional reads a regular file beneath the root and reports whether it exists. A missing file is not an error; a symlinked path still is.

func (Root) Resolve

func (r Root) Resolve(name string) (string, error)

Resolve validates name and returns its absolute path beneath the root. name may be relative to the root or an absolute path that is already inside it.

func (r Root) ResolveContainedFinalSymlink(name string) (string, error)

ResolveContainedFinalSymlink resolves a final symlink only when its physical target remains beneath this root. The returned name is relative to the root and contains no symlink components, so callers can perform the actual I/O through rooted no-follow operations without reopening the link.

func (Root) WriteFile

func (r Root) WriteFile(name string, data []byte, perm os.FileMode) error

WriteFile atomically creates or replaces a file beneath the root.

func (Root) WriteFilePreservingMode

func (r Root) WriteFilePreservingMode(name string, data []byte, perm os.FileMode) error

WriteFilePreservingMode atomically creates or replaces a regular file beneath the root. Existing files retain supported ownership, permission, ACL, and extended-attribute metadata without mutating aliases outside the rooted path. Where the platform exposes link counts, multiply linked files are refused rather than silently changing hard-link semantics. New files use perm subject to the process umask.

func (Root) WriteFrom

func (r Root) WriteFrom(name string, reader io.Reader, perm os.FileMode) (int64, error)

WriteFrom atomically creates or replaces a file beneath the root with the contents of reader and returns the number of bytes written.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL