// Copyright 2020 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 darwin || linux

package fuzz

import (
	"fmt"
	"os"
	"os/exec"
	"syscall"
)

type sharedMemSys struct{}

func sharedMemMapFile(f *os.File, size int, removeOnClose bool) (*sharedMem, error) {
	prot := syscall.PROT_READ | syscall.PROT_WRITE
	flags := syscall.MAP_FILE | syscall.MAP_SHARED
	region, err := syscall.Mmap(int(f.Fd()), 0, size, prot, flags)
	if err != nil {
		return nil, err
	}

	return &sharedMem{f: f, region: region, removeOnClose: removeOnClose}, nil
}

// Close unmaps the shared memory and closes the temporary file. If this
// sharedMem was created with sharedMemTempFile, Close also removes the file.
func (m *sharedMem) Close() error {
	// Attempt all operations, even if we get an error for an earlier operation.
	// os.File.Close may fail due to I/O errors, but we still want to delete
	// the temporary file.
	var errs []error
	errs = append(errs,
		syscall.Munmap(m.region),
		m.f.Close())
	if m.removeOnClose {
		errs = append(errs, os.Remove(m.f.Name()))
	}
	for _, err := range errs {
		if err != nil {
			return err
		}
	}
	return nil
}

// setWorkerComm configures communication channels on the cmd that will
// run a worker process.
func setWorkerComm(cmd *exec.Cmd, comm workerComm) {
	mem := <-comm.memMu
	memFile := mem.f
	comm.memMu <- mem
	cmd.ExtraFiles = []*os.File{comm.fuzzIn, comm.fuzzOut, memFile}
}

// getWorkerComm returns communication channels in the worker process.
func getWorkerComm() (comm workerComm, err error) {
	fuzzIn := os.NewFile(3, "fuzz_in")
	fuzzOut := os.NewFile(4, "fuzz_out")
	memFile := os.NewFile(5, "fuzz_mem")
	fi, err := memFile.Stat()
	if err != nil {
		return workerComm{}, err
	}
	size := int(fi.Size())
	if int64(size) != fi.Size() {
		return workerComm{}, fmt.Errorf("fuzz temp file exceeds maximum size")
	}
	removeOnClose := false
	mem, err := sharedMemMapFile(memFile, size, removeOnClose)
	if err != nil {
		return workerComm{}, err
	}
	memMu := make(chan *sharedMem, 1)
	memMu <- mem
	return workerComm{fuzzIn: fuzzIn, fuzzOut: fuzzOut, memMu: memMu}, nil
}

// isInterruptError returns whether an error was returned by a process that
// was terminated by an interrupt signal (SIGINT).
func isInterruptError(err error) bool {
	exitErr, ok := err.(*exec.ExitError)
	if !ok || exitErr.ExitCode() >= 0 {
		return false
	}
	status := exitErr.Sys().(syscall.WaitStatus)
	return status.Signal() == syscall.SIGINT
}

// terminationSignal checks if err is an exec.ExitError with a signal status.
// If it is, terminationSignal returns the signal and true.
// If not, -1 and false.
func terminationSignal(err error) (os.Signal, bool) {
	exitErr, ok := err.(*exec.ExitError)
	if !ok || exitErr.ExitCode() >= 0 {
		return syscall.Signal(-1), false
	}
	status := exitErr.Sys().(syscall.WaitStatus)
	return status.Signal(), status.Signaled()
}

// isCrashSignal returns whether a signal was likely to have been caused by an
// error in the program that received it, triggered by a fuzz input. For
// example, SIGSEGV would be received after a nil pointer dereference.
// Other signals like SIGKILL or SIGHUP are more likely to have been sent by
// another process, and we shouldn't record a crasher if the worker process
// receives one of these.
//
// Note that Go installs its own signal handlers on startup, so some of these
// signals may only be received if signal handlers are changed. For example,
// SIGSEGV is normally transformed into a panic that causes the process to exit
// with status 2 if not recovered, which we handle as a crash.
func isCrashSignal(signal os.Signal) bool {
	switch signal {
	case
		syscall.SIGILL,  // illegal instruction
		syscall.SIGTRAP, // breakpoint
		syscall.SIGABRT, // abort() called
		syscall.SIGBUS,  // invalid memory access (e.g., misaligned address)
		syscall.SIGFPE,  // math error, e.g., integer divide by zero
		syscall.SIGSEGV, // invalid memory access (e.g., write to read-only)
		syscall.SIGPIPE: // sent data to closed pipe or socket
		return true
	default:
		return false
	}
}
