-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
syscall: Exec of a setuid root binary sometimes doesn't end up as root on Linux #19546
Comments
So, we tracked this down to a couple of kernel races which have existed in the kernel since ~2009. |
I'm glad you sorted this out. Can you explain what needs to be locked to avoid the problem? The basic sequence for executing another process in Go is, of course,
Go programs also call |
There needs to be no The problem doesn't arise for the fork-then-exec, or at least I wasn't able to reproduce it via forking, possibly because there is in go a lock for forking already (and possibly the data structures that end up with the wrong data in the race get reset by the fork -- or something else entirely! I don't know). |
Thanks. It's not entirely obvious to me how to fix this. It's easy to acquire a lock before |
When one thread successfully execves all other threads are dead, and futexes are cleaned up on thread exit (this includes execve). Go's hand-rolled locks use futexes afaik, and on the cgo side |
(further: pthread mutexes and condition variables are documented as not preserved on execve) |
I don't understand how a futex could be cleaned up on thread exit, given that Go is using the system call directly, and is not calling the glibc functions. But there is a lot I don't know. You offered to write a patch earlier--that is probably the best way to go if you have the time. Thanks. |
Yup! I've got a few things in my queue but should be able to get to it before EOW. |
OK, I've got a patch. Still needs some work (especially around splitting some bits so only Linux does this dance). Should I push it at gerrit for discussion? (I'm pretty certain it'll fail review as it stands) |
Sending it to Gerrit is fine. Thanks. |
https://go-review.googlesource.com/43713 runtime, syscall: Workaround for bug in linux's execve |
CL https://golang.org/cl/43713 mentions this issue. |
CL https://golang.org/cl/45991 mentions this issue. |
This is a runtime version of sync.RWMutex that can be used by code in the runtime package. The type is not quite the same, in that the zero value is not valid. For future use by CL 43713. Updates #19546 Change-Id: I431eb3688add16ce1274dab97285f555b72735bf Reviewed-on: https://go-review.googlesource.com/45991 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Austin Clements <austin@google.com>
What version of Go are you using (
go version
)?What operating system and processor architecture are you using (
go env
)?What did you do?
https://gist.github.com/chipaca/806c90d96c437444f27f45a83d00a813
and running
(it's a race, so add more 9s if your machine is zippy)
What did you expect to see?
nothing, meaning the new process run as root.
What did you see instead?
a variable number of
GOT 1000
lines, indicating that the new process sometimes was not running as root.Notes
a_p
reproducer that only usespthreads
, no go involved.pthreads
bug: commenting out theimport "C"
line and building a “pure” Go binary reproduces the same issue (plus a lot of spam because of an unhandledEAGAIN
fromclone(2)
).The text was updated successfully, but these errors were encountered: