mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-11-04 14:49:53 +08:00
update documentations
This commit is contained in:
parent
7be82acdf7
commit
a4c78dcf5d
@ -1,5 +1,6 @@
|
||||
// Package cgroup provices builder to create multiple different cgroup-v1 sub groups
|
||||
// under systemd defined path (i.e. /sys/fs/cgroup)
|
||||
// under systemd defined path (i.e. /sys/fs/cgroup).
|
||||
//
|
||||
// current avaliable cgroups are cpuacct, memory, pids
|
||||
// not avaliable: cpu, cpuset, devices, freezer, net_cls, blkio, perf_event, net_prio, huge_tlb, rdma
|
||||
package cgroup
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package forkexec
|
||||
|
||||
import (
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package forkexec
|
||||
|
||||
import (
|
||||
|
||||
7
pkg/forkexec/doc.go
Normal file
7
pkg/forkexec/doc.go
Normal file
@ -0,0 +1,7 @@
|
||||
// Package forkexec provides interface to run a subprocess with seccomp filter, rlimit and
|
||||
// containerized or ptraced.
|
||||
//
|
||||
// unshare cgroup namespace requires kernel >= 4.6
|
||||
// seccomp, unshare pid / user namespaces requires kernel >= 3.8
|
||||
// pipe2, dup3 requires kernel >= 2.6.27
|
||||
package forkexec
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package forkexec
|
||||
|
||||
import (
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package forkexec
|
||||
|
||||
import (
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package forkexec
|
||||
|
||||
import (
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// Package forkexec provides interface to run a subprocess with seccomp filter, rlimit and
|
||||
// containerized or ptraced
|
||||
// +build linux
|
||||
|
||||
package forkexec
|
||||
|
||||
import (
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package forkexec
|
||||
|
||||
import (
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
// Package pipe provides a wrapper to create a pipe and
|
||||
// read at most max content from the reader side
|
||||
// collect at most max bytes from the reader side
|
||||
package pipe
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
@ -50,3 +51,7 @@ func NewBuffer(max int64) (*Buffer, error) {
|
||||
Done: done,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b Buffer) String() string {
|
||||
return fmt.Sprintf("Buffer[%d/%d]", b.Buffer.Len(), b.Max)
|
||||
}
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
// Package rlimit provides data structure for resource limits by setrlimit syscall on linux.
|
||||
package rlimit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/criyle/go-sandbox/types"
|
||||
)
|
||||
|
||||
// RLimits defines the rlimit applied by setrlimit syscall to traced process
|
||||
@ -67,3 +72,34 @@ func (r *RLimits) PrepareRLimit() []RLimit {
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (r RLimit) String() string {
|
||||
if r.Res == syscall.RLIMIT_CPU {
|
||||
return fmt.Sprintf("CPU[%d s:%d s]", r.Rlim.Cur, r.Rlim.Max)
|
||||
}
|
||||
t := ""
|
||||
switch r.Res {
|
||||
case syscall.RLIMIT_DATA:
|
||||
t = "Data"
|
||||
case syscall.RLIMIT_FSIZE:
|
||||
t = "File"
|
||||
case syscall.RLIMIT_STACK:
|
||||
t = "Stack"
|
||||
case syscall.RLIMIT_AS:
|
||||
t = "AddressSpace"
|
||||
}
|
||||
return fmt.Sprintf("%s[%v:%v]", t, types.Size(r.Rlim.Cur), types.Size(r.Rlim.Max))
|
||||
}
|
||||
|
||||
func (r RLimits) String() string {
|
||||
var sb strings.Builder
|
||||
sb.WriteString("RLimits[")
|
||||
for i, rl := range r.PrepareRLimit() {
|
||||
if i > 0 {
|
||||
sb.WriteByte(',')
|
||||
}
|
||||
sb.WriteString(rl.String())
|
||||
}
|
||||
sb.WriteString("]")
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
@ -1,22 +1,5 @@
|
||||
// Package seccomp provides a generated filter format for seccomp filter
|
||||
|
||||
// +build linux
|
||||
|
||||
package seccomp
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Filter is the BPF seccomp filter value
|
||||
type Filter []byte
|
||||
|
||||
// SockFprog converts Filter to SockFprog for seccomp syscall
|
||||
func (f Filter) SockFprog() *syscall.SockFprog {
|
||||
b := []byte(f)
|
||||
return &syscall.SockFprog{
|
||||
Len: uint16(len(b) / 8),
|
||||
Filter: (*syscall.SockFilter)(unsafe.Pointer(&b[0])),
|
||||
}
|
||||
}
|
||||
|
||||
15
pkg/seccomp/filter_linux.go
Normal file
15
pkg/seccomp/filter_linux.go
Normal file
@ -0,0 +1,15 @@
|
||||
package seccomp
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// SockFprog converts Filter to SockFprog for seccomp syscall
|
||||
func (f Filter) SockFprog() *syscall.SockFprog {
|
||||
b := []byte(f)
|
||||
return &syscall.SockFprog{
|
||||
Len: uint16(len(b) / 8),
|
||||
Filter: (*syscall.SockFilter)(unsafe.Pointer(&b[0])),
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package libseccomp
|
||||
|
||||
import (
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// Package libseccomp provides wrapper to "github.com/seccomp/libseccomp-golang"
|
||||
// +build linux
|
||||
|
||||
package libseccomp
|
||||
|
||||
import (
|
||||
|
||||
2
pkg/seccomp/libseccomp/doc.go
Normal file
2
pkg/seccomp/libseccomp/doc.go
Normal file
@ -0,0 +1,2 @@
|
||||
// Package libseccomp provides a wrapper for "github.com/seccomp/libseccomp-golang"
|
||||
package libseccomp
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package libseccomp
|
||||
|
||||
import (
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
// Package unixsocket provides wrapper for Linux unix socket to send and recv oob messages
|
||||
// including fd and user credential.
|
||||
package unixsocket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@ -11,17 +14,15 @@ import (
|
||||
// oob size default to page size
|
||||
const oobSize = 4096
|
||||
|
||||
// use pool to avoid allocate
|
||||
// use pool to minimize allocate gabage collector overhead
|
||||
var oobPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make([]byte, oobSize)
|
||||
},
|
||||
}
|
||||
|
||||
// Socket represents a unix socket
|
||||
type Socket struct {
|
||||
*net.UnixConn
|
||||
}
|
||||
// Socket wrappers a unix socket connection
|
||||
type Socket net.UnixConn
|
||||
|
||||
// Msg is the oob msg with the message
|
||||
type Msg struct {
|
||||
@ -37,46 +38,51 @@ type Msg struct {
|
||||
func NewSocket(fd int) (*Socket, error) {
|
||||
file := os.NewFile(uintptr(fd), "unix-socket")
|
||||
if file == nil {
|
||||
return nil, fmt.Errorf("NewSocket: fd(%d) is not a valid fd", fd)
|
||||
return nil, fmt.Errorf("NewSocket: %d is not a valid fd", fd)
|
||||
}
|
||||
defer file.Close()
|
||||
syscall.CloseOnExec(int(file.Fd()))
|
||||
|
||||
conn, err := net.FileConn(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unixConn, ok := conn.(*net.UnixConn)
|
||||
if !ok {
|
||||
conn.Close()
|
||||
return nil, fmt.Errorf("NewSocket: fd(%d) is not a unix socket", fd)
|
||||
return nil, fmt.Errorf("NewSocket: %d is not a valid unix socket connection", fd)
|
||||
}
|
||||
return &Socket{unixConn}, nil
|
||||
return (*Socket)(unixConn), nil
|
||||
}
|
||||
|
||||
// NewSocketPair creates connected unix socketpair using SOCK_SEQPACKET
|
||||
func NewSocketPair() (*Socket, *Socket, error) {
|
||||
fd, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_SEQPACKET|syscall.SOCK_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("NewSocketPair: failed to call socketpair(%v)", err)
|
||||
return nil, nil, fmt.Errorf("NewSocketPair: failed to call socketpair %w", err)
|
||||
}
|
||||
|
||||
ins, err := NewSocket(fd[0])
|
||||
if err != nil {
|
||||
syscall.Close(fd[0])
|
||||
syscall.Close(fd[1])
|
||||
return nil, nil, fmt.Errorf("NewSocketPair: failed to call NewSocket ins(%v)", err)
|
||||
return nil, nil, fmt.Errorf("NewSocketPair: failed to call NewSocket on sender %w", err)
|
||||
}
|
||||
|
||||
outs, err := NewSocket(fd[1])
|
||||
if err != nil {
|
||||
ins.Close()
|
||||
syscall.Close(fd[1])
|
||||
return nil, nil, fmt.Errorf("NewSocketPair: failed to call NewSocket outs(%v)", err)
|
||||
return nil, nil, fmt.Errorf("NewSocketPair: failed to call NewSocket receiver %w", err)
|
||||
}
|
||||
|
||||
return ins, outs, nil
|
||||
}
|
||||
|
||||
// SetPassCred set sockopt for pass cred for unix socket
|
||||
func (s *Socket) SetPassCred(option int) error {
|
||||
sysconn, err := s.SyscallConn()
|
||||
sysconn, err := (*net.UnixConn)(s).SyscallConn()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -87,16 +93,20 @@ func (s *Socket) SetPassCred(option int) error {
|
||||
|
||||
// SendMsg sendmsg to unix socket and encode possible unix right / credential
|
||||
func (s *Socket) SendMsg(b []byte, m *Msg) error {
|
||||
var oob []byte
|
||||
buf := oobPool.Get().([]byte)
|
||||
defer oobPool.Put(buf)
|
||||
|
||||
oob := bytes.NewBuffer(buf[:0])
|
||||
if m != nil {
|
||||
if len(m.Fds) > 0 {
|
||||
oob = append(oob, syscall.UnixRights(m.Fds...)...)
|
||||
oob.Write(syscall.UnixRights(m.Fds...))
|
||||
}
|
||||
if m.Cred != nil {
|
||||
oob = append(oob, syscall.UnixCredentials(m.Cred)...)
|
||||
oob.Write(syscall.UnixCredentials(m.Cred))
|
||||
}
|
||||
}
|
||||
_, _, err := s.WriteMsgUnix(b, oob, nil)
|
||||
|
||||
_, _, err := (*net.UnixConn)(s).WriteMsgUnix(b, oob.Bytes(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -107,7 +117,8 @@ func (s *Socket) SendMsg(b []byte, m *Msg) error {
|
||||
func (s *Socket) RecvMsg(b []byte) (int, *Msg, error) {
|
||||
oob := oobPool.Get().([]byte)
|
||||
defer oobPool.Put(oob)
|
||||
n, oobn, _, _, err := s.ReadMsgUnix(b, oob)
|
||||
|
||||
n, oobn, _, _, err := (*net.UnixConn)(s).ReadMsgUnix(b, oob)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
@ -126,23 +137,24 @@ func (s *Socket) RecvMsg(b []byte) (int, *Msg, error) {
|
||||
func parseMsg(msgs []syscall.SocketControlMessage) (*Msg, error) {
|
||||
var msg Msg
|
||||
for _, m := range msgs {
|
||||
if m.Header.Level == syscall.SOL_SOCKET {
|
||||
switch m.Header.Type {
|
||||
case syscall.SCM_CREDENTIALS:
|
||||
cred, err := syscall.ParseUnixCredentials(&m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msg.Cred = cred
|
||||
|
||||
case syscall.SCM_RIGHTS:
|
||||
fds, err := syscall.ParseUnixRights(&m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msg.Fds = fds
|
||||
if m.Header.Level != syscall.SOL_SOCKET {
|
||||
continue
|
||||
}
|
||||
|
||||
switch m.Header.Type {
|
||||
case syscall.SCM_CREDENTIALS:
|
||||
cred, err := syscall.ParseUnixCredentials(&m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msg.Cred = cred
|
||||
|
||||
case syscall.SCM_RIGHTS:
|
||||
fds, err := syscall.ParseUnixRights(&m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msg.Fds = fds
|
||||
}
|
||||
}
|
||||
return &msg, nil
|
||||
|
||||
44
ptracer/context_other.go
Normal file
44
ptracer/context_other.go
Normal file
@ -0,0 +1,44 @@
|
||||
// +build !linux
|
||||
|
||||
package ptracer
|
||||
|
||||
// Context empty structure filler for other OS
|
||||
type Context struct {
|
||||
Pid int
|
||||
}
|
||||
|
||||
func (c *Context) SyscallNo() uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Context) Arg0() uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Context) Arg1() uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Context) Arg2() uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Context) Arg3() uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Context) Arg4() uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Context) Arg5() uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Context) SetReturnValue(retval int) {
|
||||
|
||||
}
|
||||
|
||||
func (c *Context) GetString(addr uintptr) string {
|
||||
return ""
|
||||
}
|
||||
3
ptracer/doc.go
Normal file
3
ptracer/doc.go
Normal file
@ -0,0 +1,3 @@
|
||||
// Package ptracer provides platfirm independent ptrace pooling loop
|
||||
// interface to trace program syscalls on Linux.
|
||||
package ptracer
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package unshare
|
||||
|
||||
import (
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// +build linux
|
||||
|
||||
package unshare
|
||||
|
||||
import (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user