diff --git a/cmd/containerd/main.go b/cmd/containerd/main.go index 2541dfd56..10bde45bd 100644 --- a/cmd/containerd/main.go +++ b/cmd/containerd/main.go @@ -21,8 +21,13 @@ import ( "os" "github.com/containerd/containerd/cmd/containerd/command" + "github.com/containerd/containerd/pkg/seed" ) +func init() { + seed.WithTimeAndRand() +} + func main() { app := command.App() if err := app.Run(os.Args); err != nil { diff --git a/cmd/ctr/main.go b/cmd/ctr/main.go index 9cb81a8b2..cf72de28e 100644 --- a/cmd/ctr/main.go +++ b/cmd/ctr/main.go @@ -21,11 +21,16 @@ import ( "os" "github.com/containerd/containerd/cmd/ctr/app" + "github.com/containerd/containerd/pkg/seed" "github.com/urfave/cli" ) var pluginCmds = []cli.Command{} +func init() { + seed.WithTimeAndRand() +} + func main() { app := app.New() app.Commands = append(app.Commands, pluginCmds...) diff --git a/pkg/seed/seed.go b/pkg/seed/seed.go new file mode 100644 index 000000000..4a5829a8e --- /dev/null +++ b/pkg/seed/seed.go @@ -0,0 +1,38 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package seed + +import ( + "math/rand" + "time" +) + +// WithTimeAndRand seeds the global math rand generator with nanoseconds +// XOR'ed with a crypto component if available for uniqueness. +func WithTimeAndRand() { + var ( + b [4]byte + u int64 + ) + + tryReadRandom(b[:]) + + // Set higher 32 bits, bottom 32 will be set with nanos + u |= (int64(b[0]) << 56) | (int64(b[1]) << 48) | (int64(b[2]) << 40) | (int64(b[3]) << 32) + + rand.Seed(u ^ time.Now().UnixNano()) +} diff --git a/pkg/seed/seed_linux.go b/pkg/seed/seed_linux.go new file mode 100644 index 000000000..9f1ef74bb --- /dev/null +++ b/pkg/seed/seed_linux.go @@ -0,0 +1,24 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package seed + +import "golang.org/x/sys/unix" + +func tryReadRandom(p []byte) { + // Ignore errors, just decreases uniqueness of seed + unix.Getrandom(p, unix.GRND_NONBLOCK) +} diff --git a/pkg/seed/seed_other.go b/pkg/seed/seed_other.go new file mode 100644 index 000000000..30ba9e9e4 --- /dev/null +++ b/pkg/seed/seed_other.go @@ -0,0 +1,28 @@ +// +build !linux + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package seed + +import ( + "crypto/rand" + "io" +) + +func tryReadRandom(p []byte) { + io.ReadFull(rand.Reader, p) +}