mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-11-04 14:49:53 +08:00
apply go11 module & code clean up
This commit is contained in:
parent
bae40d66b1
commit
0c79e83a9f
43
README.md
43
README.md
@ -6,47 +6,48 @@ Goal is to reimplement [uoj-judger/run_program](https://github.com/vfleaking/uoj
|
|||||||
|
|
||||||
Install:
|
Install:
|
||||||
|
|
||||||
+ install go compiler: `apt install golang-go`
|
- install go compiler: `apt install golang-go`
|
||||||
+ install libseccomp-dev: `apt install libseccomp-dev`
|
- install libseccomp-dev: `apt install libseccomp-dev`
|
||||||
+ install: `go install github.com/criyle/go-judger/...`
|
- install: `go install github.com/criyle/go-judger/...`
|
||||||
|
|
||||||
Features (same as uoj-judger/run_program):
|
Features (same as uoj-judger/run_program):
|
||||||
|
|
||||||
1. Restricted computing resource: Time & Memory (Stack) & Output
|
1. Restricted computing resource: Time & Memory (Stack) & Output
|
||||||
1. Restricted syscall access (by libseccomp & ptrace)
|
2. Restricted syscall access (by libseccomp & ptrace)
|
||||||
1. Restricted file access (read & write & access & exec)
|
3. Restricted file access (read & write & access & exec)
|
||||||
|
|
||||||
New Features:
|
New Features:
|
||||||
|
|
||||||
1. Percise resource limits (s -> ms, mb -> kb)
|
1. Percise resource limits (s -> ms, mb -> kb)
|
||||||
1. More architectures (arm32, arm64, x86)
|
2. More architectures (arm32, arm64, x86)
|
||||||
1. Allow multiple traced programs in different threads
|
3. Allow multiple traced programs in different threads
|
||||||
1. Allow pipes as input / output files
|
4. Allow pipes as input / output files
|
||||||
|
|
||||||
Default file access action:
|
Default file access action:
|
||||||
|
|
||||||
+ check file read / write: `open`, `openat`
|
- check file read / write: `open`, `openat`
|
||||||
+ check file read: `readlink`, `readlinkat`
|
- check file read: `readlink`, `readlinkat`
|
||||||
+ check file write: `unlink`, `unlinkat`, `chmod`, `rename`
|
- check file write: `unlink`, `unlinkat`, `chmod`, `rename`
|
||||||
+ check file access: `stat`, `lstat`, `access`, `faccessat`
|
- check file access: `stat`, `lstat`, `access`, `faccessat`
|
||||||
+ check file exec: `execve`
|
- check file exec: `execve`
|
||||||
|
|
||||||
Packages:
|
Packages:
|
||||||
|
|
||||||
+ secutil: provides common utility function that wrappers libseccomp
|
- seccomp: provides utility function that wrappers libseccomp
|
||||||
+ tracee: ptraced fork-exec with seccomp loaded
|
- forkexec: fork-exec provides ptrace and seccomp before exec
|
||||||
+ tracer: ptrace tracee and provides syscall trap context
|
- tracer: ptrace tracer and provides syscall trap filter context
|
||||||
+ runprogram: wrapper to call trecee and trecer
|
- runprogram: wrapper to call forkexec and trecer
|
||||||
+ runconfig: defines arch & language specified trace condition
|
- runconfig: defines arch & language specified trace condition
|
||||||
|
|
||||||
Executable:
|
Executable:
|
||||||
|
|
||||||
+ run_program: under construction
|
- run_program: under construction
|
||||||
|
|
||||||
Configuations:
|
Configuations:
|
||||||
|
|
||||||
+ run_program/config.go: all configs toward running specs
|
- run_program/config.go: all configs toward running specs
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
1. Use Linux Namespace to isolate file access (elimilate ptrace)
|
1. Use Linux Namespace to isolate file access (elimilate ptrace)
|
||||||
1. Use Linux Control Groups to limit & acct CPU & memory (elimilate wait4 rusage)
|
2. Use Linux Control Groups to limit & acct CPU & memory (elimilate wait4 rusage)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package tracee
|
package forkexec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -1,6 +1,6 @@
|
|||||||
// Package tracee provides interface to run a seccomp filtered, rlimited
|
// Package forkexec provides interface to run a seccomp filtered, rlimited
|
||||||
// executable and ptraced
|
// executable and ptraced
|
||||||
package tracee
|
package forkexec
|
||||||
|
|
||||||
import "syscall"
|
import "syscall"
|
||||||
|
|
||||||
@ -31,8 +31,3 @@ type RLimit struct {
|
|||||||
// Rlim is the limit applied to that resource
|
// Rlim is the limit applied to that resource
|
||||||
Rlim syscall.Rlimit
|
Rlim syscall.Rlimit
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRunner creates new runner struct
|
|
||||||
func NewRunner() Runner {
|
|
||||||
return Runner{}
|
|
||||||
}
|
|
||||||
8
go.mod
Normal file
8
go.mod
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module github.com/criyle/go-judger
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/seccomp/libseccomp-golang v0.9.1
|
||||||
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb
|
||||||
|
)
|
||||||
3
go.sum
Normal file
3
go.sum
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||||
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
|
||||||
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -3,7 +3,7 @@ package runprogram
|
|||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/criyle/go-judger/tracee"
|
"github.com/criyle/go-judger/forkexec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RLimits defines the rlimit applied by setrlimit syscall to traced process
|
// RLimits defines the rlimit applied by setrlimit syscall to traced process
|
||||||
@ -22,39 +22,39 @@ func getRlimit(cur, max uint64) syscall.Rlimit {
|
|||||||
|
|
||||||
// prepareRLimit creates rlimit structures for tracee
|
// prepareRLimit creates rlimit structures for tracee
|
||||||
// TimeLimit in s, SizeLimit in byte
|
// TimeLimit in s, SizeLimit in byte
|
||||||
func (r *RLimits) prepareRLimit() []tracee.RLimit {
|
func (r *RLimits) prepareRLimit() []forkexec.RLimit {
|
||||||
var ret []tracee.RLimit
|
var ret []forkexec.RLimit
|
||||||
if r.CPU > 0 {
|
if r.CPU > 0 {
|
||||||
cpuHard := r.CPUHard
|
cpuHard := r.CPUHard
|
||||||
if cpuHard < r.CPU {
|
if cpuHard < r.CPU {
|
||||||
cpuHard = r.CPU
|
cpuHard = r.CPU
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, tracee.RLimit{
|
ret = append(ret, forkexec.RLimit{
|
||||||
Res: syscall.RLIMIT_CPU,
|
Res: syscall.RLIMIT_CPU,
|
||||||
Rlim: getRlimit(uint64(r.CPU), uint64(cpuHard)),
|
Rlim: getRlimit(uint64(r.CPU), uint64(cpuHard)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if r.Data > 0 {
|
if r.Data > 0 {
|
||||||
ret = append(ret, tracee.RLimit{
|
ret = append(ret, forkexec.RLimit{
|
||||||
Res: syscall.RLIMIT_DATA,
|
Res: syscall.RLIMIT_DATA,
|
||||||
Rlim: getRlimit(uint64(r.Data)<<10, uint64(r.Data)<<10),
|
Rlim: getRlimit(uint64(r.Data)<<10, uint64(r.Data)<<10),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if r.FileSize > 0 {
|
if r.FileSize > 0 {
|
||||||
ret = append(ret, tracee.RLimit{
|
ret = append(ret, forkexec.RLimit{
|
||||||
Res: syscall.RLIMIT_FSIZE,
|
Res: syscall.RLIMIT_FSIZE,
|
||||||
Rlim: getRlimit(uint64(r.FileSize)<<10, uint64(r.FileSize)<<10),
|
Rlim: getRlimit(uint64(r.FileSize)<<10, uint64(r.FileSize)<<10),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if r.Stack > 0 {
|
if r.Stack > 0 {
|
||||||
ret = append(ret, tracee.RLimit{
|
ret = append(ret, forkexec.RLimit{
|
||||||
Res: syscall.RLIMIT_STACK,
|
Res: syscall.RLIMIT_STACK,
|
||||||
Rlim: getRlimit(uint64(r.Stack)<<10, uint64(r.Stack)<<10),
|
Rlim: getRlimit(uint64(r.Stack)<<10, uint64(r.Stack)<<10),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if r.AddressSpace > 0 {
|
if r.AddressSpace > 0 {
|
||||||
ret = append(ret, tracee.RLimit{
|
ret = append(ret, forkexec.RLimit{
|
||||||
Res: syscall.RLIMIT_AS,
|
Res: syscall.RLIMIT_AS,
|
||||||
Rlim: getRlimit(uint64(r.AddressSpace)<<10, uint64(r.AddressSpace)<<10),
|
Rlim: getRlimit(uint64(r.AddressSpace)<<10, uint64(r.AddressSpace)<<10),
|
||||||
})
|
})
|
||||||
|
|||||||
@ -3,8 +3,8 @@ package runprogram
|
|||||||
import (
|
import (
|
||||||
libseccomp "github.com/seccomp/libseccomp-golang"
|
libseccomp "github.com/seccomp/libseccomp-golang"
|
||||||
|
|
||||||
"github.com/criyle/go-judger/secutil"
|
"github.com/criyle/go-judger/forkexec"
|
||||||
"github.com/criyle/go-judger/tracee"
|
"github.com/criyle/go-judger/seccomp"
|
||||||
"github.com/criyle/go-judger/tracer"
|
"github.com/criyle/go-judger/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,13 +18,13 @@ func (r *RunProgram) Start() (rt tracer.TraceResult, err error) {
|
|||||||
}
|
}
|
||||||
defer filter.Release()
|
defer filter.Release()
|
||||||
|
|
||||||
bpf, err := secutil.FilterToBPF(filter)
|
bpf, err := seccomp.FilterToBPF(filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
println(err)
|
println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ch := &tracee.Runner{
|
ch := &forkexec.Runner{
|
||||||
Args: r.Args,
|
Args: r.Args,
|
||||||
Env: r.Env,
|
Env: r.Env,
|
||||||
RLimits: r.RLimits.prepareRLimit(),
|
RLimits: r.RLimits.prepareRLimit(),
|
||||||
@ -51,5 +51,5 @@ func buildFilter(showDetails bool, allow, trace []string) (*libseccomp.ScmpFilte
|
|||||||
} else {
|
} else {
|
||||||
defaultAction = libseccomp.ActKill
|
defaultAction = libseccomp.ActKill
|
||||||
}
|
}
|
||||||
return secutil.BuildFilter(defaultAction, libseccomp.ActTrace.SetReturnCode(tracer.MsgHandle), allow, trace)
|
return seccomp.BuildFilter(defaultAction, libseccomp.ActTrace.SetReturnCode(tracer.MsgHandle), allow, trace)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Package secutil provides utility functions to manipulate seccomp filters
|
// Package seccomp provides utility functions to manipulate seccomp filters
|
||||||
// provided by libseccomp
|
// provided by libseccomp
|
||||||
package secutil
|
package seccomp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package secutil
|
package seccomp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
Loading…
Reference in New Issue
Block a user