1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
package main
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"os"
"runtime"
"syscall"
)
type plan struct {
Source string
Command []string
Base string
Environment string
}
type poeExitReason int
const (
POE_SUCCESS = 0
POE_SIGNALED = 1
POE_TIMEDOUT = 2
)
type resultPack struct {
result poeExitReason
status int
msg string
}
func poePanic(err error, msg string) {
cleanup()
panic(fmt.Sprintf("%s (%s)", msg, err.Error()))
}
func cleanup() {
err1 := StopScope()
err2 := PlaygroundDestroy()
if err1 != nil {
panic(err1)
}
if err2 != nil {
panic(err2)
}
}
func main() {
runtime.GOMAXPROCS(3)
dec := json.NewDecoder(os.Stdin)
var plan plan
if err := dec.Decode(&plan); err != nil {
panic(fmt.Sprintf("failed to parse plan: %s", err))
}
//fmt.Fprintf(os.Stderr, "plan: %+v\n", plan)
runtime.LockOSThread()
if err := syscall.Setresuid(0, 0, 0); err != nil {
poePanic(err, "setuid failed")
}
if err := InitializeSystemdBus(); err != nil {
poePanic(err, "failed to connect to systemd")
}
runtime.UnlockOSThread()
rootdir, errx := PlaygroundCreate(plan.Base, plan.Environment)
if errx != nil {
poePanic(errx, "playground_create failed")
}
progfile, errx := PlaygroundCopy(rootdir, plan.Source)
if errx != nil {
poePanic(errx, "playground_copy failed")
}
var stdin_fd, stdout_fd, stderr_fd [2]int
if err := syscall.Pipe2(stdin_fd[:], 0); err != nil {
poePanic(err, "pipe2 failed")
}
if err := syscall.Pipe2(stdout_fd[:], syscall.O_DIRECT); err != nil {
poePanic(err, "pipe2 failed")
}
if err := syscall.Pipe2(stderr_fd[:], syscall.O_DIRECT); err != nil {
poePanic(err, "pipe2 failed")
}
pid_, _, err := syscall.Syscall(syscall.SYS_CLONE, uintptr(syscall.SIGCHLD|syscall.CLONE_NEWIPC|syscall.CLONE_NEWNS|syscall.CLONE_NEWPID|syscall.CLONE_NEWUTS|syscall.CLONE_NEWNET), 0, 0)
pid := int(pid_)
if err != 0 {
poePanic(error(err), "clone failed")
} else if pid == 0 {
runtime.LockOSThread()
if err, msg := doChild(rootdir, progfile, plan, stdin_fd, stdout_fd, stderr_fd); err != nil {
fmt.Fprintf(os.Stderr, "%s (%s)", msg, err.Error())
os.Exit(127)
}
// unreachable
} else {
res := doParent(pid, stdin_fd, stdout_fd, stderr_fd)
cleanup()
var buf bytes.Buffer
binary.Write(&buf, binary.LittleEndian, int32(res.result))
binary.Write(&buf, binary.LittleEndian, int32(res.status))
if _, err := os.Stderr.Write(buf.Bytes()); err != nil {
poePanic(err, "stderr write failed")
}
if _, err := os.Stderr.Write([]byte(res.msg)); err != nil {
poePanic(err, "stderr write failed")
}
os.Exit(0)
// unreachable
}
}
|