pathrs

package module
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Mar 3, 2026 License: MPL-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package pathrs provides bindings for libpathrs, a library for safe path resolution on Linux.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Handle

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

Handle is a handle for a path within a given Root. This handle references an already-resolved path which can be used for only one purpose -- to "re-open" the handle and get an actual os.File which can be used for ordinary operations.

If you wish to open a file without having an intermediate Handle object, you can try to use Root.Open or Root.OpenFile.

It is critical that perform all relevant operations through this Handle (rather than fetching the underlying os.File yourself with Handle.IntoFile), because the security properties of libpathrs depend on users doing all relevant filesystem operations through libpathrs.

func HandleFromFile

func HandleFromFile(file *os.File) (*Handle, error)

HandleFromFile creates a new Handle from an existing file handle. The handle will be copied by this method, so the original handle should still be freed by the caller.

This is effectively the inverse operation of Handle.IntoFile, and is used for "deserialising" pathrs root handles.

func (*Handle) Clone

func (h *Handle) Clone() (*Handle, error)

Clone creates a copy of a Handle, such that it has a separate lifetime to the original (while referring to the same underlying file).

func (*Handle) Close

func (h *Handle) Close() error

Close frees all of the resources used by the Handle.

func (*Handle) IntoFile

func (h *Handle) IntoFile() *os.File

IntoFile unwraps the Handle into its underlying os.File.

You almost certainly want to use Handle.OpenFile to get a non-O_PATH version of this Handle.

This operation returns the internal os.File of the Handle directly, so calling Handle.Close will also close any copies of the returned os.File. If you want to get an independent copy, use Handle.Clone followed by Handle.IntoFile on the cloned Handle.

func (*Handle) Open

func (h *Handle) Open() (*os.File, error)

Open creates an "upgraded" file handle to the file referenced by the Handle. Note that the original Handle is not consumed by this operation, and can be opened multiple times.

The handle returned is only usable for reading, and this is method is shorthand for Handle.OpenFile with os.O_RDONLY.

TODO: Rename these to "Reopen" or something.

func (*Handle) OpenFile

func (h *Handle) OpenFile(flags int) (*os.File, error)

OpenFile creates an "upgraded" file handle to the file referenced by the Handle. Note that the original Handle is not consumed by this operation, and can be opened multiple times.

The provided flags indicate which open(2) flags are used to create the new handle.

TODO: Rename these to "Reopen" or something.

type Root

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

Root is a handle to the root of a directory tree to resolve within. The only purpose of this "root handle" is to perform operations within the directory tree, or to get a Handle to inodes within the directory tree.

At time of writing, it is considered a *VERY BAD IDEA* to open a Root inside a possibly-attacker-controlled directory tree. While we do have protections that should defend against it, it's far more dangerous than just opening a directory tree which is not inside a potentially-untrusted directory.

func OpenRoot

func OpenRoot(path string) (*Root, error)

OpenRoot creates a new Root handle to the directory at the given path.

func RootFromFile

func RootFromFile(file *os.File) (*Root, error)

RootFromFile creates a new Root handle from an os.File referencing a directory. The provided file will be duplicated, so the original file should still be closed by the caller.

This is effectively the inverse operation of Root.IntoFile.

func (*Root) Clone

func (r *Root) Clone() (*Root, error)

Clone creates a copy of a Root handle, such that it has a separate lifetime to the original (while referring to the same underlying directory).

func (*Root) Close

func (r *Root) Close() error

Close frees all of the resources used by the Root handle.

func (*Root) Create

func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error)

Create creates a file within the Root's directory tree at the given path, and returns a handle to the file. The provided mode is used for the new file (the process's umask applies).

Unlike os.Create, if the file already exists an error is created rather than the file being opened and truncated.

func (r *Root) Hardlink(path, target string) error

Hardlink creates a hardlink within a Root's directory tree. The hardlink is created at path and is a link to target. Both paths are within the Root's directory tree (you cannot hardlink to a different Root or the host).

This is effectively equivalent to os.Link.

func (*Root) IntoFile

func (r *Root) IntoFile() *os.File

IntoFile unwraps the Root into its underlying os.File.

It is critical that you do not operate on this file descriptor yourself, because the security properties of libpathrs depend on users doing all relevant filesystem operations through libpathrs.

This operation returns the internal os.File of the Root directly, so calling Root.Close will also close any copies of the returned os.File. If you want to get an independent copy, use Root.Clone followed by Root.IntoFile on the cloned Root.

func (*Root) Mkdir

func (r *Root) Mkdir(path string, mode os.FileMode) error

Mkdir creates a directory within a Root's directory tree. The provided mode is used for the new directory (the process's umask applies).

This is effectively equivalent to os.Mkdir.

func (*Root) MkdirAll

func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error)

MkdirAll creates a directory (and any parent path components if they don't exist) within a Root's directory tree. The provided mode is used for any directories created by this function (the process's umask applies).

This is effectively equivalent to os.MkdirAll.

func (*Root) Mknod

func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error

Mknod creates a new device inode of the given type within a Root's directory tree. The provided mode is used for the new directory (the process's umask applies).

This is effectively equivalent to golang.org/x/sys/unix.Mknod.

func (*Root) Open

func (r *Root) Open(path string) (*os.File, error)

Open is effectively shorthand for [Resolve] followed by Handle.Open, but can be slightly more efficient (it reduces CGo overhead and the number of syscalls used when using the openat2-based resolver) and is arguably more ergonomic to use.

This is effectively equivalent to os.Open.

func (*Root) OpenFile

func (r *Root) OpenFile(path string, flags int) (*os.File, error)

OpenFile is effectively shorthand for [Resolve] followed by Handle.OpenFile, but can be slightly more efficient (it reduces CGo overhead and the number of syscalls used when using the openat2-based resolver) and is arguably more ergonomic to use.

However, if flags contains os.O_NOFOLLOW and the path is a symlink, then OpenFile's behaviour will match that of openat2. In most cases an error will be returned, but if os.O_PATH is provided along with os.O_NOFOLLOW then a file equivalent to [ResolveNoFollow] will be returned instead.

This is effectively equivalent to os.OpenFile, except that os.O_CREAT is not supported.

func (r *Root) Readlink(path string) (string, error)

Readlink returns the target of a symlink with a Root's directory tree.

This is effectively equivalent to os.Readlink.

func (*Root) Remove

func (r *Root) Remove(path string) error

Remove removes the named file or (empty) directory within a Root's directory tree.

This is effectively equivalent to os.Remove.

func (*Root) RemoveAll

func (r *Root) RemoveAll(path string) error

RemoveAll recursively deletes a path and all of its children.

This is effectively equivalent to os.RemoveAll.

func (*Root) RemoveDir

func (r *Root) RemoveDir(path string) error

RemoveDir removes the named empty directory within a Root's directory tree.

func (*Root) RemoveFile

func (r *Root) RemoveFile(path string) error

RemoveFile removes the named file within a Root's directory tree.

func (*Root) Rename

func (r *Root) Rename(src, dst string, flags uint) error

Rename two paths within a Root's directory tree. The flags argument is identical to the RENAME_* flags to the renameat2(2) system call.

func (*Root) Resolve

func (r *Root) Resolve(path string) (*Handle, error)

Resolve resolves the given path within the Root's directory tree, and returns a Handle to the resolved path. The path must already exist, otherwise an error will occur.

All symlinks (including trailing symlinks) are followed, but they are resolved within the rootfs. If you wish to open a handle to the symlink itself, use [ResolveNoFollow].

func (*Root) ResolveNoFollow

func (r *Root) ResolveNoFollow(path string) (*Handle, error)

ResolveNoFollow is effectively an O_NOFOLLOW version of [Resolve]. Their behaviour is identical, except that *trailing* symlinks will not be followed. If the final component is a trailing symlink, an O_PATH|O_NOFOLLOW handle to the symlink itself is returned.

func (r *Root) Symlink(path, target string) error

Symlink creates a symlink within a Root's directory tree. The symlink is created at path and is a link to target.

This is effectively equivalent to os.Symlink.

Directories

Path Synopsis
internal
fdutils
Package fdutils contains a few helper methods when dealing with *os.File and file descriptors.
Package fdutils contains a few helper methods when dealing with *os.File and file descriptors.
libpathrs
Package libpathrs is an internal thin wrapper around the libpathrs C API.
Package libpathrs is an internal thin wrapper around the libpathrs C API.
Package procfs provides a safe API for operating on /proc on Linux.
Package procfs provides a safe API for operating on /proc on Linux.

Jump to

Keyboard shortcuts

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