Go: cmd/go: Don't put executables in TMPDIR

Created on 31 Jul 2014  Â·  27Comments  Â·  Source: golang/go

by merlin:

By default go will compile things in /tmp and try to run them from there.
This will get denied and fail on a properly configured system where /tmp does not allow
execution.

I can get 
go run ./environ1/environ1.go
fork/exec /tmp/go-build163060459/command-line-arguments/_obj/exe/environ1: permission
denied

/tmp on any securely setup system does not allow execution, hence the
error above.

I found that go support TMPDIR, but I'd rather not set TMPDIR to
~/go/src/tmp and have all temp files go there.
Would it be possible for go to also support GOTEMP to allow setting its
tmpdir and not everything else to something that allows execution?

(I modified my binary to do so for now, but this would be good to
support for all)
FrozenDueToAge Suggested

Most helpful comment

Looking through old cmd/go bugs. Enough people seem to be running into this that my plan is to fix this for Go 1.10: use $GOTMPDIR if present, or else fall back to the operating system temp dir as before.

All 27 comments

Comment 1:

I would prefer not to add another environment variable, especially as other solutions
exits.
For example
env TMPDIR=... go run something
Will work, and can be automated will a shell alias.
More importantly, I believe go run is not the right tool, you should be doing go build,
or go install then running your program.
Interestingly, go test is similarly affected by this issue but you didn't mention it.
That would probably be a way to make a stronger case for your request.

Comment 2:

TMPDIR is the usual way to set the temporary directory on Unix systems, and as Dave
points out you can always make it work.

_Status changed to WorkingAsIntended._

Comment 3 by merlin:

Dave, yes, I know go test is broken too, I just gave one example for the bug.
You can argue TMPDIR is the usual variable, but I can also argue that nothing else
copies/generates stuff there and then tries to run it, except rootkits of course.

Comment 4:

I would be sympathetic to an argument that go run or go test should build executables
somewhere else (but where?).  I'm not sympathetic to the idea that we should introduce
GOTEMP as a synonym for TMPDIR.

Comment 5 by merlin:

Fair enough. For generating executables, making them in $CWD/something (you choose
whether that be .tmp/, .go/, .run/, or anything) would work.

Comment 6:

_Labels changed: added repo-main, release-none, suggested._

_Status changed to Accepted._

Comment 7:

I don't like the idea of generating the test binary in the current directory.
there might already be a test binary there, and we shouldn't overwrite it.
(For example, the developer might put an old binary at the cwd, and then
use go test to verify behavior/performance of the modified version.)
And what if the user are currently in a read-only directory (e.g. code is
in an archival file system, or it's in a read-only snapshot)?
For similar reasons, we shouldn't create the test binary in the source directory.
I still think the solution should be to set $TMPDIR to a place without noexec
setting. Or just use a wrapper script that sets $TMPDIR before executing the
go command.

Comment 8:

The test binary can always be given a unique suffix (a la mktemp) to
avoid collisions.

Comment 9:

that doesn't solve the cwd or source in read-only or noexec file
system problem (for example, a history snapshot.)
For the similar reasons the OP don't want to set $TMPDIR to some
place other than /tmp, I don't want put temporary files in cwd.
(/tmp is a tmpfs, whereas creating files at cwd might actually
get flushed to disk.)

Comment 10:

Out of interest: What systems mount their tmp file systems as noexec? None of mine do
(Debian, OS X, Ununtu).

Comment 11 by merlin:

I can't really speak of other systems, I run debian and /tmp is noexec on all my
systems, but I've not installed debian recently from scratch, so no idea what the
defaults are.
http://www.deb-admin.com/secure-your-tmp-partition/
http://www.debian-administration.org/article/57/Making_/tmp_non-executable
says you should
https://help.ubuntu.com/community/StricterDefaults
also says you should (kinda)
https://bugs.launchpad.net/ubuntu/+source/debian-installer/+bug/304959
shows the debian installer should be fixed to do this, but doesn't yet simply because
/tmp may not be a separate partition (that's actually bogus, but never mind)
http://forums.fedoraforum.org/showthread.php?t=230619
seems to show that /tmp is tmpfs noexec on fedora
Back to the bigger question, how many people does it affect?
I don't have a clear answer for you, but anyone with a system securely setup like this
will not be happy when go fails and asks you to make your system less secure, or move
all tempfiles from all programs that honor TMPDIR to a place other than /tmp when /tmp
is actually where you want those tempfiles to go.
That's why I hacked my binary, or as you point out, I could have a wrapper for go, but
somehow that feels suboptimal, and it should thrive to work out of the box anyway, even
on more secure systems.

I use this workaround

$ mkdir ${GOPATH}/tmp

and in .bashrc

alias go='TMPDIR=${GOPATH}/tmp go'

While this works well, executables in /tmp are quite odd. I've been running /tmp with noexec for ages and go run seems to be the first command that has a problem with this setup.

Then don't use go run, it's only for you programs.

On Fri, 23 Dec 2016, 23:41 Niko E. notifications@github.com wrote:

I use this workaround

$ mkdir ${GOPATH}/tmp

and in .bashrc

alias go='TMPDIR=${GOPATH}/tmp go'

While this works well, executables in /tmp are quite odd. I've been
running /tmp with noexec for ages and go run seems to be the first
command that has a problem with this setup.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/golang/go/issues/8451#issuecomment-268984408, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAcA3C1XGQz1sFB5DLMbfys2mpo53cPks5rK8FygaJpZM4LUyvp
.

Just don't comment, if you got nothing to say.

Where do you suggest for the go command to place the temporary executables?

Sorry, autocorrect confused my message. What I tried to say is go run is only for toy programs.

On 24 Dec. 2016, at 12:12, Niko E. notifications@github.com wrote:

Just don't comment, if you got nothing to say.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

It's not just go run, go test also puts the test binary under $TMPDIR.

$GOPATH/bin would also be an option since go can (probably) write it and it is expected to contain executables (so noexec wont be an issue). As long as the tempfilename is unique and every thing is cleaned up afterwards, I don't see an issue

The problem is precisely there is no guarantee everything is cleanup.

For the case of go run:

Why can not executables be run directly from memory, by using one of the methods shown in this small C example?

@xyproto I suppose that for pure Go executables that could be done in principle. But it would be a great deal of work and the end result would be to fix a problem that people can trivially work around today. It doesn't sound like a productive use of time.

@ianlancetaylor There would also be the added benefit of being able to both mount /tmp as noexec (which might perhaps be more secure) and also speed up go run by not writing to disk. (I assume go run would have to write to disk if /tmp was mounted as noexec).

But I do see your point. It may not be worth the effort. It's hard to imagine a convincing user scenario here.

I run go from windows. Every time I do "go run main.go" my antivirus fires up and scans the file before allowing it to run. This adds a considerable delay. I am loathe to add an antivirus exception to the AppData\Local\Temp folder, but through sheer necessity I had to. Having a configurable temporary build folder would be a big plus.

Having a configurable temporary build folder would be a big plus.

I just run this command (you also need to create C:\tmp directory)

set TMP=C:\tmp

before running "go run main.go", and Go creates all executables in C:\tmp. Is that what you want?

Alex

Thanks. That will actually work. I guess I have to do it manually in a single terminal so it doesn't affect other programs.

Looking through old cmd/go bugs. Enough people seem to be running into this that my plan is to fix this for Go 1.10: use $GOTMPDIR if present, or else fall back to the operating system temp dir as before.

Change https://golang.org/cl/75475 mentions this issue: cmd/go: prefer $GOTMPDIR over operating system tmp dir for temp files

Was this page helpful?
0 / 5 - 0 ratings

Related issues

OneOfOne picture OneOfOne  Â·  3Comments

enoodle picture enoodle  Â·  3Comments

natefinch picture natefinch  Â·  3Comments

lkarlslund picture lkarlslund  Â·  3Comments

dominikh picture dominikh  Â·  3Comments