Documentation ¶
Overview ¶
Package golandlock restricts a Go program's ability to use files.
The following invocation will restrict all goroutines so that they can only read from /usr, /bin and /tmp, and only write to /tmp:
err := golandlock.V1.BestEffort().RestrictPaths( golandlock.RODirs("/usr", "/bin"), golandlock.RWDirs("/tmp"), )
This will restrict file access using Landlock V1, if available. If unavailable, it will attempt using earlier Landlock versions than the one requested. If no Landlock version is available, it will still succeed, without restricting file accesses.
More possible invocations ¶
golandlock.V1.RestrictPaths(...) enforces the given rules using the capabilities of Landlock V1, but returns an error if that is not available.
Landlock ABI versioning ¶
Callers need to identify at which ABI level they want to use Landlock and call RestrictPaths on the corresponding ABI constant. Currently the only available ABI variant is V1, which restricts basic filesystem operations.
When new Landlock versions become available in golandlock, users will need to upgrade their usages manually to higher Landlock versions, as there is a risk that new Landlock versions will break operations that their programs rely on.
Graceful degradation on older kernels ¶
Programs that get run on different kernel versions will want to use the Config.BestEffort() method to gracefully degrade to using the best available Landlock version on the current kernel.
Caveats ¶
This warning only applies to programs using cgo and linking C libraries that start OS threads through means other than pthread_create() before golandlock is called:
When using cgo, golandlock relies on libpsx in order to apply the rules across all OS threads, (rather than just the ones managed by the Go runtime). psx achieves this by wrapping the C-level phtread_create() API which is very commonly used on Unix to start threads. However, C libraries calling clone(2) through other means before golandlock is called might still create threads that won't have Landlock protections.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // Landlock V1 support (basic file operations). V1 = Config{ // contains filtered or unexported fields } )
These are the currently supported Landlock ABI versions.
The higher the ABI version, the more operations Landlock will be able to restrict.
Functions ¶
func PathAccess ¶
func PathAccess(accessFS AccessFSSet, paths ...string) pathOpt
PathAccess is a RestrictPaths() option that grants the access right specified by accessFS to the file hierarchies under the given paths.
When accessFS is larger than what is permitted by the Landlock version in use, only the applicable subset of accessFS will be used.
Most users should use the functions RODirs, RWDirs, ROFiles and RWFiles instead, which provide canned options for commonly used values of accessFS.
Filesystem access rights are represented using bits in a uint64. The individual access rights and their meaning are defined in the golandlock/syscall package and explained further in the kernel documentation at https://www.kernel.org/doc/html/latest/userspace-api/landlock.html#access-rights
func RODirs ¶
func RODirs(paths ...string) pathOpt
RODirs is a RestrictPaths() option that grants common read-only access to files and directories and permits executing files.
func ROFiles ¶
func ROFiles(paths ...string) pathOpt
ROFiles is a RestrictPaths() option that grants common read access to individual files, but not to directories, for the file hierarchies under the given paths.
Types ¶
type AccessFSSet ¶
type AccessFSSet uint64
AccessFSSet is a set of Landlockable file system access operations.
func (AccessFSSet) String ¶
func (a AccessFSSet) String() string
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
The Landlock configuration describes the desired Landlock ABI level and operations to be restricted.
func (Config) BestEffort ¶
BestEffort returns a config that will opportunistically enforce the strongest rules it can, up to the given ABI version, working with the level of Landlock support available in the running kernel.
Warning: A best-effort call to RestrictPaths() will succeed without error even when Landlock is not available at all on the current kernel.
func (Config) RestrictPaths ¶
RestrictPaths restricts all goroutines to only "see" the files provided as inputs. After this call successfully returns, the goroutines will only be able to use files in the ways as they were specified in advance in the call to RestrictPaths.
Example: The following invocation will restrict all goroutines so that it can only read from /usr, /bin and /tmp, and only write to /tmp:
err := golandlock.V1.RestrictPaths( golandlock.RODirs("/usr", "/bin"), golandlock.RWDirs("/tmp"), ) if err != nil { log.Fatalf("golandlock.V1.RestrictPaths(): %v", err) }
RestrictPaths returns an error if any of the given paths does not denote an actual directory or file, or if Landlock can't be enforced using the desired ABI version constraints.
RestrictPaths also sets the "no new privileges" flag for all OS threads managed by the Go runtime.
Restrictable access rights ¶
The notions of what "reading" and "writing" mean are limited by what the selected Landlock version supports.
Calling RestrictPaths() with a given Landlock ABI version will inhibit all future calls to the access rights supported by this ABI version, unless the accessed path is in a file hierarchy that is specifically allow-listed for a specific set of access rights.
The overall set of operations that RestrictPaths can restrict are:
For reading:
• Executing a file (V1+)
• Opening a file with read access (V1+)
• Opening a directory or listing its content (V1+)
For writing:
• Opening a file with write access (V1+)
For directory manipulation:
• Removing an empty directory or renaming one (V1+)
• Removing (or renaming) a file (V1+)
• Creating (or renaming or linking) a character device (V1+)
• Creating (or renaming) a directory (V1+)
• Creating (or renaming or linking) a regular file (V1+)
• Creating (or renaming or linking) a UNIX domain socket (V1+)
• Creating (or renaming or linking) a named pipe (V1+)
• Creating (or renaming or linking) a block device (V1+)
• Creating (or renaming or linking) a symbolic link (V1+)
Future versions of Landlock will be able to inhibit more operations. Quoting the Landlock documentation:
It is currently not possible to restrict some file-related actions accessible through these syscall families: chdir(2), truncate(2), stat(2), flock(2), chmod(2), chown(2), setxattr(2), utime(2), ioctl(2), fcntl(2), access(2). Future Landlock evolutions will enable to restrict them.
The access rights are documented in more depth at: https://www.kernel.org/doc/html/latest/userspace-api/landlock.html#access-rights
Helper functions for selecting access rights ¶
These helper functions help selecting common subsets of access rights:
• RODirs() selects access rights in the group "for reading". In V1, this means reading files, listing directories and executing files.
• RWDirs() selects access rights in the group "for reading", "for writing" and "for directory manipulation". In V1, this grants the full set of access rights.
• ROFiles() is like RODirs(), but does not select directory-specific access rights. In V1, this means reading and executing files.
• RWFiles() is like RWDirs(), but does not select directory-specific access rights. In V1, this means reading, writing and executing files.
The PathAccess() option lets callers define custom subsets of these access rights.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
Package syscall provides a low-level interface to the Linux Landlock sandboxing feature.
|
Package syscall provides a low-level interface to the Linux Landlock sandboxing feature. |