Security Issue: Runtime Compiled with Full Filepaths in Debug Symbols

509 views
Skip to first unread message

Joshua Liebow-Feeser

unread,
Jan 8, 2014, 12:25:57 AM1/8/14
to golan...@googlegroups.com
It appears as though the debug symbols compiled into the Go runtime reveal the full filepaths of the source that it was compiled from originally.

On my machine (go1.0.2 installed as a Debian Wheezy package), running runtime/debug.Stack() returns:

/home/josh/tmp2/tmp.go:13 (0x400c5f)
    main: fmt.Println(string(debug.Stack()))
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:244 (0x40cf40)
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:271 (0x40cfe3)

The first line (/home/josh/tmp2/tmp.go:13) corresponds to the main function that I wrote (/home/josh is my home directory). However, the last two lines (with the paths /home/michael/DPKG/golang/src/pkg/runtime/proc.c) appear to be the paths at which proc.c lived during the original compilation of the runtime (Michael Stapelberg is listed as the maintainer of the Debian Wheezy package, so this seems consistent).

Maybe this isn't such a big deal (and Go certainly requires debug symbols for most normal functioning, so maybe everybody knew this going in), but it seems sort of bad to leak the names of the people who originally compiled the runtime, or whatever other sort of information could potentially be gleaned through filepaths.

Dmitry Vyukov

unread,
Jan 8, 2014, 12:28:46 AM1/8/14
to Joshua Liebow-Feeser, golang-nuts
Next time Michael need to set GOROOT_FINAL when building Go.

Ian Lance Taylor

unread,
Jan 8, 2014, 12:29:29 AM1/8/14
to Joshua Liebow-Feeser, golang-nuts
I think you'll find that other compilers behave this way as well.

Ian

minux

unread,
Jan 8, 2014, 12:31:00 AM1/8/14
to Joshua Liebow-Feeser, golang-nuts
go build -ldflags -s used to strip this out but Go 1.2 runtime requires some function data to be present
to unwind the stack, so in the later stage of Go 1.2 development, -s functionality is changed to preserve
the pclntab (PC to line number table).

I think for Go 1.3, it makes sense to make -s strip the directory part of filenames in the Go executable.
But I don't know if we can reach consensus on this issue.
(However, I'd emphasize that stripping the paths doesn't help much from a security standpoint.)

Dave Cheney

unread,
Jan 8, 2014, 12:36:10 AM1/8/14
to minux, Joshua Liebow-Feeser, golang-nuts
I am not supportive of altering the paths printed in panics and stack traces. 

This information has been critical to diagnosing countless bug reports where users have multiple versions of go installed on their machines. 

I do no view this as a security issue. 
--
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.
For more options, visit https://groups.google.com/groups/opt_out.

Joshua Liebow-Feeser

unread,
Jan 8, 2014, 12:36:47 AM1/8/14
to golan...@googlegroups.com, Joshua Liebow-Feeser
I think this approach sounds to be the cleanest. Using -ldflags -s is probably untenable for releases since people expect all of the normal reflection and debugging to work properly. GOROOT_FINAL gets around the privacy issue without making any other major changes.

minux

unread,
Jan 8, 2014, 12:38:09 AM1/8/14
to Joshua Liebow-Feeser, golang-nuts
On Wed, Jan 8, 2014 at 12:36 AM, Joshua Liebow-Feeser <josh...@gmail.com> wrote:
I think this approach sounds to be the cleanest. Using -ldflags -s is probably untenable for releases since people expect all of the normal reflection and debugging to work properly. GOROOT_FINAL gets around the privacy issue without making any other major changes.
just note that GOROOT_FINAL only changes paths in standard packages, not your packages.

Joshua Liebow-Feeser

unread,
Jan 8, 2014, 12:40:03 AM1/8/14
to golan...@googlegroups.com, Joshua Liebow-Feeser
Sure, sure. I meant that it sounds good to use for package maintainers and others who are building Go from source to be distributed (so that they don't leak private information in the runtime and other pre-compiled packages).

Joshua Liebow-Feeser

unread,
Jan 8, 2014, 12:40:37 AM1/8/14
to golan...@googlegroups.com, minux, Joshua Liebow-Feeser
Are you not supportive only of removing them, or also of altering them using GOROOT_FINAL?

Dave Cheney

unread,
Jan 8, 2014, 12:43:10 AM1/8/14
to Joshua Liebow-Feeser, golan...@googlegroups.com, minux, Joshua Liebow-Feeser
I don't want the debug information touched in any way. 

minux

unread,
Jan 8, 2014, 12:46:01 AM1/8/14
to Dave Cheney, Joshua Liebow-Feeser, golan...@googlegroups.com
On Wed, Jan 8, 2014 at 12:43 AM, Dave Cheney <da...@cheney.net> wrote:
I don't want the debug information touched in any way. 
about a slightly related issue, do you support that we use some method to compress those
strings only intended for debugging? I think that might buy us some binary size savings.
Though I haven't thought any details.

Dave Cheney

unread,
Jan 8, 2014, 12:53:27 AM1/8/14
to minux, Joshua Liebow-Feeser, golan...@googlegroups.com
As long as the stack trace isn't affected you can store them in cuneiform for all
I care :)

I don't think the way we encode the dwarf information is really the point of this thread. 

Dave Cheney

unread,
Jan 8, 2014, 1:11:14 AM1/8/14
to minux, Joshua Liebow-Feeser, golan...@googlegroups.com
I would like to apologise for the tone of my last reply. It was not appropriate and I am sorry. 

Keith Randall

unread,
Jan 8, 2014, 7:28:47 PM1/8/14
to golan...@googlegroups.com, minux, Joshua Liebow-Feeser
I'm a big fan of byte-by-byte reproducibility.  If I build the go runtime on my machine and you build it on yours, we should get the same result.  Including path components below GOROOT breaks that guarantee.  If I need a flag to make that happen, that's ok, but there has to be a way.

Joshua Liebow-Feeser

unread,
Jan 8, 2014, 7:33:23 PM1/8/14
to golan...@googlegroups.com, minux, Joshua Liebow-Feeser
I agree that byte-by-byte reproducibility is a good goal to have, and I agree that including local filepath components below GOROOT breaks that. That said: What should replace it? Do we just call the root "/go" or "go" or something? So you'd have "/go/src/..." or "go/src/..."?

Keith Randall

unread,
Jan 9, 2014, 7:17:29 PM1/9/14
to golan...@googlegroups.com, minux, Joshua Liebow-Feeser
I'd start below the "go", so "src/pkg/" and so on.  "go" gives no information.  In other words, relative paths from GOROOT.
I often rename the "go" directory to the task I'm working on, like "go-gc" or "issueXXX".

Joshua Liebow-Feeser

unread,
Jan 9, 2014, 8:19:32 PM1/9/14
to golan...@googlegroups.com, minux, Joshua Liebow-Feeser
That sounds reasonable.

Maxim Khitrov

unread,
Jan 9, 2014, 8:29:12 PM1/9/14
to Keith Randall, golang-nuts, minux, Joshua Liebow-Feeser
Using "GOROOT/..." and "GOPATH/..." prefixes might be helpful in
identifying where the original source file was located. I agree that
exposing paths outside of the GOROOT and GOPATH trees is not good for
both privacy and byte-by-byte reproducibility reasons.

Sebastien Binet

unread,
Jan 10, 2014, 2:33:08 AM1/10/14
to Maxim Khitrov, Keith Randall, golang-nuts, minux, Joshua Liebow-Feeser
On Fri, Jan 10, 2014 at 2:29 AM, Maxim Khitrov <m...@mxcrypt.com> wrote:
> Using "GOROOT/..." and "GOPATH/..." prefixes might be helpful in
> identifying where the original source file was located. I agree that
> exposing paths outside of the GOROOT and GOPATH trees is not good for
> both privacy and byte-by-byte reproducibility reasons.

why not got the extra last mile and directly display: "${GOROOT}/..."
and "${GOPATH}/..."
?
that way, tools scraping outputs of such traces wouldn't be broken
(provided they run inside a sane environment)
and easy copy-paste would still work.

-s

Joshua Liebow-Feeser

unread,
Jan 10, 2014, 4:10:39 AM1/10/14
to golan...@googlegroups.com, Maxim Khitrov, Keith Randall, minux, Joshua Liebow-Feeser
I see where you're coming from, but I feel like that places too much emphasis on features specific to certain shells on certain systems (namely, shells on unix systems that can handle the '${}' syntax). Plus, even on the right systems, that could cause very mysterious bugs if you wrote scripts not expecting to get variables injected into your execution. Further, even if you /did/ expect this, reasoning about how variables and values interact in shells and shell scripts can be /very/ difficult, and having spent a large amount of time confused by it in my own shell scripts, I'm hesitant to wish it on others.

Russ Cox

unread,
Jan 14, 2014, 10:21:28 AM1/14/14
to Joshua Liebow-Feeser, golang-nuts, Maxim Khitrov, Keith Randall, minux
Including the actual full paths was an explicit design decision, not an accident. It means that when you get a crash, or you are running the program in a debugger, the source paths recorded are 100% correct. They do not need additional interpretation.

To expand on what Ian said, gcc also records full path information, but by default gdb shows only the path name sent to the compiler. In general, if you are in /home/you and you run gcc subdir/x.c, gcc records the full path /home/you/subdir/x.c but gdb only shows subdir/x.c. When we compile the C programs in the Go toolchain, we pass gcc an absolute path to the source file precisely to get gdb to show it (most of the time; gdb is subtle and quick to anger).

Byte-for-byte reproducibility across different build directories is nice, but even nicer is having accurate path information in the stack traces when your program crashes, and the two are inherently in conflict. We opted for the latter.

As has been pointed out, if you want a different path to show up in a distributed package or binary, that's already possible: set GOROOT_FINAL during the build. Note that GOROOT_FINAL is not working in current tip, due to in-progress changes to the object file format, but it worked fine in Go 1, 1.1, and 1.2, and it will work again for Go 1.3.

Russ

brainman

unread,
Jan 14, 2014, 8:33:30 PM1/14/14
to golan...@googlegroups.com, Joshua Liebow-Feeser, Maxim Khitrov, Keith Randall, minux
On Wednesday, 15 January 2014 02:21:28 UTC+11, Russ Cox wrote:

> ... if you want a different path to show up in a distributed package or binary, that's already possible: set GOROOT_FINAL during the build. ...

FWIW, this is broken on windows (https://code.google.com/p/go/issues/detail?id=5458).

Alex

RickyS

unread,
Jan 16, 2014, 3:16:15 AM1/16/14
to golan...@googlegroups.com
Is there a good reason for the heap to be executable?

Jan Mercl

unread,
Jan 16, 2014, 4:02:35 AM1/16/14
to RickyS, golang-nuts
On Thu, Jan 16, 2014 at 9:16 AM, RickyS <rickys...@gmail.com> wrote:
> Is there a good reason for the heap to be executable?

In the general case it is not. In one special case (Windows) it is, IIRC.

-j
Reply all
Reply to author
Forward
0 new messages