mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-11-04 14:49:53 +08:00
Add MacOS sandbox support
This commit is contained in:
parent
3fd00038db
commit
bc0b7f92f1
@ -3,6 +3,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -17,6 +19,8 @@ var (
|
|||||||
timeLimit, realTimeLimit, memoryLimit, outputLimit, stackLimit uint64
|
timeLimit, realTimeLimit, memoryLimit, outputLimit, stackLimit uint64
|
||||||
inputFileName, outputFileName, errorFileName, workPath string
|
inputFileName, outputFileName, errorFileName, workPath string
|
||||||
|
|
||||||
|
profilePath string
|
||||||
|
|
||||||
args []string
|
args []string
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,6 +35,7 @@ func main() {
|
|||||||
flag.StringVar(&outputFileName, "out", "", "Set output file name")
|
flag.StringVar(&outputFileName, "out", "", "Set output file name")
|
||||||
flag.StringVar(&errorFileName, "err", "", "Set error file name")
|
flag.StringVar(&errorFileName, "err", "", "Set error file name")
|
||||||
flag.StringVar(&workPath, "work-path", "", "Set the work path of the program")
|
flag.StringVar(&workPath, "work-path", "", "Set the work path of the program")
|
||||||
|
flag.StringVar(&profilePath, "p", "", "sandbox profile")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
args = flag.Args()
|
args = flag.Args()
|
||||||
@ -61,6 +66,15 @@ func start() (*runner.Result, error) {
|
|||||||
}
|
}
|
||||||
defer closeFiles(files)
|
defer closeFiles(files)
|
||||||
|
|
||||||
|
var profile string
|
||||||
|
if profilePath != "" {
|
||||||
|
c, err := ioutil.ReadFile(profilePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("profile: %v", err)
|
||||||
|
}
|
||||||
|
profile = string(c)
|
||||||
|
}
|
||||||
|
|
||||||
// if not defined, then use the original value
|
// if not defined, then use the original value
|
||||||
fds := make([]uintptr, len(files))
|
fds := make([]uintptr, len(files))
|
||||||
for i, f := range files {
|
for i, f := range files {
|
||||||
@ -89,7 +103,7 @@ func start() (*runner.Result, error) {
|
|||||||
RLimits: rlims.PrepareRLimit(),
|
RLimits: rlims.PrepareRLimit(),
|
||||||
Files: fds,
|
Files: fds,
|
||||||
WorkDir: workPath,
|
WorkDir: workPath,
|
||||||
SandboxProfile: "",
|
SandboxProfile: profile,
|
||||||
SyncFunc: func(pid int) error {
|
SyncFunc: func(pid int) error {
|
||||||
mTime = time.Now()
|
mTime = time.Now()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -9,7 +9,8 @@ import (
|
|||||||
//go:norace
|
//go:norace
|
||||||
func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, profile *byte, p [2]int) (r1 uintptr, err1 syscall.Errno) {
|
func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, profile *byte, p [2]int) (r1 uintptr, err1 syscall.Errno) {
|
||||||
var (
|
var (
|
||||||
err2 syscall.Errno
|
err2 syscall.Errno
|
||||||
|
errBuf *byte
|
||||||
)
|
)
|
||||||
|
|
||||||
// similar to exec_linux, avoid side effect by shuffling around
|
// similar to exec_linux, avoid side effect by shuffling around
|
||||||
@ -93,12 +94,25 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
|||||||
|
|
||||||
// Set limit
|
// Set limit
|
||||||
for _, rlim := range r.RLimits {
|
for _, rlim := range r.RLimits {
|
||||||
_, _, err1 := rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(rlim.Res), uintptr(unsafe.Pointer(&rlim.Rlim)), 0)
|
_, _, err1 = rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(rlim.Res), uintptr(unsafe.Pointer(&rlim.Rlim)), 0)
|
||||||
if err1 != 0 {
|
if err1 != 0 {
|
||||||
goto childerror
|
goto childerror
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load sandbox profile
|
||||||
|
if profile != nil {
|
||||||
|
r1, _, err1 = rawSyscall(funcPC(libc_sandbox_init_trampoline), uintptr(unsafe.Pointer(profile)), 0, uintptr(unsafe.Pointer(&errBuf)))
|
||||||
|
if err1 != 0 {
|
||||||
|
goto childerror
|
||||||
|
}
|
||||||
|
if r1 != 0 {
|
||||||
|
err1 = 253
|
||||||
|
goto childerror
|
||||||
|
}
|
||||||
|
rawSyscall(funcPC(libc_sandbox_free_error_trampoline), uintptr(unsafe.Pointer(errBuf)), 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// Sync before exec
|
// Sync before exec
|
||||||
err2 = 0
|
err2 = 0
|
||||||
r1, _, err1 = rawSyscall(funcPC(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
|
r1, _, err1 = rawSyscall(funcPC(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
|
||||||
|
|||||||
@ -3,8 +3,12 @@ package forkexec
|
|||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
_ "unsafe" // use go:linkname
|
_ "unsafe" // use go:linkname
|
||||||
|
|
||||||
|
"github.com/criyle/go-sandbox/pkg/darwin" // use sandbox_init
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ = darwin.SandboxInit
|
||||||
|
|
||||||
//go:linkname funcPC syscall.funcPC
|
//go:linkname funcPC syscall.funcPC
|
||||||
func funcPC(f func()) uintptr
|
func funcPC(f func()) uintptr
|
||||||
|
|
||||||
@ -47,5 +51,11 @@ func libc_execve_trampoline()
|
|||||||
//go:linkname libc_exit_trampoline syscall.libc_exit_trampoline
|
//go:linkname libc_exit_trampoline syscall.libc_exit_trampoline
|
||||||
func libc_exit_trampoline()
|
func libc_exit_trampoline()
|
||||||
|
|
||||||
|
//go:linkname libc_sandbox_init_trampoline github.com/criyle/go-sandbox/pkg/darwin.libc_sandbox_init_trampoline
|
||||||
|
func libc_sandbox_init_trampoline()
|
||||||
|
|
||||||
|
//go:linkname libc_sandbox_free_error_trampoline github.com/criyle/go-sandbox/pkg/darwin.libc_sandbox_free_error_trampoline
|
||||||
|
func libc_sandbox_free_error_trampoline()
|
||||||
|
|
||||||
//go:linkname fcntl syscall.fcntl
|
//go:linkname fcntl syscall.fcntl
|
||||||
func fcntl(fd int, cmd int, arg int) (val int, err error)
|
func fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user