Skip to content

Commit 7cc8e52

Browse files
author
Christian Weichel
committed
[ws-daemon] Support proc mounts using open_tree/move_mount
1 parent 7712280 commit 7cc8e52

39 files changed

+1476
-663
lines changed

components/docker-up/runc-facade/main.go

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -35,62 +35,25 @@ func main() {
3535
log.WithError(err).Fatal("runc not found")
3636
}
3737

38-
var runcDirect bool
38+
var useFacade bool
3939
for _, arg := range os.Args {
40-
if arg == "-v" || arg == "--version" {
41-
runcDirect = true
40+
if arg == "create" {
41+
useFacade = true
4242
break
4343
}
4444
}
45-
if runcDirect {
46-
err = syscall.Exec(runcPath, os.Args, os.Environ())
47-
if err != nil {
48-
panic(err)
49-
}
50-
}
5145

52-
switch os.Args[0] {
53-
case cmdMountProc:
54-
err = mountProc()
55-
case cmdUnmountProc:
56-
err = unmountProc()
57-
default:
58-
err = runc(runcPath)
46+
if useFacade {
47+
err = createAndRunc(runcPath)
48+
} else {
49+
err = syscall.Exec(runcPath, os.Args, os.Environ())
5950
}
6051
if err != nil {
6152
log.WithError(err).Fatal("failed")
6253
}
6354
}
6455

65-
func mountProc() error {
66-
wd, err := os.Getwd()
67-
if err != nil {
68-
return err
69-
}
70-
71-
err = ioutil.WriteFile("/tmp/runc-facade-mount", []byte(wd+"\n"+fmt.Sprint(os.Args)), 0644)
72-
if err != nil {
73-
return err
74-
}
75-
76-
return nil
77-
}
78-
79-
func unmountProc() error {
80-
wd, err := os.Getwd()
81-
if err != nil {
82-
return err
83-
}
84-
85-
err = ioutil.WriteFile("/tmp/runc-facade-unmount", []byte(wd), 0644)
86-
if err != nil {
87-
return err
88-
}
89-
90-
return nil
91-
}
92-
93-
func runc(runcPath string) error {
56+
func createAndRunc(runcPath string) error {
9457
fc, err := ioutil.ReadFile("config.json")
9558
if err != nil {
9659
return fmt.Errorf("cannot read config.json: %w", err)

components/workspacekit/BUILD.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,18 @@ packages:
2020
config:
2121
commands:
2222
- ["sh", "-c", "curl -L https://github.com/seccomp/libseccomp/releases/download/v2.5.1/libseccomp-2.5.1.tar.gz | tar xz"]
23-
- ["sh", "-c", "cd libseccomp-2.5.1 && ./configure --prefix=$PWD/../lib && make && make install"]
23+
- ["sh", "-c", "cd libseccomp-2.5.1 && ./configure --prefix=$PWD/../lib && make && make install"]
24+
- name: lib
25+
type: go
26+
srcs:
27+
- go.mod
28+
- go.sum
29+
- "pkg/**/*.go"
30+
- "pkg/**/*.c"
31+
deps:
32+
- components/common-go:lib
33+
- components/ws-daemon-api/go:lib
34+
- components/content-service-api/go:lib
35+
config:
36+
packaging: library
37+
dontTest: true

components/workspacekit/cmd/handler-mount.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

components/workspacekit/cmd/handler.go

Lines changed: 0 additions & 19 deletions
This file was deleted.

components/workspacekit/cmd/rings.go

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ var ring1Cmd = &cobra.Command{
218218
unix.Prctl(unix.PR_SET_PDEATHSIG, uintptr(unix.SIGKILL), 0, 0, 0)
219219
runtime.UnlockOSThread()
220220

221-
tmpdir, err := ioutil.TempDir("", "supervisor")
221+
ring2Root, err := ioutil.TempDir("", "supervisor")
222222
if err != nil {
223223
log.WithError(err).Fatal("cannot create tempdir")
224224
}
@@ -243,7 +243,7 @@ var ring1Cmd = &cobra.Command{
243243
{Target: "/tmp", Source: "tmpfs", FSType: "tmpfs"},
244244
}
245245
for _, m := range mnts {
246-
dst := filepath.Join(tmpdir, m.Target)
246+
dst := filepath.Join(ring2Root, m.Target)
247247
_ = os.MkdirAll(dst, 0644)
248248

249249
if m.Source == "" {
@@ -281,7 +281,7 @@ var ring1Cmd = &cobra.Command{
281281
Pdeathsig: syscall.SIGKILL,
282282
Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWPID,
283283
}
284-
cmd.Dir = tmpdir
284+
cmd.Dir = ring2Root
285285
cmd.Stdin = os.Stdin
286286
cmd.Stdout = os.Stdout
287287
cmd.Stderr = os.Stderr
@@ -294,31 +294,28 @@ var ring1Cmd = &cobra.Command{
294294
sigc := sigproxy.ForwardAllSignals(context.Background(), cmd.Process.Pid)
295295
defer sigproxysignal.StopCatch(sigc)
296296

297-
procLoc := filepath.Join(tmpdir, "proc")
297+
procLoc := filepath.Join(ring2Root, "proc")
298298
err = os.MkdirAll(procLoc, 0755)
299299
if err != nil {
300300
log.WithError(err).Error("cannot mount proc")
301301
failed = true
302302
return
303303
}
304-
resp, err := client.MountProc(ctx, &daemonapi.MountProcRequest{
305-
Pid: int64(cmd.Process.Pid),
304+
_, err = client.MountProc(ctx, &daemonapi.MountProcRequest{
305+
Target: procLoc,
306+
Pid: int64(cmd.Process.Pid),
306307
})
307308
if err != nil {
308309
log.WithError(err).Error("cannot mount proc")
309310
failed = true
310311
return
311312
}
312313

313-
// TODO(cw): this mount doesn't work because we need to be in the ring2 mount namespace.
314-
// Use nsenter/mount handler to do this.
315-
err = unix.Mount(resp.Location, procLoc, "", unix.MS_MOVE, "")
316-
if err != nil {
317-
log.WithError(err).WithFields(map[string]interface{}{"loc": resp.Location, "dest": procLoc}).Error("cannot move proc mount")
318-
failed = true
319-
return
320-
}
321-
314+
// We have to wait for ring2 to come back to us and connect to the socket we've passed along.
315+
// There's a chance that ring2 crashes or misbehaves, so we don't want to wait forever, hence
316+
// the someone complicated "accept" logic below.
317+
// If there's a deadline that can be set somewhere that we've missed, we should be using that
318+
// one instead.
322319
incoming := make(chan net.Conn, 1)
323320
errc := make(chan error, 1)
324321
go func() {
@@ -364,7 +361,7 @@ var ring1Cmd = &cobra.Command{
364361
log.Info("signaling to child process")
365362
_, err = msgutil.MarshalToWriter(ring2Conn, ringSyncMsg{
366363
Stage: 1,
367-
Rootfs: tmpdir,
364+
Rootfs: ring2Root,
368365
})
369366
if err != nil {
370367
log.WithError(err).Error("cannot send ring sync msg to ring2")
@@ -383,7 +380,15 @@ var ring1Cmd = &cobra.Command{
383380
if scmpfd == 0 {
384381
log.Warn("received 0 as ring2 seccomp fd - syscall handling is broken")
385382
} else {
386-
stp, errchan := seccomp.Handle(scmpfd, cmd.Process.Pid, client)
383+
handler := &seccomp.InWorkspaceHandler{
384+
FD: scmpfd,
385+
Daemon: client,
386+
Ring2PID: cmd.Process.Pid,
387+
Ring2Rootfs: ring2Root,
388+
BindEvents: make(chan seccomp.BindEvent),
389+
}
390+
391+
stp, errchan := seccomp.Handle(scmpfd, handler)
387392
defer close(stp)
388393
go func() {
389394
t := time.NewTicker(10 * time.Millisecond)
@@ -505,14 +510,18 @@ var ring2Cmd = &cobra.Command{
505510
// our seccomp filter, and tell our parent about it.
506511
scmpFd, err := seccomp.LoadFilter()
507512
if err != nil {
508-
log.WithError(err).Warn("cannot load seccomp filter - syscall handling will be broken")
513+
log.WithError(err).Error("cannot load seccomp filter - syscall handling would be broken")
514+
failed = true
515+
return
509516
}
510517
connf, err := conn.File()
511518
if err != nil {
512519
log.WithError(err).Error("cannot get parent socket fd")
513520
failed = true
514521
return
515522
}
523+
defer connf.Close()
524+
516525
sktfd := int(connf.Fd())
517526
err = unix.Sendmsg(sktfd, nil, unix.UnixRights(int(scmpFd)), nil, 0)
518527
connf.Close()
@@ -534,6 +543,7 @@ var ring2Cmd = &cobra.Command{
534543
failed = true
535544
return
536545
}
546+
537547
err = unix.Exec(ring2Opts.SupervisorPath, []string{"supervisor", "run", "--inns"}, os.Environ())
538548
if err != nil {
539549
log.WithError(err).WithField("cmd", ring2Opts.SupervisorPath).Error("cannot exec")

components/workspacekit/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ replace github.com/seccomp/libseccomp-golang => github.com/kinvolk/libseccomp-go
77
require (
88
github.com/gitpod-io/gitpod/common-go v0.0.0-00010101000000-000000000000
99
github.com/gitpod-io/gitpod/ws-daemon/api v0.0.0-00010101000000-000000000000
10+
github.com/moby/sys/mountinfo v0.4.0
1011
github.com/rootless-containers/rootlesskit v0.11.1
1112
github.com/seccomp/libseccomp-golang v0.9.1
1213
github.com/spf13/cobra v1.1.1

components/workspacekit/go.sum

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
7979
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
8080
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
8181
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
82+
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
8283
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
84+
github.com/fatih/gomodifytags v1.13.0/go.mod h1:TbUyEjH1Zo0GkJd2Q52oVYqYcJ0eGNqG8bsiOb75P9c=
85+
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
8386
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
8487
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
8588
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@@ -226,6 +229,7 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
226229
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
227230
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
228231
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
232+
github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM=
229233
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
230234
github.com/moby/vpnkit v0.4.0/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ=
231235
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -451,6 +455,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
451455
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
452456
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
453457
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
458+
golang.org/x/tools v0.0.0-20180824175216-6c1c5e93cdc1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
454459
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
455460
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
456461
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

components/workspacekit/main.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package main
66

77
import (
88
"github.com/gitpod-io/gitpod/workspacekit/cmd"
9-
_ "github.com/gitpod-io/gitpod/workspacekit/pkg/nsenter"
109
)
1110

1211
func main() {

components/workspacekit/pkg/nsenter/nsenter.go

Lines changed: 0 additions & 12 deletions
This file was deleted.

components/workspacekit/pkg/nsenter/nsenter_gccgo.go

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)