Skip to content
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

runtime: Go programs should be able to drop capabilities #13838

Closed
mbenkmann opened this issue Jan 6, 2016 · 6 comments
Closed

runtime: Go programs should be able to drop capabilities #13838

mbenkmann opened this issue Jan 6, 2016 · 6 comments
Milestone

Comments

@mbenkmann
Copy link

In issue #1435 it has been suggested to use capabilities as a workaround to achieve security. To make this workaround viable, internal threads created by the Go runtime before main() even starts need to drop all capabilities, because the user thread running main() is not permitted to do that.

In addition there should probably be a mask in the runtime package that determines which capabilities are preserved when the Go runtime creates new threads. And for convenience there should be a function to drop capabilities in the current thread (although this can be done with cgo and is therefore secondary)
The idea is to make the following work

func main() {
    runtime.LockOSThread() // stay on this thread to make sure we don't lose capabilities
    runtime.SetInheritedCapabilities(0) // all threads created from now on will drop ALL capabilities

   // Do privileged stuff such as chroot or bind to privileged port
   // This may start new Goroutines and thereby new threads, but due to
   // runtime.SetInheritedCapabilities(0) these threads will drop all capabilities immediately,
   // so no privileged threads will be created

  runtime.DropAllCapabilities()  // convenience function. Could be done with C.capset(...)

  // At this point no privileged threads exist anymore
  runtime.UnlockOSThread() // now it doesn't matter on which thread we execute
 }
@minux
Copy link
Member

minux commented Jan 6, 2016 via email

@mbenkmann
Copy link
Author

@minux:

  1. This issue in its barest form does not introduce any API. It just says that internal threads such as the GC should drop privileges. That's a no brainer. And it's trivial to implement.
  2. The original issue with setuid() and setgid() is very hard and ugly to fix because it needs some kind of signalling mechanism and support within all threads for these changes, just the way libc does it. My suggested additions to runtime are way easier because they only affect future threads.
  3. If all 3 runtime functions I suggest are added, this would allow writing Go programs that are secure and portable with no need for cgo.

@ianlancetaylor ianlancetaylor added this to the Go1.7 milestone Jan 6, 2016
@ianlancetaylor ianlancetaylor changed the title Go runtime internal threads should drop capabilities runtime: Go programs should be able to drop capabilities Jan 6, 2016
@rsc
Copy link
Contributor

rsc commented Jan 6, 2016

Duplicate of #1435.

@rsc rsc closed this as completed Jan 6, 2016
@rsc
Copy link
Contributor

rsc commented Jan 6, 2016

I marked this as a duplicate of #1435 and I tagged #1435 for consideration in Go 1.7. The runtime package is certainly the wrong place for this API. Perhaps the os package, but even there I worry that it's too customized for Linux. The right fix really is to make syscall.Setuid/syscall.Setgid behave as one would expect. The discussion on #1435 explains why this is difficult, but it's still the right fix.

@ianlancetaylor
Copy link
Contributor

For the record, I think the right place for specific control of Linux capabilities (the Go equivalent of cap_get_proc/cap_set_proc) is golang.org/x/sys/unix.

@rsc
Copy link
Contributor

rsc commented Jan 6, 2016 via email

@golang golang locked and limited conversation to collaborators Jan 7, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants