diff --git a/.gitignore b/.gitignore index da0921b..900a322 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ env*.sh # Test Files /runprog /test + +.vscode diff --git a/cmd/runprog/main_darwin.go b/cmd/runprog/main_darwin.go index 821ebd8..3f5476b 100644 --- a/cmd/runprog/main_darwin.go +++ b/cmd/runprog/main_darwin.go @@ -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() diff --git a/container/consts.go b/container/consts_linux.go similarity index 100% rename from container/consts.go rename to container/consts_linux.go diff --git a/pkg/cgroup/benchmark_test.go b/pkg/cgroup/benchmark_linux_test.go similarity index 100% rename from pkg/cgroup/benchmark_test.go rename to pkg/cgroup/benchmark_linux_test.go diff --git a/pkg/cgroup/builder.go b/pkg/cgroup/builder_linux.go similarity index 100% rename from pkg/cgroup/builder.go rename to pkg/cgroup/builder_linux.go diff --git a/pkg/cgroup/cgroup_info.go b/pkg/cgroup/cgroup_info_linux.go similarity index 100% rename from pkg/cgroup/cgroup_info.go rename to pkg/cgroup/cgroup_info_linux.go diff --git a/pkg/cgroup/cgroup.go b/pkg/cgroup/cgroup_linux.go similarity index 100% rename from pkg/cgroup/cgroup.go rename to pkg/cgroup/cgroup_linux.go diff --git a/pkg/cgroup/consts.go b/pkg/cgroup/consts_linux.go similarity index 100% rename from pkg/cgroup/consts.go rename to pkg/cgroup/consts_linux.go diff --git a/pkg/cgroup/utils.go b/pkg/cgroup/utils_linux.go similarity index 100% rename from pkg/cgroup/utils.go rename to pkg/cgroup/utils_linux.go diff --git a/pkg/cgroup/v1.go b/pkg/cgroup/v1_linux.go similarity index 100% rename from pkg/cgroup/v1.go rename to pkg/cgroup/v1_linux.go diff --git a/pkg/cgroup/v1controller.go b/pkg/cgroup/v1controller_linux.go similarity index 100% rename from pkg/cgroup/v1controller.go rename to pkg/cgroup/v1controller_linux.go diff --git a/pkg/cgroup/v2.go b/pkg/cgroup/v2_linux.go similarity index 100% rename from pkg/cgroup/v2.go rename to pkg/cgroup/v2_linux.go diff --git a/pkg/forkexec/fork_child_darwin.go b/pkg/forkexec/fork_child_darwin.go index cb6b27e..b33da4f 100644 --- a/pkg/forkexec/fork_child_darwin.go +++ b/pkg/forkexec/fork_child_darwin.go @@ -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) } } diff --git a/pkg/forkexec/fork_darwin.go b/pkg/forkexec/fork_darwin.go index 4c89947..49257ad 100644 --- a/pkg/forkexec/fork_darwin.go +++ b/pkg/forkexec/fork_darwin.go @@ -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) } diff --git a/pkg/forkexec/syscall_darwin.go b/pkg/forkexec/syscall_darwin.go index 1b97cb9..d56a751 100644 --- a/pkg/forkexec/syscall_darwin.go +++ b/pkg/forkexec/syscall_darwin.go @@ -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) diff --git a/pkg/forkexec/zsyscall_darwin.go b/pkg/forkexec/zsyscall_darwin.go index 243e0c4..5fb9770 100644 --- a/pkg/forkexec/zsyscall_darwin.go +++ b/pkg/forkexec/zsyscall_darwin.go @@ -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" diff --git a/pkg/forkexec/zsyscall_darwin.s b/pkg/forkexec/zsyscall_darwin.s index 6a81d4d..a0ceb06 100644 --- a/pkg/forkexec/zsyscall_darwin.s +++ b/pkg/forkexec/zsyscall_darwin.s @@ -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) diff --git a/pkg/unixsocket/benchmark_test.go b/pkg/unixsocket/benchmark_linux_test.go similarity index 100% rename from pkg/unixsocket/benchmark_test.go rename to pkg/unixsocket/benchmark_linux_test.go diff --git a/pkg/unixsocket/socket_test.go b/pkg/unixsocket/socket_linux_test.go similarity index 100% rename from pkg/unixsocket/socket_test.go rename to pkg/unixsocket/socket_linux_test.go