mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-11-04 14:49:53 +08:00
parent
d32acd7591
commit
f8361a08a0
@ -224,14 +224,15 @@ func start() (*runner.Result, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syncFunc := func(pid int) error {
|
var syncFunc func(pid int) error
|
||||||
if cg != nil {
|
if cg != nil {
|
||||||
|
syncFunc = func(pid int) error {
|
||||||
if err := cg.AddProc(pid); err != nil {
|
if err := cg.AddProc(pid); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if memfile {
|
if memfile {
|
||||||
fin, err := os.Open(args[0])
|
fin, err := os.Open(args[0])
|
||||||
|
|||||||
@ -351,6 +351,7 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, host
|
|||||||
// Enable Ptrace & sync with parent (since ptrace_me is a blocking operation)
|
// Enable Ptrace & sync with parent (since ptrace_me is a blocking operation)
|
||||||
if r.Ptrace && r.Seccomp != nil {
|
if r.Ptrace && r.Seccomp != nil {
|
||||||
{
|
{
|
||||||
|
if r.SyncFunc != nil {
|
||||||
r1, _, err1 = syscall.RawSyscall(syscall.SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
r1, _, err1 = syscall.RawSyscall(syscall.SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
||||||
if r1 == 0 || err1 != 0 {
|
if r1 == 0 || err1 != 0 {
|
||||||
childExitError(pipe, LocSyncWrite, err1)
|
childExitError(pipe, LocSyncWrite, err1)
|
||||||
@ -360,6 +361,7 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, host
|
|||||||
if r1 == 0 || err1 != 0 {
|
if r1 == 0 || err1 != 0 {
|
||||||
childExitError(pipe, LocSyncRead, err1)
|
childExitError(pipe, LocSyncRead, err1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// unshare cgroup namespace
|
// unshare cgroup namespace
|
||||||
if r.UnshareCgroupAfterSync {
|
if r.UnshareCgroupAfterSync {
|
||||||
@ -414,6 +416,7 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, host
|
|||||||
// Before exec, sync with parent through pipe (configured as close_on_exec)
|
// Before exec, sync with parent through pipe (configured as close_on_exec)
|
||||||
if !r.Ptrace || r.Seccomp == nil {
|
if !r.Ptrace || r.Seccomp == nil {
|
||||||
{
|
{
|
||||||
|
if r.SyncFunc != nil {
|
||||||
r1, _, err1 = syscall.RawSyscall(syscall.SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
r1, _, err1 = syscall.RawSyscall(syscall.SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
||||||
if r1 == 0 || err1 != 0 {
|
if r1 == 0 || err1 != 0 {
|
||||||
childExitError(pipe, LocSyncWrite, err1)
|
childExitError(pipe, LocSyncWrite, err1)
|
||||||
@ -423,6 +426,7 @@ func forkAndExecInChild(r *Runner, argv0 *byte, argv, env []*byte, workdir, host
|
|||||||
if r1 == 0 || err1 != 0 {
|
if r1 == 0 || err1 != 0 {
|
||||||
childExitError(pipe, LocSyncRead, err1)
|
childExitError(pipe, LocSyncRead, err1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// unshare cgroup namespace
|
// unshare cgroup namespace
|
||||||
if r.UnshareCgroupAfterSync {
|
if r.UnshareCgroupAfterSync {
|
||||||
|
|||||||
@ -65,6 +65,7 @@ func syncWithChild(r *Runner, p [2]int, pid int, err1 syscall.Errno) (int, error
|
|||||||
err error
|
err error
|
||||||
unshareUser = r.CloneFlags&unix.CLONE_NEWUSER == unix.CLONE_NEWUSER
|
unshareUser = r.CloneFlags&unix.CLONE_NEWUSER == unix.CLONE_NEWUSER
|
||||||
childErr ChildError
|
childErr ChildError
|
||||||
|
n int
|
||||||
)
|
)
|
||||||
|
|
||||||
// sync with child
|
// sync with child
|
||||||
@ -86,24 +87,24 @@ func syncWithChild(r *Runner, p [2]int, pid int, err1 syscall.Errno) (int, error
|
|||||||
syscall.RawSyscall(syscall.SYS_WRITE, uintptr(p[0]), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
syscall.RawSyscall(syscall.SYS_WRITE, uintptr(p[0]), uintptr(unsafe.Pointer(&err2)), uintptr(unsafe.Sizeof(err2)))
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err := readChildErr(p[0], &childErr)
|
// if syncfunc return error, then fail child immediately
|
||||||
|
// only sync if there is a syncFunc
|
||||||
|
if r.SyncFunc != nil {
|
||||||
|
n, err = readChildErr(p[0], &childErr)
|
||||||
// child returned error code
|
// child returned error code
|
||||||
if (n != int(unsafe.Sizeof(err2)) && n != int(unsafe.Sizeof(childErr))) || childErr.Err != 0 || err != nil {
|
if (n != int(unsafe.Sizeof(err2)) && n != int(unsafe.Sizeof(childErr))) || childErr.Err != 0 || err != nil {
|
||||||
childErr.Err = handlePipeError(n, childErr.Err)
|
childErr.Err = handlePipeError(n, childErr.Err)
|
||||||
goto fail
|
goto fail
|
||||||
}
|
}
|
||||||
|
|
||||||
// if syncfunc return error, then fail child immediately
|
|
||||||
if r.SyncFunc != nil {
|
|
||||||
if err = r.SyncFunc(int(pid)); err != nil {
|
if err = r.SyncFunc(int(pid)); err != nil {
|
||||||
goto fail
|
goto fail
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// otherwise, ack child (err1 == 0)
|
// otherwise, ack child (err1 == 0)
|
||||||
syscall.RawSyscall(syscall.SYS_WRITE, uintptr(p[0]), uintptr(unsafe.Pointer(&err1)), uintptr(unsafe.Sizeof(err1)))
|
syscall.RawSyscall(syscall.SYS_WRITE, uintptr(p[0]), uintptr(unsafe.Pointer(&err1)), uintptr(unsafe.Sizeof(err1)))
|
||||||
|
}
|
||||||
|
|
||||||
// if stopped before execve by signal SIGSTOP or PTRACE_ME, then do not wait until execve
|
// if stopped before execve by signal SIGSTOP or PTRACE_ME, then do not wait until execve
|
||||||
if r.Ptrace || r.StopBeforeSeccomp {
|
if r.StopBeforeSeccomp || (r.Seccomp != nil && r.Ptrace) {
|
||||||
// let's wait it in another goroutine to avoid SIGPIPE
|
// let's wait it in another goroutine to avoid SIGPIPE
|
||||||
go func() {
|
go func() {
|
||||||
readChildErr(p[0], &childErr)
|
readChildErr(p[0], &childErr)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user