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 ¶
- Variables
- func ValidateRelative(name string) error
- func ValidateRelativeAllowingTraversal(name string) error
- type Root
- func (r Root) AllowingInternalSymlinks() Root
- func (r Root) AppendFile(name string, data []byte, perm os.FileMode) error
- func (r Root) CheckContained(name string) error
- func (r Root) CheckParents(name string) error
- func (r Root) CheckWriteFilePreservingMode(name string) error
- func (r Root) CreateNewFile(name string, data []byte, perm os.FileMode) error
- func (r Root) MkdirAll(name string, perm os.FileMode) error
- func (r Root) OpenFile(name string) (*os.File, error)
- func (r Root) Path() string
- func (r Root) ReadFile(name string) ([]byte, error)
- func (r Root) ReadFileOptional(name string) ([]byte, bool, error)
- func (r Root) Resolve(name string) (string, error)
- func (r Root) ResolveContainedFinalSymlink(name string) (string, error)
- func (r Root) WriteFile(name string, data []byte, perm os.FileMode) error
- func (r Root) WriteFilePreservingMode(name string, data []byte, perm os.FileMode) error
- func (r Root) WriteFrom(name string, reader io.Reader, perm os.FileMode) (int64, error)
Constants ¶
This section is empty.
Variables ¶
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 ¶
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 ¶
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 ¶
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 (Root) AllowingInternalSymlinks ¶
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 ¶
AppendFile appends data to a file beneath the root, creating it when missing, without following a final or parent symlink.
func (Root) CheckContained ¶
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 ¶
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 ¶
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 ¶
CreateNewFile writes data to a new file beneath the root and fails when the destination already exists.
func (Root) MkdirAll ¶
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 ¶
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) ReadFileOptional ¶
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 ¶
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 (Root) ResolveContainedFinalSymlink ¶
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) WriteFilePreservingMode ¶
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.