// Copyright 2017 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.

// This test uses the Pdeathsig field of syscall.SysProcAttr, so it only works
// on platforms that support that.

//go:build linux || (freebsd && amd64)

// sanitizers_test checks the use of Go with sanitizers like msan, asan, etc.
// See https://github.com/google/sanitizers.
package sanitizers_test

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"testing"
	"time"
	"unicode"
)

var overcommit struct {
	sync.Once
	value int
	err   error
}

// requireOvercommit skips t if the kernel does not allow overcommit.
func requireOvercommit(t *testing.T) {
	t.Helper()

	overcommit.Once.Do(func() {
		var out []byte
		out, overcommit.err = os.ReadFile("/proc/sys/vm/overcommit_memory")
		if overcommit.err != nil {
			return
		}
		overcommit.value, overcommit.err = strconv.Atoi(string(bytes.TrimSpace(out)))
	})

	if overcommit.err != nil {
		t.Skipf("couldn't determine vm.overcommit_memory (%v); assuming no overcommit", overcommit.err)
	}
	if overcommit.value == 2 {
		t.Skip("vm.overcommit_memory=2")
	}
}

var env struct {
	sync.Once
	m   map[string]string
	err error
}

// goEnv returns the output of $(go env) as a map.
func goEnv(key string) (string, error) {
	env.Once.Do(func() {
		var out []byte
		out, env.err = exec.Command("go", "env", "-json").Output()
		if env.err != nil {
			return
		}

		env.m = make(map[string]string)
		env.err = json.Unmarshal(out, &env.m)
	})
	if env.err != nil {
		return "", env.err
	}

	v, ok := env.m[key]
	if !ok {
		return "", fmt.Errorf("`go env`: no entry for %v", key)
	}
	return v, nil
}

// replaceEnv sets the key environment variable to value in cmd.
func replaceEnv(cmd *exec.Cmd, key, value string) {
	if cmd.Env == nil {
		cmd.Env = cmd.Environ()
	}
	cmd.Env = append(cmd.Env, key+"="+value)
}

// appendExperimentEnv appends comma-separated experiments to GOEXPERIMENT.
func appendExperimentEnv(cmd *exec.Cmd, experiments []string) {
	if cmd.Env == nil {
		cmd.Env = cmd.Environ()
	}
	exps := strings.Join(experiments, ",")
	for _, evar := range cmd.Env {
		c := strings.SplitN(evar, "=", 2)
		if c[0] == "GOEXPERIMENT" {
			exps = c[1] + "," + exps
		}
	}
	cmd.Env = append(cmd.Env, "GOEXPERIMENT="+exps)
}

// mustRun executes t and fails cmd with a well-formatted message if it fails.
func mustRun(t *testing.T, cmd *exec.Cmd) {
	t.Helper()
	out := new(strings.Builder)
	cmd.Stdout = out
	cmd.Stderr = out

	err := cmd.Start()
	if err != nil {
		t.Fatalf("%v: %v", cmd, err)
	}

	if deadline, ok := t.Deadline(); ok {
		timeout := time.Until(deadline)
		timeout -= timeout / 10 // Leave 10% headroom for logging and cleanup.
		timer := time.AfterFunc(timeout, func() {
			cmd.Process.Signal(syscall.SIGQUIT)
		})
		defer timer.Stop()
	}

	if err := cmd.Wait(); err != nil {
		t.Fatalf("%v exited with %v\n%s", cmd, err, out)
	}
}

// cc returns a cmd that executes `$(go env CC) $(go env GOGCCFLAGS) $args`.
func cc(args ...string) (*exec.Cmd, error) {
	CC, err := goEnv("CC")
	if err != nil {
		return nil, err
	}

	GOGCCFLAGS, err := goEnv("GOGCCFLAGS")
	if err != nil {
		return nil, err
	}

	// Split GOGCCFLAGS, respecting quoting.
	//
	// TODO(bcmills): This code also appears in
	// cmd/cgo/internal/testcarchive/carchive_test.go, and perhaps ought to go in
	// src/cmd/dist/test.go as well. Figure out where to put it so that it can be
	// shared.
	var flags []string
	quote := '\000'
	start := 0
	lastSpace := true
	backslash := false
	for i, c := range GOGCCFLAGS {
		if quote == '\000' && unicode.IsSpace(c) {
			if !lastSpace {
				flags = append(flags, GOGCCFLAGS[start:i])
				lastSpace = true
			}
		} else {
			if lastSpace {
				start = i
				lastSpace = false
			}
			if quote == '\000' && !backslash && (c == '"' || c == '\'') {
				quote = c
				backslash = false
			} else if !backslash && quote == c {
				quote = '\000'
			} else if (quote == '\000' || quote == '"') && !backslash && c == '\\' {
				backslash = true
			} else {
				backslash = false
			}
		}
	}
	if !lastSpace {
		flags = append(flags, GOGCCFLAGS[start:])
	}

	cmd := exec.Command(CC, flags...)
	cmd.Args = append(cmd.Args, args...)
	return cmd, nil
}

type version struct {
	name         string
	major, minor int
}

var compiler struct {
	sync.Once
	version
	err error
}

// compilerVersion detects the version of $(go env CC).
//
// It returns a non-nil error if the compiler matches a known version schema but
// the version could not be parsed, or if $(go env CC) could not be determined.
func compilerVersion() (version, error) {
	compiler.Once.Do(func() {
		compiler.err = func() error {
			compiler.name = "unknown"

			cmd, err := cc("--version")
			if err != nil {
				return err
			}
			out, err := cmd.Output()
			if err != nil {
				// Compiler does not support "--version" flag: not Clang or GCC.
				return nil
			}

			var match [][]byte
			if bytes.HasPrefix(out, []byte("gcc")) {
				compiler.name = "gcc"
				cmd, err := cc("-dumpfullversion", "-dumpversion")
				if err != nil {
					return err
				}
				out, err := cmd.Output()
				if err != nil {
					// gcc, but does not support gcc's "-v" flag?!
					return err
				}
				gccRE := regexp.MustCompile(`(\d+)\.(\d+)`)
				match = gccRE.FindSubmatch(out)
			} else {
				clangRE := regexp.MustCompile(`clang version (\d+)\.(\d+)`)
				if match = clangRE.FindSubmatch(out); len(match) > 0 {
					compiler.name = "clang"
				}
			}

			if len(match) < 3 {
				return nil // "unknown"
			}
			if compiler.major, err = strconv.Atoi(string(match[1])); err != nil {
				return err
			}
			if compiler.minor, err = strconv.Atoi(string(match[2])); err != nil {
				return err
			}
			return nil
		}()
	})
	return compiler.version, compiler.err
}

// compilerSupportsLocation reports whether the compiler should be
// able to provide file/line information in backtraces.
func compilerSupportsLocation() bool {
	compiler, err := compilerVersion()
	if err != nil {
		return false
	}
	switch compiler.name {
	case "gcc":
		return compiler.major >= 10
	case "clang":
		return true
	default:
		return false
	}
}

// compilerRequiredTsanVersion reports whether the compiler is the version required by Tsan.
// Only restrictions for ppc64le are known; otherwise return true.
func compilerRequiredTsanVersion(goos, goarch string) bool {
	compiler, err := compilerVersion()
	if err != nil {
		return false
	}
	if compiler.name == "gcc" && goarch == "ppc64le" {
		return compiler.major >= 9
	}
	return true
}

// compilerRequiredAsanVersion reports whether the compiler is the version required by Asan.
func compilerRequiredAsanVersion(goos, goarch string) bool {
	compiler, err := compilerVersion()
	if err != nil {
		return false
	}
	switch compiler.name {
	case "gcc":
		if goarch == "ppc64le" {
			return compiler.major >= 9
		}
		return compiler.major >= 7
	case "clang":
		return compiler.major >= 9
	default:
		return false
	}
}

type compilerCheck struct {
	once sync.Once
	err  error
	skip bool // If true, skip with err instead of failing with it.
}

type config struct {
	sanitizer string

	cFlags, ldFlags, goFlags []string

	sanitizerCheck, runtimeCheck compilerCheck
}

var configs struct {
	sync.Mutex
	m map[string]*config
}

// configure returns the configuration for the given sanitizer.
func configure(sanitizer string) *config {
	configs.Lock()
	defer configs.Unlock()
	if c, ok := configs.m[sanitizer]; ok {
		return c
	}

	c := &config{
		sanitizer: sanitizer,
		cFlags:    []string{"-fsanitize=" + sanitizer},
		ldFlags:   []string{"-fsanitize=" + sanitizer},
	}

	if testing.Verbose() {
		c.goFlags = append(c.goFlags, "-x")
	}

	switch sanitizer {
	case "memory":
		c.goFlags = append(c.goFlags, "-msan")

	case "thread":
		c.goFlags = append(c.goFlags, "--installsuffix=tsan")
		compiler, _ := compilerVersion()
		if compiler.name == "gcc" {
			c.cFlags = append(c.cFlags, "-fPIC")
			c.ldFlags = append(c.ldFlags, "-fPIC", "-static-libtsan")
		}

	case "address":
		c.goFlags = append(c.goFlags, "-asan")
		// Set the debug mode to print the C stack trace.
		c.cFlags = append(c.cFlags, "-g")

	case "fuzzer":
		c.goFlags = append(c.goFlags, "-tags=libfuzzer", "-gcflags=-d=libfuzzer")

	default:
		panic(fmt.Sprintf("unrecognized sanitizer: %q", sanitizer))
	}

	if configs.m == nil {
		configs.m = make(map[string]*config)
	}
	configs.m[sanitizer] = c
	return c
}

// goCmd returns a Cmd that executes "go $subcommand $args" with appropriate
// additional flags and environment.
func (c *config) goCmd(subcommand string, args ...string) *exec.Cmd {
	return c.goCmdWithExperiments(subcommand, args, nil)
}

// goCmdWithExperiments returns a Cmd that executes
// "GOEXPERIMENT=$experiments go $subcommand $args" with appropriate
// additional flags and CGO-related environment variables.
func (c *config) goCmdWithExperiments(subcommand string, args []string, experiments []string) *exec.Cmd {
	cmd := exec.Command("go", subcommand)
	cmd.Args = append(cmd.Args, c.goFlags...)
	cmd.Args = append(cmd.Args, args...)
	replaceEnv(cmd, "CGO_CFLAGS", strings.Join(c.cFlags, " "))
	replaceEnv(cmd, "CGO_LDFLAGS", strings.Join(c.ldFlags, " "))
	appendExperimentEnv(cmd, experiments)
	return cmd
}

// skipIfCSanitizerBroken skips t if the C compiler does not produce working
// binaries as configured.
func (c *config) skipIfCSanitizerBroken(t *testing.T) {
	check := &c.sanitizerCheck
	check.once.Do(func() {
		check.skip, check.err = c.checkCSanitizer()
	})
	if check.err != nil {
		t.Helper()
		if check.skip {
			t.Skip(check.err)
		}
		t.Fatal(check.err)
	}
}

var cMain = []byte(`
int main() {
	return 0;
}
`)

var cLibFuzzerInput = []byte(`
#include <stddef.h>
int LLVMFuzzerTestOneInput(char *data, size_t size) {
	return 0;
}
`)

func (c *config) checkCSanitizer() (skip bool, err error) {
	dir, err := os.MkdirTemp("", c.sanitizer)
	if err != nil {
		return false, fmt.Errorf("failed to create temp directory: %v", err)
	}
	defer os.RemoveAll(dir)

	src := filepath.Join(dir, "return0.c")
	cInput := cMain
	if c.sanitizer == "fuzzer" {
		// libFuzzer generates the main function itself, and uses a different input.
		cInput = cLibFuzzerInput
	}
	if err := os.WriteFile(src, cInput, 0600); err != nil {
		return false, fmt.Errorf("failed to write C source file: %v", err)
	}

	dst := filepath.Join(dir, "return0")
	cmd, err := cc(c.cFlags...)
	if err != nil {
		return false, err
	}
	cmd.Args = append(cmd.Args, c.ldFlags...)
	cmd.Args = append(cmd.Args, "-o", dst, src)
	out, err := cmd.CombinedOutput()
	if err != nil {
		if bytes.Contains(out, []byte("-fsanitize")) &&
			(bytes.Contains(out, []byte("unrecognized")) ||
				bytes.Contains(out, []byte("unsupported"))) {
			return true, errors.New(string(out))
		}
		return true, fmt.Errorf("%#q failed: %v\n%s", strings.Join(cmd.Args, " "), err, out)
	}

	if c.sanitizer == "fuzzer" {
		// For fuzzer, don't try running the test binary. It never finishes.
		return false, nil
	}

	if out, err := exec.Command(dst).CombinedOutput(); err != nil {
		if os.IsNotExist(err) {
			return true, fmt.Errorf("%#q failed to produce executable: %v", strings.Join(cmd.Args, " "), err)
		}
		snippet, _, _ := bytes.Cut(out, []byte("\n"))
		return true, fmt.Errorf("%#q generated broken executable: %v\n%s", strings.Join(cmd.Args, " "), err, snippet)
	}

	return false, nil
}

// skipIfRuntimeIncompatible skips t if the Go runtime is suspected not to work
// with cgo as configured.
func (c *config) skipIfRuntimeIncompatible(t *testing.T) {
	check := &c.runtimeCheck
	check.once.Do(func() {
		check.skip, check.err = c.checkRuntime()
	})
	if check.err != nil {
		t.Helper()
		if check.skip {
			t.Skip(check.err)
		}
		t.Fatal(check.err)
	}
}

func (c *config) checkRuntime() (skip bool, err error) {
	if c.sanitizer != "thread" {
		return false, nil
	}

	// libcgo.h sets CGO_TSAN if it detects TSAN support in the C compiler.
	// Dump the preprocessor defines to check that works.
	// (Sometimes it doesn't: see https://golang.org/issue/15983.)
	cmd, err := cc(c.cFlags...)
	if err != nil {
		return false, err
	}
	cmd.Args = append(cmd.Args, "-dM", "-E", "../../../../runtime/cgo/libcgo.h")
	cmdStr := strings.Join(cmd.Args, " ")
	out, err := cmd.CombinedOutput()
	if err != nil {
		return false, fmt.Errorf("%#q exited with %v\n%s", cmdStr, err, out)
	}
	if !bytes.Contains(out, []byte("#define CGO_TSAN")) {
		return true, fmt.Errorf("%#q did not define CGO_TSAN", cmdStr)
	}
	return false, nil
}

// srcPath returns the path to the given file relative to this test's source tree.
func srcPath(path string) string {
	return filepath.Join("testdata", path)
}

// A tempDir manages a temporary directory within a test.
type tempDir struct {
	base string
}

func (d *tempDir) RemoveAll(t *testing.T) {
	t.Helper()
	if d.base == "" {
		return
	}
	if err := os.RemoveAll(d.base); err != nil {
		t.Fatalf("Failed to remove temp dir: %v", err)
	}
}

func (d *tempDir) Base() string {
	return d.base
}

func (d *tempDir) Join(name string) string {
	return filepath.Join(d.base, name)
}

func newTempDir(t *testing.T) *tempDir {
	t.Helper()
	dir, err := os.MkdirTemp("", filepath.Dir(t.Name()))
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	return &tempDir{base: dir}
}

// hangProneCmd returns an exec.Cmd for a command that is likely to hang.
//
// If one of these tests hangs, the caller is likely to kill the test process
// using SIGINT, which will be sent to all of the processes in the test's group.
// Unfortunately, TSAN in particular is prone to dropping signals, so the SIGINT
// may terminate the test binary but leave the subprocess running. hangProneCmd
// configures subprocess to receive SIGKILL instead to ensure that it won't
// leak.
func hangProneCmd(name string, arg ...string) *exec.Cmd {
	cmd := exec.Command(name, arg...)
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Pdeathsig: syscall.SIGKILL,
	}
	return cmd
}
