Skip to content
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

runtime: buildmode=c-shared libraries on Linux all reuse AT_RANDOM bits from aux vector #16017

Closed
jamesr opened this issue Jun 9, 2016 · 3 comments

Comments

@jamesr
Copy link

jamesr commented Jun 9, 2016

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?

go version devel +f3689d1 Wed Jun 8 20:35:53 2016 +0000 linux/amd64

  1. What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/usr/local/google/home/jamesr/gocode"
GORACE=""
GOROOT="/usr/local/google/home/jamesr/go"
GOTOOLDIR="/usr/local/google/home/jamesr/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build474773350=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

  1. What did you do?
    If possible, provide a recipe for reproducing the error.
    A complete runnable program is good.
    A link on play.golang.org is best.

If any number of go libraries built in buildmode=c-shared are loaded into the same program they will all seed their random number generator using the same 16 bytes from the initial processes AT_RANDOM entry in the auxiliary vector.

  1. What did you expect to see?

Shared libraries seeding themselves with different values either by calling the host libc's rand() when loaded from a C shared library or by reading from /dev/urandom explicitly.

  1. What did you see instead?

glibc's dlopen() passes a pointer to the hosting process' argc which is propagated through to the src/runtime argument parsing routine which identifies the AT_RANDOM tagged data in the auxv section and populates startupRandomData bytes here:

https://go.googlesource.com/go/+/master/src/runtime/os_linux.go#185

which is then seeded into the runtime's random number generator (mixed in with a call to nanotime() which will very likely but not always differ from library to library).

In practice this means multiple shared libraries in the same address space will have less initial randomness than might be expected. This should not cause problems in properly written applications but may be surprising.

@randall77
Copy link
Contributor

I don't see how this could cause a problem. These random numbers are only used by the runtime, they are not provided to the application.

The application might see them indirectly, via map iterator order, scheduling decisions, etc. But if anyone is depending on these things being different/independent across shared libraries, they are depending on implementation details not promised by Go.

@ianlancetaylor ianlancetaylor changed the title Buildmode=c-shared libraries on Linux all reuse AT_RANDOM bits from aux vector runtime: buildmode=c-shared libraries on Linux all reuse AT_RANDOM bits from aux vector Jun 9, 2016
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Jun 9, 2016
@jamesr
Copy link
Author

jamesr commented Jun 9, 2016

I don't see how this could cause a problem.

By that reasoning, why seed the runtime with random bits from the auxv in any case? The runtime would initialize faster if it did not copy these bytes out of the auxv and seed its PRNG with it.

I agree this shouldn't break any correct program or cause any obvious issues, but it may cause subtle issues. For example a program using many shared libraries could behave more poorly than expected due to the runtimes in each shared library having correlated rather than independent initial random state. This appears to be an artifact of the way the code is structured rather than a deliberate choice so seems worth examining in more detail.

@randall77
Copy link
Contributor

The AT_RANDOM data is only used to seed the hash function for maps. We do that to make the hash function unpredictable, which helps prevent hash flooding attacks. That works equally well if one or twelve shared libraries use the same seed. As far as I can see, there's no issue here.

@golang golang locked and limited conversation to collaborators Jun 9, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants