Is this really true? (Go 'unable to reliably change their UID once started for goroutines' ?)

341 views
Skip to first unread message

Russtopia

unread,
Dec 16, 2020, 3:51:56 AM12/16/20
to golang-nuts
The experimental 'Project Gemini' [https://gemini.circumlunar.space/] has a few servers written in Go, and one in particular [https://tildegit.org/solderpunk/molly-brown] makes this claim:

It is very important to be aware that programs written in Go are unable to reliably change their UID once started, due to how goroutines are implemented on unix systems. As an unavoidable consequence of this, CGI processes started by Molly Brown are run as the same user as the server process.

Surely this is not true? This claim seems to suggest a big security issue that I would hope can be refuted by Go experts -- perhaps the maintainers of the molly-brown project could be guided to a solution so this scary claim could be removed.

I wanted to try out the above server but am hesitant to do so given the above ...

-R.


Russtopia

unread,
Dec 16, 2020, 4:00:26 AM12/16/20
to golang-nuts
My bad ... I see too late that someone already filed an issue with the molly-brown project about this.


Axel Wagner

unread,
Dec 16, 2020, 5:19:38 AM12/16/20
to Russtopia, golang-nuts
Even pre go1.16, while it's true that Setuid/Setgid don't work reliably in a multi-threaded program, I don't think the conclusions they draw are correct. You can still start CGI processes as a different user: https://golang.org/pkg/os/exec/#Cmd.SysProcAttr
Also, while I'm not totally sure, I think before `main` starts, a Go process is effectively single-threaded, so if called from `init` they might be safe?
Lastly, there are of course workarounds you can do with helper-processes to drop privileges.

It certainly is possible to run a subprocess as a different user. It might not be terribly convenient and you definitely have to deviate from the traditional fork/change process state/exec" model. But it's also not beyond feasible.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAN4yCu8jcGfx0tuW7YL3itVh-k1YYxYTSRAaB_bCLdNBce_RpA%40mail.gmail.com.

Kevin Chadwick

unread,
Dec 16, 2020, 8:11:55 AM12/16/20
to golang-nuts
>> It is very important to be aware that programs written in Go are unable to
>> reliably change their UID once started, due to how goroutines are implemented
>> on unix systems. As an unavoidable consequence of this, CGI processes started
>> by Molly Brown are run as the same user as the server process.

> It certainly is possible to run a subprocess as a different user. It might not
> be terribly convenient and you definitely have to deviate from the traditional
> fork/change process state/exec" model. But it's also not beyond feasible.

The statement is quite far off practically but pretty close for arguments sake,
if you understand the details. Probably written to avoid criticism to some
degree. It's worth pointing out that whilst running go processes as different
users is certainly a security benefit if designed right and not over used. It is
less important than for daemons written in c.

s/'once started'/'post go command/'

I had read that OpenBSD was unaffected but I'm not sure whether that is true or
whether I am confusing two bugs. If that is true then.

s/'unix'/'linux'/

I Run server processes as many users all started from a master process on
OpenBSD. I just setup the processes before using the go command, to be certain.
Currently they all run as the same process group still. I like that as the
master dying takes down all the processes. So, what I am doing curently is
certainly different to forking children on demand but then I believe that would
be less efficient than using go routines anyway.

I use sh scripts to bootstrap separate process groups where needed for
simplicity and you could always use a sh script to fork processes, if you really
wanted and didn't mind bringing in a shell. Or write a forking tool. That would
be pointless in my experience of using go though.

Ian Lance Taylor

unread,
Dec 16, 2020, 4:44:03 PM12/16/20
to Kevin Chadwick, golang-nuts
To the best of my knowledge this issue is specific to GNU/Linux. And
on GNU/Linux the issue will be fixed in the upcoming 1.16 release.
See https://golang.org/issue/1435.

Ian
Reply all
Reply to author
Forward
0 new messages