mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-09-26 23:19:11 +08:00
*: fix macOS build for go1.18
This commit is contained in:
parent
8fc50bc5b7
commit
ca60fcad98
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,3 +8,5 @@ env*.sh
|
||||
# Test Files
|
||||
/runprog
|
||||
/test
|
||||
|
||||
.vscode
|
||||
|
@ -74,6 +74,9 @@ func main() {
|
||||
|
||||
rt, err := start()
|
||||
debug(rt, err)
|
||||
if e, ok := err.(syscall.Errno); ok {
|
||||
debug("errno", int(e))
|
||||
}
|
||||
|
||||
if rt == nil {
|
||||
rt = &runner.Result{
|
||||
@ -194,8 +197,8 @@ func start() (*runner.Result, error) {
|
||||
case wstatus.Exited():
|
||||
if status := wstatus.ExitStatus(); status != 0 {
|
||||
result.Status = runner.StatusNonzeroExitStatus
|
||||
return &result, nil
|
||||
}
|
||||
return &result, nil
|
||||
|
||||
case wstatus.Signaled():
|
||||
sig := wstatus.Signal()
|
||||
|
@ -22,7 +22,7 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
||||
beforeFork()
|
||||
|
||||
// UnshareFlags (new namespaces) is activated by clone syscall
|
||||
r1, _, err1 = rawSyscall(funcPC(libc_fork_trampoline), 0, 0, 0)
|
||||
r1, _, err1 = rawSyscall(libc_fork_trampoline_addr, 0, 0, 0)
|
||||
if err1 != 0 || r1 != 0 {
|
||||
// in parent process, immediate return
|
||||
return
|
||||
@ -33,12 +33,12 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
||||
// Notice: cannot call any GO functions beyond this point
|
||||
|
||||
// Close write end of pipe
|
||||
if _, _, err1 = rawSyscall(funcPC(libc_close_trampoline), uintptr(p[0]), 0, 0); err1 != 0 {
|
||||
if _, _, err1 = rawSyscall(libc_close_trampoline_addr, uintptr(p[0]), 0, 0); err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
|
||||
// Set pg id
|
||||
_, _, err1 = rawSyscall(funcPC(libc_setpgid_trampoline), 0, 0, 0)
|
||||
_, _, err1 = rawSyscall(libc_setpgid_trampoline_addr, 0, 0, 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
@ -46,11 +46,11 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
||||
// Pass 1 & pass 2 assigns fds for child process
|
||||
// Pass 1: fd[i] < i => nextfd
|
||||
if pipe < nextfd {
|
||||
_, _, err1 = rawSyscall(funcPC(libc_dup2_trampoline), uintptr(pipe), uintptr(nextfd), 0)
|
||||
_, _, err1 = rawSyscall(libc_dup2_trampoline_addr, uintptr(pipe), uintptr(nextfd), 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
rawSyscall(funcPC(libc_fcntl_trampoline), uintptr(nextfd), syscall.F_SETFD, syscall.FD_CLOEXEC)
|
||||
rawSyscall(libc_fcntl_trampoline_addr, uintptr(nextfd), syscall.F_SETFD, syscall.FD_CLOEXEC)
|
||||
pipe = nextfd
|
||||
nextfd++
|
||||
}
|
||||
@ -60,11 +60,11 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
||||
if nextfd == pipe {
|
||||
nextfd++
|
||||
}
|
||||
_, _, err1 = rawSyscall(funcPC(libc_dup2_trampoline), uintptr(fd[i]), uintptr(nextfd), 0)
|
||||
_, _, err1 = rawSyscall(libc_dup2_trampoline_addr, uintptr(fd[i]), uintptr(nextfd), 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
rawSyscall(funcPC(libc_fcntl_trampoline), uintptr(nextfd), syscall.F_SETFD, syscall.FD_CLOEXEC)
|
||||
rawSyscall(libc_fcntl_trampoline_addr, uintptr(nextfd), syscall.F_SETFD, syscall.FD_CLOEXEC)
|
||||
// Set up close on exec
|
||||
fd[i] = nextfd
|
||||
nextfd++
|
||||
@ -73,18 +73,18 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
||||
// Pass 2: fd[i] => i
|
||||
for i := 0; i < len(fd); i++ {
|
||||
if fd[i] == -1 {
|
||||
rawSyscall(funcPC(libc_close_trampoline), uintptr(i), 0, 0)
|
||||
rawSyscall(libc_close_trampoline_addr, uintptr(i), 0, 0)
|
||||
continue
|
||||
}
|
||||
if fd[i] == int(i) {
|
||||
// dup2(i, i) will not clear close on exec flag, need to reset the flag
|
||||
_, _, err1 = rawSyscall(funcPC(libc_fcntl_trampoline), uintptr(fd[i]), syscall.F_SETFD, 0)
|
||||
_, _, err1 = rawSyscall(libc_fcntl_trampoline_addr, uintptr(fd[i]), syscall.F_SETFD, 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
continue
|
||||
}
|
||||
_, _, err1 = rawSyscall(funcPC(libc_dup2_trampoline), uintptr(fd[i]), uintptr(i), 0)
|
||||
_, _, err1 = rawSyscall(libc_dup2_trampoline_addr, uintptr(fd[i]), uintptr(i), 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
@ -92,7 +92,7 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
||||
|
||||
// chdir for child
|
||||
if workdir != nil {
|
||||
_, _, err1 = rawSyscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(workdir)), 0, 0)
|
||||
_, _, err1 = rawSyscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(workdir)), 0, 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
@ -100,15 +100,18 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
||||
|
||||
// Set limit
|
||||
for _, rlim := range r.RLimits {
|
||||
_, _, err1 = rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(rlim.Res), uintptr(unsafe.Pointer(&rlim.Rlim)), 0)
|
||||
_, _, err1 = rawSyscall(libc_setrlimit_trampoline_addr, uintptr(rlim.Res), uintptr(unsafe.Pointer(&rlim.Rlim)), 0)
|
||||
if err1 != 0 {
|
||||
if err1 == syscall.EINVAL && (rlim.Res == syscall.RLIMIT_DATA || rlim.Res == syscall.RLIMIT_AS) {
|
||||
continue
|
||||
}
|
||||
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)))
|
||||
r1, _, err1 = rawSyscall(libc_sandbox_init_trampoline_addr, uintptr(unsafe.Pointer(profile)), 0, uintptr(unsafe.Pointer(&errBuf)))
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
@ -116,31 +119,31 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, prof
|
||||
err1 = 253
|
||||
goto childerror
|
||||
}
|
||||
rawSyscall(funcPC(libc_sandbox_free_error_trampoline), uintptr(unsafe.Pointer(errBuf)), 0, 0)
|
||||
rawSyscall(libc_sandbox_free_error_trampoline_addr, uintptr(unsafe.Pointer(errBuf)), 0, 0)
|
||||
}
|
||||
|
||||
// Sync before exec
|
||||
err2 = 0
|
||||
r1, _, err1 = rawSyscall(funcPC(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
|
||||
r1, _, err1 = rawSyscall(libc_write_trampoline_addr, uintptr(pipe), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
|
||||
if r1 == 0 || err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
|
||||
r1, _, err1 = rawSyscall(funcPC(libc_read_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
|
||||
r1, _, err1 = rawSyscall(libc_read_trampoline_addr, uintptr(pipe), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
|
||||
if r1 == 0 || err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
|
||||
// Time to exec.
|
||||
_, _, err1 = rawSyscall(funcPC(libc_execve_trampoline),
|
||||
_, _, err1 = rawSyscall(libc_execve_trampoline_addr,
|
||||
uintptr(unsafe.Pointer(argv0)),
|
||||
uintptr(unsafe.Pointer(&argv[0])),
|
||||
uintptr(unsafe.Pointer(&env[0])))
|
||||
|
||||
childerror:
|
||||
// send error code on pipe
|
||||
rawSyscall(funcPC(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
|
||||
rawSyscall(libc_write_trampoline_addr, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
|
||||
for {
|
||||
rawSyscall(funcPC(libc_exit_trampoline), uintptr(err1+err2), 0, 0)
|
||||
rawSyscall(libc_exit_trampoline_addr, uintptr(err1+err2), 0, 0)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package forkexec
|
||||
|
||||
import (
|
||||
"log"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
@ -84,7 +83,7 @@ func syncWithChild(r *Runner, p [2]int, pid int, err1 syscall.Errno) (int, error
|
||||
unix.Close(p[0])
|
||||
return 0, syscall.Errno(err1)
|
||||
}
|
||||
r1, _, err1 = syscall3(funcPC(libc_read_trampoline), uintptr(p[0]), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
||||
r1, _, err1 = syscall3(libc_read_trampoline_addr, uintptr(p[0]), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
||||
// child returned error code
|
||||
if r1 != unsafe.Sizeof(err2) || err2 != 0 || err1 != 0 {
|
||||
err = handlePipeError(r1, err2)
|
||||
@ -98,13 +97,13 @@ func syncWithChild(r *Runner, p [2]int, pid int, err1 syscall.Errno) (int, error
|
||||
}
|
||||
}
|
||||
// otherwise, ack child (err1 == 0)
|
||||
r1, _, err1 = syscall3(funcPC(libc_write_trampoline), uintptr(p[0]), uintptr(unsafe.Pointer(&err1)), uintptr(unsafe.Sizeof(err1)))
|
||||
r1, _, err1 = syscall3(libc_write_trampoline_addr, uintptr(p[0]), uintptr(unsafe.Pointer(&err1)), uintptr(unsafe.Sizeof(err1)))
|
||||
if err1 != 0 {
|
||||
goto fail
|
||||
}
|
||||
|
||||
// if read anything mean child failed after sync (close_on_exec so it should not block)
|
||||
r1, _, err1 = syscall3(funcPC(libc_read_trampoline), uintptr(p[0]), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
||||
r1, _, err1 = syscall3(libc_read_trampoline_addr, uintptr(p[0]), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
||||
unix.Close(p[0])
|
||||
if r1 != 0 || err1 != 0 {
|
||||
err = handlePipeError(r1, err2)
|
||||
@ -122,7 +121,6 @@ failAfterClose:
|
||||
|
||||
// check pipe error
|
||||
func handlePipeError(r1 uintptr, errno syscall.Errno) error {
|
||||
log.Println(r1, errno, int(errno))
|
||||
if r1 == unsafe.Sizeof(errno) {
|
||||
return syscall.Errno(errno)
|
||||
}
|
||||
|
@ -5,9 +5,6 @@ import (
|
||||
_ "unsafe" // use go:linkname
|
||||
)
|
||||
|
||||
//go:linkname funcPC syscall.funcPC
|
||||
func funcPC(f func()) uintptr
|
||||
|
||||
//go:linkname syscall3 syscall.syscall
|
||||
func syscall3(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
@ -17,38 +14,27 @@ func rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
//go:linkname rawSyscall6 syscall.rawSyscall6
|
||||
func rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
//go:linkname libc_fork_trampoline syscall.libc_fork_trampoline
|
||||
func libc_fork_trampoline()
|
||||
var libc_fork_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_close_trampoline syscall.libc_close_trampoline
|
||||
func libc_close_trampoline()
|
||||
var libc_close_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_read_trampoline syscall.libc_read_trampoline
|
||||
func libc_read_trampoline()
|
||||
var libc_read_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_write_trampoline syscall.libc_write_trampoline
|
||||
func libc_write_trampoline()
|
||||
var libc_write_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_fcntl_trampoline syscall.libc_fcntl_trampoline
|
||||
func libc_fcntl_trampoline()
|
||||
var libc_fcntl_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_dup2_trampoline syscall.libc_dup2_trampoline
|
||||
func libc_dup2_trampoline()
|
||||
var libc_dup2_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_chdir_trampoline syscall.libc_chdir_trampoline
|
||||
func libc_chdir_trampoline()
|
||||
var libc_chdir_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_setrlimit_trampoline syscall.libc_setrlimit_trampoline
|
||||
func libc_setrlimit_trampoline()
|
||||
var libc_setrlimit_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_execve_trampoline syscall.libc_execve_trampoline
|
||||
func libc_execve_trampoline()
|
||||
var libc_execve_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_exit_trampoline syscall.libc_exit_trampoline
|
||||
func libc_exit_trampoline()
|
||||
var libc_exit_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_setpgid_trampoline syscall.libc_setpgid_trampoline
|
||||
func libc_setpgid_trampoline()
|
||||
var libc_setpgid_trampoline_addr uintptr
|
||||
|
||||
//go:linkname fcntl syscall.fcntl
|
||||
func fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
// SandboxInit calls sandbox_init
|
||||
func SandboxInit(profile *byte, flags uint64, errorBuf **byte) (err error) {
|
||||
var r1 uintptr
|
||||
r1, _, err = syscall3(funcPC(libc_sandbox_init_trampoline), uintptr(unsafe.Pointer(profile)), uintptr(flags), uintptr(unsafe.Pointer(errorBuf)))
|
||||
r1, _, err = syscall3(libc_sandbox_init_trampoline_addr, uintptr(unsafe.Pointer(profile)), uintptr(flags), uintptr(unsafe.Pointer(errorBuf)))
|
||||
if r1 != 0 {
|
||||
err = syscall.EINVAL
|
||||
} else {
|
||||
@ -19,15 +19,13 @@ func SandboxInit(profile *byte, flags uint64, errorBuf **byte) (err error) {
|
||||
|
||||
// SandboxFreeError calls sandbox_free_error
|
||||
func SandboxFreeError(errorBuf *byte) {
|
||||
syscall3(funcPC(libc_sandbox_free_error_trampoline), uintptr(unsafe.Pointer(errorBuf)), 0, 0)
|
||||
syscall3(libc_sandbox_free_error_trampoline_addr, uintptr(unsafe.Pointer(errorBuf)), 0, 0)
|
||||
}
|
||||
|
||||
func libc_sandbox_init_trampoline()
|
||||
var libc_sandbox_init_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_sandbox_init libc_sandbox_init
|
||||
//go:cgo_import_dynamic libc_sandbox_init sandbox_init "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
func libc_sandbox_free_error_trampoline()
|
||||
var libc_sandbox_free_error_trampoline_addr uintptr
|
||||
|
||||
//go:linkname libc_sandbox_free_error libc_sandbox_free_error
|
||||
//go:cgo_import_dynamic libc_sandbox_free_error sandbox_free_error "/usr/lib/libSystem.B.dylib"
|
||||
|
@ -1,6 +1,79 @@
|
||||
#include "textflag.h"
|
||||
TEXT ·libc_sandbox_init_trampoline(SB),NOSPLIT,$0-0
|
||||
|
||||
TEXT libc_sandbox_init_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sandbox_init(SB)
|
||||
|
||||
TEXT ·libc_sandbox_free_error_trampoline(SB),NOSPLIT,$0-0
|
||||
GLOBL ·libc_sandbox_init_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_sandbox_init_trampoline_addr(SB)/8, $libc_sandbox_init_trampoline<>(SB)
|
||||
|
||||
TEXT libc_sandbox_free_error_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sandbox_free_error(SB)
|
||||
|
||||
GLOBL ·libc_sandbox_free_error_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_sandbox_free_error_trampoline_addr(SB)/8, $libc_sandbox_free_error_trampoline<>(SB)
|
||||
|
||||
TEXT libc_fork_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_fork(SB)
|
||||
|
||||
GLOBL ·libc_fork_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_fork_trampoline_addr(SB)/8, $libc_fork_trampoline<>(SB)
|
||||
|
||||
TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_close(SB)
|
||||
|
||||
GLOBL ·libc_close_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB)
|
||||
|
||||
TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_read(SB)
|
||||
|
||||
GLOBL ·libc_read_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB)
|
||||
|
||||
TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_write(SB)
|
||||
|
||||
GLOBL ·libc_write_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB)
|
||||
|
||||
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_fcntl(SB)
|
||||
|
||||
GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
|
||||
|
||||
TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_dup2(SB)
|
||||
|
||||
GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB)
|
||||
|
||||
TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_chdir(SB)
|
||||
|
||||
GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB)
|
||||
|
||||
TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_setrlimit(SB)
|
||||
|
||||
GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB)
|
||||
|
||||
TEXT libc_execve_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_execve(SB)
|
||||
|
||||
GLOBL ·libc_execve_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_execve_trampoline_addr(SB)/8, $libc_execve_trampoline<>(SB)
|
||||
|
||||
TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_exit(SB)
|
||||
|
||||
GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB)
|
||||
|
||||
TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_setpgid(SB)
|
||||
|
||||
GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB)
|
||||
|
Loading…
Reference in New Issue
Block a user