-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrootless_linux.go
More file actions
124 lines (111 loc) · 3.21 KB
/
rootless_linux.go
File metadata and controls
124 lines (111 loc) · 3.21 KB
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
117
118
119
120
121
122
123
124
//go:build linux
package bbox
import (
"fmt"
"os"
"os/exec"
"github.com/moolen/bbox/internal/dockerbuildpaths"
"github.com/moolen/bbox/internal/sandboxroot"
)
const defaultBuilderCgroupPath = "/sys/fs/cgroup"
type bwrapCommandConfig struct {
runtimeBinary string
root string
proxyListenAddr string
mitm MITMOptions
opts SandboxOptions
builder *sandboxroot.BuilderTooling
mode TrafficMode
payloadSeccompPath string
bridgeFD int
seccompFD int
extraFiles []*os.File
dockerSocketMount *dockerSocketMount
maxRequestBody int64
}
func buildLinuxSandboxCommand(cfg bwrapCommandConfig) (*exec.Cmd, error) {
tooling := cfg.builder
if tooling == nil {
var err error
tooling, err = sandboxroot.ResolveDockerBuildSupport(toSandboxrootDockerBuildOptions(cfg.opts.DockerBuild))
if err != nil {
return nil, err
}
}
mounts := append([]Mount(nil), cfg.opts.Mounts...)
var tmpfsTargets []string
if tooling != nil {
tmpfsTargets = defaultBuilderTmpfsTargets(mounts)
mounts = appendBuilderMounts(mounts)
}
runtimeMounts, err := prepareRuntimeMounts(cfg.root, mounts)
if err != nil {
return nil, fmt.Errorf("prepare runtime mounts: %w", err)
}
bwrapArgs := buildBwrapArgs(bwrapArgsConfig{
root: cfg.root,
helperPath: sandboxroot.DefaultSandboxBBoxPath,
proxyListenAddr: cfg.proxyListenAddr,
mitm: cfg.mitm,
unshareUser: os.Geteuid() != 0 && tooling == nil,
capSysAdmin: tooling != nil,
maxRequestBodyBytes: cfg.maxRequestBody,
mounts: runtimeMounts,
tmpfsTargets: tmpfsTargets,
dockerSocketMount: cfg.dockerSocketMount,
trafficMode: cfg.mode,
payloadSeccompBPFPath: cfg.payloadSeccompPath,
bridgeFD: cfg.bridgeFD,
seccompFD: cfg.seccompFD,
})
var cmd *exec.Cmd
if tooling != nil {
args := append([]string{"--cgroup-manager=cgroupfs", "unshare", "bwrap"}, bwrapArgs...)
cmd = exec.Command(tooling.PodmanPath, args...)
} else {
cmd = exec.Command("bwrap", bwrapArgs...)
}
cmd.ExtraFiles = cfg.extraFiles
return cmd, nil
}
func appendBuilderMounts(mounts []Mount) []Mount {
info, err := os.Stat(defaultBuilderCgroupPath)
if err != nil || !info.IsDir() {
return mounts
}
return appendBuilderMountIfAbsent(mounts, Mount{
Type: MountTypeBind,
Source: defaultBuilderCgroupPath,
Target: defaultBuilderCgroupPath,
ReadOnly: true,
})
}
func appendBuilderMountIfAbsent(mounts []Mount, want Mount) []Mount {
for _, mount := range mounts {
if targetsOverlap(mount.Target, want.Target) {
return mounts
}
}
return append(mounts, want)
}
func defaultBuilderTmpfsTargets(mounts []Mount) []string {
targets := make([]string, 0, 2)
for _, target := range []string{
dockerbuildpaths.DefaultBuildkitRootPath,
dockerbuildpaths.DefaultBuildOutputDir,
} {
if builderTargetMounted(mounts, target) {
continue
}
targets = append(targets, target)
}
return targets
}
func builderTargetMounted(mounts []Mount, target string) bool {
for _, mount := range mounts {
if targetsOverlap(mount.Target, target) {
return true
}
}
return false
}