blob: 8dca4b6efd65479a9186ae63deeac1f0fe88aec8 [file] [log] [blame]
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build cgo
package sysrand_test
import (
"bytes"
"crypto/internal/sysrand/internal/seccomp"
"internal/syscall/unix"
"internal/testenv"
"os"
"runtime"
"syscall"
"testing"
)
func TestNoGetrandom(t *testing.T) {
if os.Getenv("GO_GETRANDOM_DISABLED") == "1" {
// We are running under seccomp, the rest of the test suite will take
// care of actually testing the implementation, we check that getrandom
// is actually disabled.
_, err := unix.GetRandom(make([]byte, 16), 0)
if err != syscall.ENOSYS {
t.Errorf("GetRandom returned %v, want ENOSYS", err)
} else {
t.Log("GetRandom returned ENOSYS as expected")
}
return
}
if testing.Short() {
t.Skip("skipping test in short mode")
}
testenv.MustHaveExec(t) // testenv.Command can't skip from a goroutine
done := make(chan struct{})
go func() {
defer close(done)
// Call LockOSThread in a new goroutine, where we will apply the seccomp
// filter. We exit without unlocking the thread, so the thread will die
// and won't be reused.
runtime.LockOSThread()
if err := seccomp.DisableGetrandom(); err != nil {
t.Errorf("failed to disable getrandom: %v", err)
return
}
cmd := testenv.Command(t, testenv.Executable(t), "-test.v")
cmd.Env = append(os.Environ(), "GO_GETRANDOM_DISABLED=1")
out, err := cmd.CombinedOutput()
t.Logf("running with GO_GETRANDOM_DISABLED=1:\n%s", out)
if err != nil {
t.Errorf("subprocess failed: %v", err)
return
}
if !bytes.Contains(out, []byte("GetRandom returned ENOSYS")) {
t.Errorf("subprocess did not disable getrandom")
}
if !bytes.Contains(out, []byte("TestRead")) {
t.Errorf("subprocess did not run TestRead")
}
}()
<-done
}