Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
syscall: Exec of a setuid root binary sometimes doesn't end up as root on Linux #19546
Comments
bradfitz
changed the title from
syscall.Exec of a setuid root binary sometimes doesn't end up as root
to
syscall: Exec of a setuid root binary sometimes doesn't end up as root on Linux
Mar 14, 2017
bradfitz
added this to the Unplanned milestone
Mar 14, 2017
bradfitz
added
the
NeedsInvestigation
label
Mar 14, 2017
|
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 |
gopherbot
commented
Jun 15, 2017
|
CL https://golang.org/cl/43713 mentions this issue. |
gopherbot
commented
Jun 15, 2017
|
CL https://golang.org/cl/45991 mentions this issue. |
chipaca commentedMar 14, 2017
•
Edited 1 time
-
chipaca
Mar 14, 2017
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 1000lines, indicating that the new process sometimes was not running as root.Notes
a_preproducer that only usespthreads, no go involved.pthreadsbug: commenting out theimport "C"line and building a “pure” Go binary reproduces the same issue (plus a lot of spam because of an unhandledEAGAINfromclone(2)).