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 OpenFile(path string) (*os.File, error)
- 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) CheckCreateNewFile(name string) error
- func (r Root) CheckDirectoryWritable(name string, perm os.FileMode) error
- func (r Root) CheckFileParent(name string) error
- func (r Root) CheckParents(name string) error
- func (r Root) CheckWriteFilePreservingMode(name string) error
- func (r Root) Close() error
- func (r Root) ContainsAnchoredPath(path string, anchored *os.Root) (bool, error)
- func (r Root) ContainsPath(path string) (bool, error)
- func (r Root) CreateNewFile(name string, data []byte, perm os.FileMode) error
- func (r Root) CreateNewFileAtomic(name string, data []byte, perm os.FileMode) error
- func (r Root) CreateNewFrom(name string, reader io.Reader, perm os.FileMode) (int64, error)
- func (r Root) MkdirAll(name string, perm os.FileMode) error
- func (r Root) OpenDir(name string) (*os.File, error)
- func (r Root) OpenFile(name string) (*os.File, error)
- func (r Root) OpenRoot() (*os.Root, error)
- func (r Root) Path() string
- func (r Root) ReadFile(name string) ([]byte, error)
- func (r Root) ReadFileLimited(name string, limit int64) ([]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 OpenFile ¶ added in v1.260816.0
OpenFile opens an existing regular file through a rooted traversal. Paths below the current working directory or OS temporary directory use that trusted anchor; other paths use their filesystem root. Unlike a final-component O_NOFOLLOW open, this rejects symlinks in parent components below the selected root.
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) CheckCreateNewFile ¶ added in v1.260816.0
CheckCreateNewFile performs the non-mutating checks required before CreateNewFile publishes a destination. Missing parents are accepted because the eventual rooted write creates them; existing files and symlinks are not.
func (Root) CheckDirectoryWritable ¶ added in v1.260816.0
CheckDirectoryWritable verifies that a temporary regular file can be created and removed within an existing directory beneath the root.
func (Root) CheckFileParent ¶ added in v1.260816.0
CheckFileParent validates a future file path and all existing parent components without requiring the final destination name to be absent.
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) Close ¶ added in v1.260816.0
Close releases the selected directory descriptor shared by this Root and all of its copies. Close is idempotent; no copied Root may be used afterward.
func (Root) ContainsAnchoredPath ¶ added in v1.260816.0
ContainsAnchoredPath reports whether an already-open directory is within this root. The lexical path must still resolve to the supplied directory identity; replacements between anchoring and comparison fail closed.
func (Root) ContainsPath ¶ added in v1.260816.0
ContainsPath reports whether path resolves within the directory identity selected by New. It verifies that the retained root is still reachable at its selected physical path before comparing prospective paths, so replacing the root after selection fails closed.
func (Root) CreateNewFile ¶
CreateNewFile writes data to a new file beneath the root and fails when the destination already exists. It prefers atomic no-replace publication, then falls back to rooted, no-follow O_EXCL creation when the filesystem does not support atomic no-replace rename.
func (Root) CreateNewFileAtomic ¶ added in v1.260816.0
CreateNewFileAtomic atomically publishes complete data as a new file beneath the root. It returns ErrRenameNoReplaceUnsupported instead of falling back when the filesystem cannot provide atomic no-replace rename semantics.
func (Root) CreateNewFrom ¶ added in v1.260816.0
CreateNewFrom atomically publishes reader's complete contents as a new file beneath the root. It stages an unpredictable no-follow file in the same directory, syncs and closes it, then uses an atomic no-replace rename. A read, write, sync, close, or publish failure leaves an existing destination intact.
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) OpenDir ¶ added in v1.260816.0
OpenDir opens an existing directory beneath the root without following symlinks in the final component or in any component below the root.
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) OpenRoot ¶ added in v1.260816.0
OpenRoot opens the trusted root without following symlinks introduced after New selected it. New records the physical target of a pre-existing trusted symlink layout, while later path substitutions cannot change the selected directory identity. Every physical component and the final root are reopened from parent directory handles.
func (Root) ReadFileLimited ¶ added in v1.260816.0
ReadFileLimited reads at most limit bytes from a regular file beneath the root. It rejects, rather than truncates, files that exceed the limit.
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.