Skip to content

Commit

Permalink
Stop using math/rand.Read and rand.Seed (deprecated in Go 1.20)
Browse files Browse the repository at this point in the history
From golangci-lint:

> SA1019: rand.Read has been deprecated since Go 1.20 because it
>shouldn't be used: For almost all use cases, crypto/rand.Read is more
>appropriate. (staticcheck)

> SA1019: rand.Seed has been deprecated since Go 1.20 and an alternative
>has been available since Go 1.0: Programs that call Seed and then expect
>a specific sequence of results from the global random source (using
>functions such as Int) can be broken when a dependency changes how
>much it consumes from the global random source. To avoid such breakages,
>programs that need a specific result sequence should use
>NewRand(NewSource(seed)) to obtain a random generator that other
>packages cannot access. (staticcheck)

See also:

- https://pkg.go.dev/math/rand@go1.20#Read
- https://pkg.go.dev/math/rand@go1.20#Seed

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
(cherry picked from commit d8b68e3)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
AkihiroSuda authored and thaJeztah committed Aug 28, 2023
1 parent 70dc11a commit 81fa937
Show file tree
Hide file tree
Showing 17 changed files with 80 additions and 29 deletions.
2 changes: 1 addition & 1 deletion archive/compression/compression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
"bytes"
"compress/gzip"
"context"
"crypto/rand"
"io"
"math/rand"
"os"
"path/filepath"
"runtime"
Expand Down
3 changes: 2 additions & 1 deletion cmd/containerd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import (
"os"

"github.com/containerd/containerd/cmd/containerd/command"
"github.com/containerd/containerd/pkg/seed"
"github.com/containerd/containerd/pkg/seed" //nolint:staticcheck // Global math/rand seed is deprecated, but still used by external dependencies
)

func init() {
//nolint:staticcheck // Global math/rand seed is deprecated, but still used by external dependencies
seed.WithTimeAndRand()
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/ctr/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ import (
"os"

"github.com/containerd/containerd/cmd/ctr/app"
"github.com/containerd/containerd/pkg/seed"
"github.com/containerd/containerd/pkg/seed" //nolint:staticcheck // Global math/rand seed is deprecated, but still used by external dependencies
"github.com/urfave/cli"
)

var pluginCmds = []cli.Command{}

func init() {
//nolint:staticcheck // Global math/rand seed is deprecated, but still used by external dependencies
seed.WithTimeAndRand()
}

Expand Down
4 changes: 2 additions & 2 deletions content/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (
"errors"
"fmt"
"io"
"math/rand"
"sync"
"time"

"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/pkg/randutil"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
Expand Down Expand Up @@ -113,7 +113,7 @@ func OpenWriter(ctx context.Context, cs Ingester, opts ...WriterOpt) (Writer, er
// error or abort. Requires asserting for an ingest manager

select {
case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))):
case <-time.After(time.Millisecond * time.Duration(randutil.Intn(retry))):
if retry < 2048 {
retry = retry << 1
}
Expand Down
4 changes: 2 additions & 2 deletions content/local/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"fmt"
"io"
"math/rand"
"os"
"path/filepath"
"strconv"
Expand All @@ -32,6 +31,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/filters"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/pkg/randutil"
"github.com/sirupsen/logrus"

"github.com/opencontainers/go-digest"
Expand Down Expand Up @@ -473,7 +473,7 @@ func (s *store) Writer(ctx context.Context, opts ...content.WriterOpt) (content.
lockErr = nil
break
}
time.Sleep(time.Millisecond * time.Duration(rand.Intn(1<<count)))
time.Sleep(time.Millisecond * time.Duration(randutil.Intn(1<<count)))
}

if lockErr != nil {
Expand Down
5 changes: 3 additions & 2 deletions content/local/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import (
"bufio"
"bytes"
"context"
"crypto/rand"
_ "crypto/sha256" // required for digest package
"fmt"
"io"
"math/rand"
"os"
"path/filepath"
"reflect"
Expand All @@ -35,6 +35,7 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/content/testsuite"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/pkg/randutil"
"github.com/containerd/containerd/pkg/testutil"

"github.com/opencontainers/go-digest"
Expand Down Expand Up @@ -268,7 +269,7 @@ func generateBlobs(t checker, nblobs, maxsize int64) map[digest.Digest][]byte {
blobs := map[digest.Digest][]byte{}

for i := int64(0); i < nblobs; i++ {
p := make([]byte, rand.Int63n(maxsize))
p := make([]byte, randutil.Int63n(maxsize))

if _, err := rand.Read(p); err != nil {
t.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion diff/walking/differ.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ package walking

import (
"context"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"io"
"math/rand"
"time"

"github.com/containerd/containerd/archive"
Expand Down
2 changes: 1 addition & 1 deletion leases/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
package leases

import (
"crypto/rand"
"encoding/base64"
"fmt"
"math/rand"
"time"
)

Expand Down
4 changes: 2 additions & 2 deletions mount/losetup_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ package mount
import (
"errors"
"fmt"
"math/rand"
"os"
"strings"
"syscall"
"time"
"unsafe"

"github.com/containerd/containerd/pkg/randutil"
"golang.org/x/sys/unix"
)

Expand Down Expand Up @@ -163,7 +163,7 @@ func setupLoop(backingFile string, param LoopParams) (*os.File, error) {
// with EBUSY when trying to set it up.
if strings.Contains(err.Error(), ebusyString) {
// Fallback a bit to avoid live lock
time.Sleep(time.Millisecond * time.Duration(rand.Intn(retry*10)))
time.Sleep(time.Millisecond * time.Duration(randutil.Intn(retry*10)))
continue
}
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/cri/util/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package util

import (
"crypto/rand"
"encoding/hex"
"math/rand"
)

// GenerateID generates a random unique id.
Expand Down
13 changes: 4 additions & 9 deletions pkg/kmutex/kmutex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,16 @@ package kmutex

import (
"context"
"math/rand"
"runtime"
"strconv"
"sync"
"testing"
"time"

"github.com/containerd/containerd/pkg/seed"
"github.com/containerd/containerd/pkg/randutil"
"github.com/stretchr/testify/assert"
)

func init() {
seed.WithTimeAndRand()
}

func TestBasic(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -60,7 +55,7 @@ func TestBasic(t *testing.T) {
waitLock = true
break
}
time.Sleep(time.Duration(rand.Int63n(100)) * time.Millisecond)
time.Sleep(time.Duration(randutil.Int63n(100)) * time.Millisecond)
}
assert.Equal(t, waitLock, true)
}
Expand Down Expand Up @@ -130,7 +125,7 @@ func TestMultileAcquireOnKeys(t *testing.T) {
for i := 0; i < nloops; i++ {
km.Lock(ctx, key)

time.Sleep(time.Duration(rand.Int63n(100)) * time.Nanosecond)
time.Sleep(time.Duration(randutil.Int63n(100)) * time.Nanosecond)

km.Unlock(key)
}
Expand Down Expand Up @@ -161,7 +156,7 @@ func TestMultiAcquireOnSameKey(t *testing.T) {
for i := 0; i < nloops; i++ {
km.Lock(ctx, key)

time.Sleep(time.Duration(rand.Int63n(100)) * time.Nanosecond)
time.Sleep(time.Duration(randutil.Int63n(100)) * time.Nanosecond)

km.Unlock(key)
}
Expand Down
48 changes: 48 additions & 0 deletions pkg/randutil/randutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
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 randutil provides utilities for [cyrpto/rand].
package randutil

import (
"crypto/rand"
"math"
"math/big"
)

// Int63n is similar to [math/rand.Int63n] but uses [crypto/rand.Reader] under the hood.
func Int63n(n int64) int64 {
b, err := rand.Int(rand.Reader, big.NewInt(n))
if err != nil {
panic(err)
}
return b.Int64()
}

// Int63 is similar to [math/rand.Int63] but uses [crypto/rand.Reader] under the hood.
func Int63() int64 {
return Int63n(math.MaxInt64)
}

// Intn is similar to [math/rand.Intn] but uses [crypto/rand.Reader] under the hood.
func Intn(n int) int {
return int(Int63n(int64(n)))
}

// Int is similar to [math/rand.Int] but uses [crypto/rand.Reader] under the hood.
func Int() int {
return int(Int63())
}
5 changes: 5 additions & 0 deletions pkg/seed/seed.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
limitations under the License.
*/

// Package seed provides an initializer for the global [math/rand] seed.
//
// Deprecated: Do not rely on the global seed.
package seed

import (
Expand All @@ -23,6 +26,8 @@ import (

// WithTimeAndRand seeds the global math rand generator with nanoseconds
// XOR'ed with a crypto component if available for uniqueness.
//
// Deprecated: Do not rely on the global seed.
func WithTimeAndRand() {
var (
b [4]byte
Expand Down
2 changes: 1 addition & 1 deletion rootfs/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ package rootfs

import (
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"math/rand"
"time"

"github.com/containerd/containerd/diff"
Expand Down
4 changes: 2 additions & 2 deletions snapshots/testsuite/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ package testsuite
import (
"context"
"fmt"
"math/rand"
"os"

"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/pkg/randutil"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/continuity/fs/fstest"
)
Expand All @@ -49,7 +49,7 @@ func applyToMounts(m []mount.Mount, work string, a fstest.Applier) (err error) {
// createSnapshot creates a new snapshot in the snapshotter
// given an applier to run on top of the given parent.
func createSnapshot(ctx context.Context, sn snapshots.Snapshotter, parent, work string, a fstest.Applier) (string, error) {
n := fmt.Sprintf("%p-%d", a, rand.Int())
n := fmt.Sprintf("%p-%d", a, randutil.Int())
prepare := fmt.Sprintf("%s-prepare", n)

m, err := sn.Prepare(ctx, prepare, parent, opt)
Expand Down
4 changes: 2 additions & 2 deletions snapshots/testsuite/testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
//nolint:revive // go-digest needs the blank import. See https://github.com/opencontainers/go-digest#usage.
_ "crypto/sha256"
"fmt"
"math/rand"
"os"
"path/filepath"
"sort"
Expand All @@ -32,6 +31,7 @@ import (
"github.com/containerd/containerd/log/logtest"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/randutil"
"github.com/containerd/containerd/pkg/testutil"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/continuity/fs/fstest"
Expand Down Expand Up @@ -837,7 +837,7 @@ func checkFileFromLowerLayer(ctx context.Context, t *testing.T, snapshotter snap
}

func closeTwice(ctx context.Context, t *testing.T, snapshotter snapshots.Snapshotter, work string) {
n := fmt.Sprintf("closeTwice-%d", rand.Int())
n := fmt.Sprintf("closeTwice-%d", randutil.Int())
prepare := fmt.Sprintf("%s-prepare", n)

// do some dummy ops to modify the snapshotter internal state
Expand Down
2 changes: 1 addition & 1 deletion unpacker.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ package containerd

import (
"context"
"crypto/rand"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"math/rand"
"sync"
"sync/atomic"
"time"
Expand Down

0 comments on commit 81fa937

Please sign in to comment.