Proposal Details
This is a continuation of #47049, which was retracted with the following comment:
Treating this as retracted, but it seems like we reached a reasonable API change. What we don't know is whether it is good enough in practice or whether anyone needs it. If someone does need it, please feel free to open a new proposal and we can continue this discussion. Thanks.
I have a Golang binary that gets deployed once and then it os/exec's the git binary with various arguments under the hood hundreds of thousands of times to process lots of untrusted repositories on the internet.
This git invocation ideally should only access a single temporary directory that we create for it and doesn't need anything else, yet the invoking Golang binary needs an access to much more files and directories, including the networking. So basically, I'm looking to exercise the least privilege principle here.
Unfortunately due to Go's runtime and the use of threads, it seems to be somewhat complicated to use fork(2), and even if it would work, it would mean re-inventing the os/exec.
It'd be great if one could do something like this on instead:
cmd.SysProcAttr = &syscall.SysProcAttr{
UseLandlock: true,
LandlockRuleset: fd,
}
There's a nice github.com/landlock-lsm/go-landlock package with a very ergonomic API that can be adapted to emit the ruleset file-descriptor instead of restricting the current process with a couple of line changes.
To get the fd for the *syscall.SysProcAttr above, the user might do something like this:
fd, err := landlock.V5.BestEffort().OnlyPaths().Ruleset(
landlock.ROFiles("/usr"),
landlock.RWFiles(tmpDir),
)
/cc @rsc
Proposal Details
This is a continuation of #47049, which was retracted with the following comment:
I have a Golang binary that gets deployed once and then it
os/exec's thegitbinary with various arguments under the hood hundreds of thousands of times to process lots of untrusted repositories on the internet.This
gitinvocation ideally should only access a single temporary directory that we create for it and doesn't need anything else, yet the invoking Golang binary needs an access to much more files and directories, including the networking. So basically, I'm looking to exercise the least privilege principle here.Unfortunately due to Go's runtime and the use of threads, it seems to be somewhat complicated to use
fork(2), and even if it would work, it would mean re-inventing theos/exec.It'd be great if one could do something like this on instead:
There's a nice
github.com/landlock-lsm/go-landlockpackage with a very ergonomic API that can be adapted to emit the ruleset file-descriptor instead of restricting the current process with a couple of line changes.To get the
fdfor the*syscall.SysProcAttrabove, the user might do something like this:/cc @rsc
Note
Updated to match rsc@'s suggestions from #68595 (comment) below. (Renamed flags, made
no_new_privsan orthogonal setting)Motivation
Landlock is an unprivileged sandboxing mechanism provided by Linux's Landlock LSM, which is enabled by default on many Linux distributions:
The goal is that Go programs can create subprocesses that run in Landlock sandboxes, without affecting the Go program from which these subprocesses are created.
Without this proposal…