-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[supervisor] execve into ring3 #2664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
28a182c
to
f511f1a
Compare
/werft run 👍 started the job as gitpod-build-cw-supervisor-execve-ring3.23 |
components/supervisor/cmd/rings.go
Outdated
log.WithError(err).Error("failed to start the child process") | ||
err = cap.SetUID(33333) | ||
if err != nil { | ||
log.WithError(err).Error("cannot setgid") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error msg switched
components/supervisor/cmd/rings.go
Outdated
}, | ||
err = cap.SetGroups(33333) | ||
if err != nil { | ||
log.WithError(err).Error("cannot setuid") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error msg switched
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switche err messages, but works like a charm!
1a9c380
to
fd3db95
Compare
fd3db95
to
65dc59c
Compare
This PR makes ring2 execve
supervisor run
(aka ring3). This way PID 1 in the workspace issupervisor run
, much like it would be without user namespaces. Hence supervisor can properly do its job as reaper, and the graceful shutdown of tasks is a bit less brittle (#2654).How does it work?
Instead of starting a child process, ring2 now calls setgid/setuid to drop to the Gitpod user (
33333
) and then execve's/proc/self/exe run
, thereby replacing the ring2 process with supervisor run.Why didn't we do this before?
setuid/setgid have a long and difficult history in Go. Go 1.16 introduced
AllThreadsSyscall
which makes setuid/setgid work on all threads without the use of CGO. TLDR; Before Go 1.16 we'd need CGO, but we don't want CGO because supervisor has to run in glibc and muslibc environments. cap - a Go-native port of libcap - supports this feature, and if it's present supports capability-preservingsetuid/setgid
calls without CGO.But wait, Go 1.16 is still in beta?!?
Indeed. That's why leeway now supports choosing a Go version on a package level. Starting with this PR, we compile supervisor with go1.16beta1, and the rest using the Go version we have installed in the dev-environment image. Once Go 1.16 is out of beta (Feb 2021), we'll switch over for all components. Go betas have been really rather stable and I don't expect issues because we build supervisor using Go 1.16. Note golang/go#43149 does not concern us, because only ring2 uses AllThreadsSyscall and ring2 does not use
signal
.How to test
proper-shutdown.txt
in the list of changed files. This file was created when the task stopped properly../zombie & sleep 1 && ps guaxf | grep zombie
... once the zombie parent exitsps guaxf | grep defunct
should not return anything. Previously, the defunct process would still have been around.Screen.Recording.2021-01-05.at.11.22.18.mov
/werft https