-
Notifications
You must be signed in to change notification settings - Fork 18k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: syscall: support process sandboxing using Landlock on Linux #68595
Comments
Related Issues and Documentation (Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
I've actually toyed a bit with the Golang's source code, and this patch seems to work just fine on diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index e4b9ce1bf4..6359b129ff 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -109,6 +109,9 @@ type SysProcAttr struct {
// functionality is supported by the kernel, or -1. Note *PidFD is
// changed only if the process starts successfully.
PidFD *int
+ // Landlock LSM
+ UseLandlock bool
+ LandlockRuleset int
}
var (
@@ -645,6 +648,19 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
}
}
+ // Landlock LSM
+ if sys.UseLandlock {
+ _, _, err1 = RawSyscall(SYS_PRCTL, PR_SET_NO_NEW_PRIVS, 1, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+
+ _, _, err1 = RawSyscall(SYS_LANDLOCK_RESTRICT_SELF, uintptr(sys.LandlockRuleset), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
// Time to exec.
_, _, err1 = RawSyscall(SYS_EXECVE,
uintptr(unsafe.Pointer(argv0)),
diff --git a/src/syscall/zsysnum_linux_amd64.go b/src/syscall/zsysnum_linux_amd64.go
index 576c7c36a6..5b32beb830 100644
--- a/src/syscall/zsysnum_linux_amd64.go
+++ b/src/syscall/zsysnum_linux_amd64.go
@@ -309,4 +309,5 @@ const (
SYS_FANOTIFY_INIT = 300
SYS_FANOTIFY_MARK = 301
SYS_PRLIMIT64 = 302
+ SYS_LANDLOCK_RESTRICT_SELF = 446
) This clearly needs more documentation and a thorough analysis of whether (1) the placement of Landlock LSM invocation is correct and whether (2) the ruleset FD won't be closed at the point of But besides that, the system call constant values defined in To implement the support for all architectures, one only needs a single What is the correct approach to add new system call definitions in this case? As far as I understand it's not possible to use |
New system calls needed by the standard library are put into internal/syscall/unix. |
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 thegit
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 theos/exec
.It'd be great if one could do something like this on instead:
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:/cc @rsc
The text was updated successfully, but these errors were encountered: