{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/13838","labels_url":"https://api.github.com/repos/golang/go/issues/13838/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/13838/comments","events_url":"https://api.github.com/repos/golang/go/issues/13838/events","html_url":"https://github.com/golang/go/issues/13838","id":125143568,"number":13838,"title":"runtime: Go programs should be able to drop capabilities","user":{"login":"mbenkmann","id":6864958,"avatar_url":"https://avatars.githubusercontent.com/u/6864958?v=3","gravatar_id":"","url":"https://api.github.com/users/mbenkmann","html_url":"https://github.com/mbenkmann","followers_url":"https://api.github.com/users/mbenkmann/followers","following_url":"https://api.github.com/users/mbenkmann/following{/other_user}","gists_url":"https://api.github.com/users/mbenkmann/gists{/gist_id}","starred_url":"https://api.github.com/users/mbenkmann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbenkmann/subscriptions","organizations_url":"https://api.github.com/users/mbenkmann/orgs","repos_url":"https://api.github.com/users/mbenkmann/repos","events_url":"https://api.github.com/users/mbenkmann/events{/privacy}","received_events_url":"https://api.github.com/users/mbenkmann/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/31","html_url":"https://github.com/golang/go/milestones/Go1.7","labels_url":"https://api.github.com/repos/golang/go/milestones/31/labels","id":1414133,"number":31,"title":"Go1.7","description":"","creator":{"login":"bradfitz","id":2621,"avatar_url":"https://avatars.githubusercontent.com/u/2621?v=3","gravatar_id":"","url":"https://api.github.com/users/bradfitz","html_url":"https://github.com/bradfitz","followers_url":"https://api.github.com/users/bradfitz/followers","following_url":"https://api.github.com/users/bradfitz/following{/other_user}","gists_url":"https://api.github.com/users/bradfitz/gists{/gist_id}","starred_url":"https://api.github.com/users/bradfitz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bradfitz/subscriptions","organizations_url":"https://api.github.com/users/bradfitz/orgs","repos_url":"https://api.github.com/users/bradfitz/repos","events_url":"https://api.github.com/users/bradfitz/events{/privacy}","received_events_url":"https://api.github.com/users/bradfitz/received_events","type":"User","site_admin":false},"open_issues":67,"closed_issues":8,"state":"open","created_at":"2015-11-16T16:57:07Z","updated_at":"2016-01-06T14:50:44Z","due_on":"2016-07-31T07:00:00Z","closed_at":null},"comments":4,"created_at":"2016-01-06T09:46:01Z","updated_at":"2016-01-06T14:52:42Z","closed_at":"2016-01-06T14:50:44Z","body":"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.\r\n\r\nIn 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)\r\nThe idea is to make the following work\r\n\r\n```\r\nfunc main() {\r\n    runtime.LockOSThread() // stay on this thread to make sure we don't lose capabilities\r\n    runtime.SetInheritedCapabilities(0) // all threads created from now on will drop ALL capabilities\r\n \r\n   // Do privileged stuff such as chroot or bind to privileged port\r\n   // This may start new Goroutines and thereby new threads, but due to\r\n   // runtime.SetInheritedCapabilities(0) these threads will drop all capabilities immediately,\r\n   // so no privileged threads will be created\r\n\r\n  runtime.DropAllCapabilities()  // convenience function. Could be done with C.capset(...)\r\n\r\n  // At this point no privileged threads exist anymore\r\n  runtime.UnlockOSThread() // now it doesn't matter on which thread we execute\r\n }\r\n```"},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/169343896","html_url":"https://github.com/golang/go/issues/13838#issuecomment-169343896","issue_url":"https://api.github.com/repos/golang/go/issues/13838","id":169343896,"user":{"login":"rsc","id":104030,"avatar_url":"https://avatars.githubusercontent.com/u/104030?v=3","gravatar_id":"","url":"https://api.github.com/users/rsc","html_url":"https://github.com/rsc","followers_url":"https://api.github.com/users/rsc/followers","following_url":"https://api.github.com/users/rsc/following{/other_user}","gists_url":"https://api.github.com/users/rsc/gists{/gist_id}","starred_url":"https://api.github.com/users/rsc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rsc/subscriptions","organizations_url":"https://api.github.com/users/rsc/orgs","repos_url":"https://api.github.com/users/rsc/repos","events_url":"https://api.github.com/users/rsc/events{/privacy}","received_events_url":"https://api.github.com/users/rsc/received_events","type":"User","site_admin":false},"created_at":"2016-01-06T14:52:42Z","updated_at":"2016-01-06T14:52:42Z","body":"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."}}