mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-11-04 14:49:53 +08:00
add support for arm32
This commit is contained in:
parent
79d33bd16d
commit
4828363e1d
223
run_program/config_arm.go
Normal file
223
run_program/config_arm.go
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// This file includes configs for the run program settings
|
||||||
|
|
||||||
|
var (
|
||||||
|
// default read permission files
|
||||||
|
defaultReadableFiles = []string{
|
||||||
|
"/etc/ld.so.nohwcap",
|
||||||
|
"/etc/ld.so.preload",
|
||||||
|
"/etc/ld.so.cache",
|
||||||
|
"/lib/arm-linux-gnueabihf/", // 32-bit
|
||||||
|
"/usr/lib/arm-linux-gnueabihf/", // 32-bit
|
||||||
|
"/usr/lib/locale/locale-archive",
|
||||||
|
"/proc/self/exe",
|
||||||
|
"/etc/timezone",
|
||||||
|
"/usr/share/zoneinfo/",
|
||||||
|
"/dev/random",
|
||||||
|
"/dev/urandom",
|
||||||
|
"/proc/meminfo",
|
||||||
|
"/etc/localtime",
|
||||||
|
}
|
||||||
|
|
||||||
|
// default write permission files
|
||||||
|
defaultWritableFiles = []string{"/dev/null"}
|
||||||
|
|
||||||
|
// default allowed safe syscalls
|
||||||
|
defaultSyscallAllows = []string{
|
||||||
|
// file access through fd
|
||||||
|
"read",
|
||||||
|
"write",
|
||||||
|
"readv",
|
||||||
|
"writev",
|
||||||
|
"close",
|
||||||
|
"fstat",
|
||||||
|
"fstat64", // 32-bit
|
||||||
|
"lseek",
|
||||||
|
"_llseek", // 32-bit
|
||||||
|
"dup",
|
||||||
|
"dup2",
|
||||||
|
"dup3",
|
||||||
|
"ioctl",
|
||||||
|
"fcntl",
|
||||||
|
"fcntl64", // 32-bit
|
||||||
|
|
||||||
|
// memory action
|
||||||
|
"mmap",
|
||||||
|
"mmap2", // 32-bit
|
||||||
|
"mprotect",
|
||||||
|
"munmap",
|
||||||
|
"brk",
|
||||||
|
"mremap",
|
||||||
|
"msync",
|
||||||
|
"mincore",
|
||||||
|
"madvise",
|
||||||
|
|
||||||
|
// signal action
|
||||||
|
"rt_sigaction",
|
||||||
|
"rt_sigprocmask",
|
||||||
|
"rt_sigreturn",
|
||||||
|
"rt_sigpending",
|
||||||
|
"sigaltstack",
|
||||||
|
|
||||||
|
// get current work dir
|
||||||
|
"getcwd",
|
||||||
|
|
||||||
|
// process exit
|
||||||
|
"exit",
|
||||||
|
"exit_group",
|
||||||
|
|
||||||
|
// others
|
||||||
|
"arch_prctl",
|
||||||
|
|
||||||
|
"gettimeofday",
|
||||||
|
"getrlimit",
|
||||||
|
"getrusage",
|
||||||
|
"times",
|
||||||
|
"time",
|
||||||
|
"clock_gettime",
|
||||||
|
|
||||||
|
"restart_syscall",
|
||||||
|
|
||||||
|
// arch
|
||||||
|
"uname",
|
||||||
|
"set_tls",
|
||||||
|
}
|
||||||
|
|
||||||
|
// default syscalls to trace
|
||||||
|
defaultSyscallTraces = []string{
|
||||||
|
// should be traced
|
||||||
|
"execve",
|
||||||
|
|
||||||
|
// file open
|
||||||
|
"open",
|
||||||
|
"openat",
|
||||||
|
|
||||||
|
// file delete
|
||||||
|
"unlink",
|
||||||
|
"unlinkat",
|
||||||
|
|
||||||
|
// soft link
|
||||||
|
"readlink",
|
||||||
|
"readlinkat",
|
||||||
|
|
||||||
|
// permission check
|
||||||
|
"lstat",
|
||||||
|
"lstat64", // 32-bit
|
||||||
|
"stat",
|
||||||
|
"stat64", // 32-bit
|
||||||
|
"access",
|
||||||
|
}
|
||||||
|
|
||||||
|
// process related syscall if allowProc enabled
|
||||||
|
defaultProcSyscalls = []string{"clone", "fork", "vfork", "nanosleep", "execve"}
|
||||||
|
|
||||||
|
// config for different type of program
|
||||||
|
// workpath and arg0 have additional read / stat permission
|
||||||
|
runprogramConfig = map[string]ProgramConfig{
|
||||||
|
"python2.7": ProgramConfig{
|
||||||
|
Syscall: SyscallConfig{
|
||||||
|
ExtraAllow: []string{
|
||||||
|
"futex", "getdents", "getdents64", "prlimit64", "getpid", "sysinfo",
|
||||||
|
},
|
||||||
|
ExtraCount: map[string]int{
|
||||||
|
"set_tid_address": 1,
|
||||||
|
"set_robust_list": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
FileAccess: FileAccessConfig{
|
||||||
|
ExtraRead: []string{
|
||||||
|
"/usr/bin/python2.7",
|
||||||
|
"/usr/lib/python2.7/",
|
||||||
|
"/usr/bin/lib/python2.7/",
|
||||||
|
"/usr/local/lib/python2.7/",
|
||||||
|
"/usr/lib/pymodules/python2.7/",
|
||||||
|
"/usr/bin/Modules/",
|
||||||
|
"/usr/bin/pybuilddir.txt",
|
||||||
|
"/usr/lib/locale/",
|
||||||
|
"./answer.code",
|
||||||
|
},
|
||||||
|
ExtraStat: []string{
|
||||||
|
"/usr", "/usr/bin",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RunCommand: []string{"/usr/bin/python2.7", "-E", "-s", "-B"},
|
||||||
|
},
|
||||||
|
"python3": ProgramConfig{
|
||||||
|
Syscall: SyscallConfig{
|
||||||
|
ExtraAllow: []string{
|
||||||
|
"futex", "getdents", "getdents64", "prlimit64", "getpid", "sysinfo", "getrandom",
|
||||||
|
},
|
||||||
|
ExtraCount: map[string]int{
|
||||||
|
"set_tid_address": 1,
|
||||||
|
"set_robust_list": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
FileAccess: FileAccessConfig{
|
||||||
|
ExtraRead: []string{
|
||||||
|
"/usr/bin/python3",
|
||||||
|
"/usr/lib/python3/",
|
||||||
|
"/usr/bin/python3.6",
|
||||||
|
"/usr/lib/python3.6/",
|
||||||
|
"/usr/bin/lib/python3.6/",
|
||||||
|
"/usr/local/lib/python3.6/",
|
||||||
|
"/usr/bin/pyvenv.cfg",
|
||||||
|
"/usr/pyvenv.cfg",
|
||||||
|
"/usr/bin/Modules",
|
||||||
|
"/usr/bin/pybuilddir.txt",
|
||||||
|
"/usr/lib/dist-python",
|
||||||
|
"/usr/lib/locale/",
|
||||||
|
"./answer.code",
|
||||||
|
},
|
||||||
|
ExtraStat: []string{
|
||||||
|
"/usr", "/usr/bin", "/usr/lib", "/usr/lib/python36.zip",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RunCommand: []string{"/usr/bin/python3", "-I", "-B"},
|
||||||
|
},
|
||||||
|
"compiler": ProgramConfig{
|
||||||
|
Syscall: SyscallConfig{
|
||||||
|
ExtraAllow: []string{
|
||||||
|
"gettid", "set_tid_address", "set_robust_list", "futex",
|
||||||
|
"getpid", "vfork", "fork", "clone", "execve", "wait4",
|
||||||
|
"clock_gettime", "clock_getres",
|
||||||
|
"setrlimit", "pipe",
|
||||||
|
"getdents64", "getdents",
|
||||||
|
"umask", "rename", "chmod", "mkdir",
|
||||||
|
"chdir", "fchdir",
|
||||||
|
"ftruncate",
|
||||||
|
"sched_getaffinity", "sched_yield",
|
||||||
|
"uname", "sysinfo",
|
||||||
|
"prlimit64", "getrandom",
|
||||||
|
},
|
||||||
|
ExtraBan: []string{"socket", "connect", "geteuid", "getuid"},
|
||||||
|
},
|
||||||
|
FileAccess: FileAccessConfig{
|
||||||
|
ExtraWrite: []string{
|
||||||
|
"/tmp/", "./",
|
||||||
|
},
|
||||||
|
ExtraRead: []string{
|
||||||
|
"./",
|
||||||
|
"../runtime/",
|
||||||
|
"/etc/oracle/java/usagetracker.properties",
|
||||||
|
"/usr/",
|
||||||
|
"/lib/",
|
||||||
|
"/lib64/",
|
||||||
|
"/bin/",
|
||||||
|
"/sbin/",
|
||||||
|
"/sys/devices/system/cpu/",
|
||||||
|
"/proc/",
|
||||||
|
"/etc/timezone",
|
||||||
|
"/etc/fpc-2.6.2.cfg.d/",
|
||||||
|
"/etc/fpc.cfg",
|
||||||
|
"/*",
|
||||||
|
"/", // system_root
|
||||||
|
},
|
||||||
|
ExtraBan: []string{
|
||||||
|
"/etc/nsswitch.conf",
|
||||||
|
"/etc/passwd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
@ -118,9 +118,9 @@ func (h *handler) Handle(ctx *tracer.Context) tracer.TraceAction {
|
|||||||
case "access":
|
case "access":
|
||||||
return h.checkStat(ctx, ctx.Arg0())
|
return h.checkStat(ctx, ctx.Arg0())
|
||||||
|
|
||||||
case "stat":
|
case "stat", "stat64":
|
||||||
return h.checkStat(ctx, ctx.Arg0())
|
return h.checkStat(ctx, ctx.Arg0())
|
||||||
case "lstat":
|
case "lstat", "lstat64":
|
||||||
return h.checkStat(ctx, ctx.Arg0())
|
return h.checkStat(ctx, ctx.Arg0())
|
||||||
|
|
||||||
case "execve":
|
case "execve":
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
|
||||||
|
|
||||||
secutil "github.com/criyle/go-judger/secutil"
|
secutil "github.com/criyle/go-judger/secutil"
|
||||||
tracee "github.com/criyle/go-judger/tracee"
|
tracee "github.com/criyle/go-judger/tracee"
|
||||||
@ -21,7 +20,6 @@ func main() {
|
|||||||
timeLimit, realTimeLimit, memoryLimit, outputLimit, stackLimit uint
|
timeLimit, realTimeLimit, memoryLimit, outputLimit, stackLimit uint
|
||||||
inputFileName, outputFileName, errorFileName, workPath string
|
inputFileName, outputFileName, errorFileName, workPath string
|
||||||
)
|
)
|
||||||
debug.SetGCPercent(-1)
|
|
||||||
|
|
||||||
flag.UintVar(&timeLimit, "tl", 1, "Set time limit (in second)")
|
flag.UintVar(&timeLimit, "tl", 1, "Set time limit (in second)")
|
||||||
flag.UintVar(&realTimeLimit, "rtl", 0, "Set real time limit (in second)")
|
flag.UintVar(&realTimeLimit, "rtl", 0, "Set real time limit (in second)")
|
||||||
@ -101,11 +99,15 @@ func main() {
|
|||||||
fds[i] = uintptr(i)
|
fds[i] = uintptr(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rlimit
|
||||||
|
rlimit := prepareRLimit(timeLimit, realTimeLimit, outputLimit<<20, stackLimit<<20)
|
||||||
|
|
||||||
// get tracee
|
// get tracee
|
||||||
ch := &tracee.Runner{
|
ch := &tracee.Runner{
|
||||||
Args: args,
|
Args: args,
|
||||||
Env: []string{"PATH=/"},
|
Env: []string{"PATH=/"},
|
||||||
RLimits: prepareRLimit(timeLimit, realTimeLimit, outputLimit<<20, stackLimit<<20),
|
RLimits: rlimit,
|
||||||
Files: fds,
|
Files: fds,
|
||||||
WorkDir: workPath,
|
WorkDir: workPath,
|
||||||
BPF: bpf,
|
BPF: bpf,
|
||||||
|
|||||||
@ -91,7 +91,8 @@ func (r *Runner) Start() (int, error) {
|
|||||||
|
|
||||||
// Set limit
|
// Set limit
|
||||||
for _, rlim := range r.RLimits {
|
for _, rlim := range r.RLimits {
|
||||||
_, _, err1 = syscall.RawSyscall(syscall.SYS_SETRLIMIT, uintptr(rlim.Res), uintptr(unsafe.Pointer(&rlim.Rlim)), 0)
|
// Prlimit instead of setrlimit to avoid 32-bit limitation (linux > 3.2)
|
||||||
|
_, _, err1 = syscall.RawSyscall6(syscall.SYS_PRLIMIT64, 0, uintptr(rlim.Res), uintptr(unsafe.Pointer(&rlim.Rlim)), 0, 0, 0)
|
||||||
if err1 != 0 {
|
if err1 != 0 {
|
||||||
goto childerror
|
goto childerror
|
||||||
}
|
}
|
||||||
|
|||||||
1
tracee/tracee_fork.s
Normal file
1
tracee/tracee_fork.s
Normal file
@ -0,0 +1 @@
|
|||||||
|
// to use go:linkname
|
||||||
61
tracer/context_arm.go
Normal file
61
tracer/context_arm.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package tracer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
unix "golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SyscallNo get current syscall no
|
||||||
|
func (c *Context) SyscallNo() uint {
|
||||||
|
return uint(c.regs.Uregs[7]) // R7
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arg0 gets the arg0 for the current syscall
|
||||||
|
func (c *Context) Arg0() uint {
|
||||||
|
return uint(c.regs.Uregs[17]) //Orig_R0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arg1 gets the arg1 for the current syscall
|
||||||
|
func (c *Context) Arg1() uint {
|
||||||
|
return uint(c.regs.Uregs[1]) // R1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arg2 gets the arg2 for the current syscall
|
||||||
|
func (c *Context) Arg2() uint {
|
||||||
|
return uint(c.regs.Uregs[2]) // R2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arg3 gets the arg3 for the current syscall
|
||||||
|
func (c *Context) Arg3() uint {
|
||||||
|
return uint(c.regs.Uregs[3]) // R3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arg4 gets the arg4 for the current syscall
|
||||||
|
func (c *Context) Arg4() uint {
|
||||||
|
return uint(c.regs.Uregs[4]) // R4
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arg5 gets the arg5 for the current syscall
|
||||||
|
func (c *Context) Arg5() uint {
|
||||||
|
return uint(c.regs.Uregs[5]) //R5
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReturnValue set the return value if skip the syscall
|
||||||
|
func (c *Context) SetReturnValue(retval int) {
|
||||||
|
c.regs.Uregs[0] = uint32(retval) // R0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) skipSyscall() error {
|
||||||
|
c.regs.Uregs[7] = ^uint32(0) //-1
|
||||||
|
return syscall.PtraceSetRegs(c.Pid, &c.regs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIovecs(base *byte, l int) []unix.Iovec {
|
||||||
|
return []unix.Iovec{
|
||||||
|
unix.Iovec{
|
||||||
|
Base: base,
|
||||||
|
Len: uint32(l),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -83,16 +83,6 @@ func Trace(handler Handler, runners []Runner, limits ResLimit, timeout int64) (r
|
|||||||
return results, TraceCodeFatal
|
return results, TraceCodeFatal
|
||||||
}
|
}
|
||||||
println("------ ", pid, " ------")
|
println("------ ", pid, " ------")
|
||||||
// Set option if the process is newly forked
|
|
||||||
if !traced[pid] {
|
|
||||||
println("set ptrace option")
|
|
||||||
traced[pid] = true
|
|
||||||
// Ptrace set option valid if the tracee is stopped
|
|
||||||
err = setPtraceOption(pid)
|
|
||||||
if err != nil {
|
|
||||||
return results, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update resource usage and check against limits
|
// update resource usage and check against limits
|
||||||
userTime := uint(rusage.Utime.Sec*1e3 + rusage.Utime.Usec/1e3) // ms
|
userTime := uint(rusage.Utime.Sec*1e3 + rusage.Utime.Usec/1e3) // ms
|
||||||
@ -155,6 +145,18 @@ func Trace(handler Handler, runners []Runner, limits ResLimit, timeout int64) (r
|
|||||||
delete(traced, pid)
|
delete(traced, pid)
|
||||||
|
|
||||||
case wstatus.Stopped():
|
case wstatus.Stopped():
|
||||||
|
// Set option if the process is newly forked
|
||||||
|
if !traced[pid] {
|
||||||
|
println("set ptrace option")
|
||||||
|
traced[pid] = true
|
||||||
|
// Ptrace set option valid if the tracee is stopped
|
||||||
|
err = setPtraceOption(pid)
|
||||||
|
if err != nil {
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check stop signal, if trap then check seccomp
|
||||||
if stopSig := wstatus.StopSignal(); stopSig == unix.SIGTRAP {
|
if stopSig := wstatus.StopSignal(); stopSig == unix.SIGTRAP {
|
||||||
switch trapCause := wstatus.TrapCause(); trapCause {
|
switch trapCause := wstatus.TrapCause(); trapCause {
|
||||||
case unix.PTRACE_EVENT_SECCOMP:
|
case unix.PTRACE_EVENT_SECCOMP:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user