// Copyright 2021 Google Inc. All rights reserved.
//
// 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 fuzz

// This file contains the common code for compiling C/C++ and Rust fuzzers for Android.

import (
	"encoding/json"
	"fmt"
	"sort"
	"strings"

	"github.com/google/blueprint/proptools"

	"android/soong/android"
)

type Lang string

const (
	Cc   Lang = "cc"
	Rust Lang = "rust"
	Java Lang = "java"
)

type Framework string

const (
	AFL              Framework = "afl"
	LibFuzzer        Framework = "libfuzzer"
	Jazzer           Framework = "jazzer"
	UnknownFramework Framework = "unknownframework"
)

var BoolDefault = proptools.BoolDefault

type FuzzModule struct {
	android.ModuleBase
	android.DefaultableModuleBase
	android.ApexModuleBase
}

type FuzzPackager struct {
	Packages                android.Paths
	FuzzTargets             map[string]bool
	SharedLibInstallStrings []string
}

type FileToZip struct {
	SourceFilePath        android.Path
	DestinationPathPrefix string
	DestinationPath       string
}

type ArchOs struct {
	HostOrTarget string
	Arch         string
	Dir          string
}

type Vector string

const (
	unknown_access_vector Vector = "unknown_access_vector"
	// The code being fuzzed is reachable from a remote source, or using data
	// provided by a remote source.  For example: media codecs process media files
	// from the internet, SMS processing handles remote message data.
	// See
	// https://source.android.com/docs/security/overview/updates-resources#local-vs-remote
	// for an explanation of what's considered "remote."
	remote = "remote"
	// The code being fuzzed can only be reached locally, such as from an
	// installed app.  As an example, if it's fuzzing a Binder interface, it's
	// assumed that you'd need a local app to make arbitrary Binder calls.
	// And the app that's calling the fuzzed code does not require any privileges;
	// any 3rd party app could make these calls.
	local_no_privileges_required = "local_no_privileges_required"
	// The code being fuzzed can only be called locally, and the calling process
	// requires additional permissions that prevent arbitrary 3rd party apps from
	// calling the code.  For instance: this requires a privileged or signature
	// permission to reach, or SELinux restrictions prevent the untrusted_app
	// domain from calling it.
	local_privileges_required = "local_privileges_required"
	// The code is only callable on a PC host, not on a production Android device.
	// For instance, this is fuzzing code used during the build process, or
	// tooling that does not exist on a user's actual Android device.
	host_access = "host_access"
	// The code being fuzzed is only reachable if the user has enabled Developer
	// Options, or has enabled a persistent Developer Options setting.
	local_with_developer_options = "local_with_developer_options"
)

func (vector Vector) isValidVector() bool {
	switch vector {
	case "",
		unknown_access_vector,
		remote,
		local_no_privileges_required,
		local_privileges_required,
		host_access,
		local_with_developer_options:
		return true
	}
	return false
}

type ServicePrivilege string

const (
	unknown_service_privilege ServicePrivilege = "unknown_service_privilege"
	// The code being fuzzed runs on a Secure Element.  This has access to some
	// of the most privileged data on the device, such as authentication keys.
	// Not all devices have a Secure Element.
	secure_element = "secure_element"
	// The code being fuzzed runs in the TEE.  The TEE is designed to be resistant
	// to a compromised kernel, and stores sensitive data.
	trusted_execution = "trusted_execution"
	// The code being fuzzed has privileges beyond what arbitrary 3rd party apps
	// have.  For instance, it's running as the System UID, or it's in an SELinux
	// domain that's able to perform calls that can't be made by 3rd party apps.
	privileged = "privileged"
	// The code being fuzzed is equivalent to a 3rd party app.  It runs in the
	// untrusted_app SELinux domain, or it only has privileges that are equivalent
	// to what a 3rd party app could have.
	unprivileged = "unprivileged"
	// The code being fuzzed is significantly constrained, and even if it's
	// compromised, it has significant restrictions that prevent it from
	// performing most actions.  This is significantly more restricted than
	// UNPRIVILEGED.  An example is the isolatedProcess=true setting in a 3rd
	// party app.  Or a process that's very restricted by SELinux, such as
	// anything in the mediacodec SELinux domain.
	constrained = "constrained"
	// The code being fuzzed always has Negligible Security Impact.  Even
	// arbitrary out of bounds writes and full code execution would not be
	// considered a security vulnerability.  This typically only makes sense if
	// FuzzedCodeUsage is set to FUTURE_VERSION or EXPERIMENTAL, and if
	// AutomaticallyRouteTo is set to ALWAYS_NSI.
	nsi = "nsi"
	// The code being fuzzed only runs on a PC host, not on a production Android
	// device.  For instance, the fuzzer is fuzzing code used during the build
	// process, or tooling that does not exist on a user's actual Android device.
	host_only = "host_only"
)

func (service_privilege ServicePrivilege) isValidServicePrivilege() bool {
	switch service_privilege {
	case "",
		unknown_service_privilege,
		secure_element,
		trusted_execution,
		privileged,
		unprivileged,
		constrained,
		nsi,
		host_only:
		return true
	}
	return false
}

type UsePlatformLibs string

const (
	unknown_use_platform_libs UsePlatformLibs = "unknown_use_platform_libs"
	// Use the native libraries on the device, typically in /system directory
	use_platform_libs = "use_platform_libs"
	// Do not use any native libraries (ART will not be initialized)
	use_none = "use_none"
)

func (use_platform_libs UsePlatformLibs) isValidUsePlatformLibs() bool {
	switch use_platform_libs {
	case "",
		unknown_use_platform_libs,
		use_platform_libs,
		use_none:
		return true
	}
	return false
}

type UserData string

const (
	unknown_user_data UserData = "unknown_user_data"
	// The process being fuzzed only handles data from a single user, or from a
	// single process or app.  It's possible the process shuts down before
	// handling data from another user/process/app, or it's possible the process
	// only ever handles one user's/process's/app's data.  As an example, some
	// print spooler processes are started for a single document and terminate
	// when done, so each instance only handles data from a single user/app.
	single_user = "single_user"
	// The process handles data from multiple users, or from multiple other apps
	// or processes.  Media processes, for instance, can handle media requests
	// from multiple different apps without restarting.  Wi-Fi and network
	// processes handle data from multiple users, and processes, and apps.
	multi_user = "multi_user"
)

func (user_data UserData) isValidUserData() bool {
	switch user_data {
	case "",
		unknown_user_data,
		single_user,
		multi_user:
		return true
	}
	return false
}

type FuzzedCodeUsage string

const (
	undefined FuzzedCodeUsage = "undefined"
	unknown                   = "unknown"
	// The code being fuzzed exists in a shipped version of Android and runs on
	// devices in production.
	shipped = "shipped"
	// The code being fuzzed is not yet in a shipping version of Android, but it
	// will be at some point in the future.
	future_version = "future_version"
	// The code being fuzzed is not in a shipping version of Android, and there
	// are no plans to ship it in the future.
	experimental = "experimental"
)

func (fuzzed_code_usage FuzzedCodeUsage) isValidFuzzedCodeUsage() bool {
	switch fuzzed_code_usage {
	case "",
		undefined,
		unknown,
		shipped,
		future_version,
		experimental:
		return true
	}
	return false
}

type AutomaticallyRouteTo string

const (
	undefined_routing AutomaticallyRouteTo = "undefined_routing"
	// Automatically route this to the Android Automotive security team for
	// assessment.
	android_automotive = "android_automotive"
	// This should not be used in fuzzer configurations.  It is used internally
	// by Severity Assigner to flag memory leak reports.
	memory_leak = "memory_leak"
	// Route this vulnerability to our Ittiam vendor team for assessment.
	ittiam = "ittiam"
	// Reports from this fuzzer are always NSI (see the NSI ServicePrivilegeEnum
	// value for additional context).  It is not possible for this code to ever
	// have a security vulnerability.
	always_nsi = "always_nsi"
	// Route this vulnerability to AIDL team for assessment.
	aidl = "aidl"
)

func (automatically_route_to AutomaticallyRouteTo) isValidAutomaticallyRouteTo() bool {
	switch automatically_route_to {
	case "",
		undefined_routing,
		android_automotive,
		memory_leak,
		ittiam,
		always_nsi,
		aidl:
		return true
	}
	return false
}

func IsValidConfig(fuzzModule FuzzPackagedModule, moduleName string) bool {
	var config = fuzzModule.FuzzProperties.Fuzz_config
	if config != nil {
		if !config.Vector.isValidVector() {
			panic(fmt.Errorf("Invalid vector in fuzz config in %s", moduleName))
		}

		if !config.Service_privilege.isValidServicePrivilege() {
			panic(fmt.Errorf("Invalid service_privilege in fuzz config in %s", moduleName))
		}

		if !config.Users.isValidUserData() {
			panic(fmt.Errorf("Invalid users (user_data) in fuzz config in %s", moduleName))
		}

		if !config.Fuzzed_code_usage.isValidFuzzedCodeUsage() {
			panic(fmt.Errorf("Invalid fuzzed_code_usage in fuzz config in %s", moduleName))
		}

		if !config.Automatically_route_to.isValidAutomaticallyRouteTo() {
			panic(fmt.Errorf("Invalid automatically_route_to in fuzz config in %s", moduleName))
		}

		if !config.Use_platform_libs.isValidUsePlatformLibs() {
			panic(fmt.Errorf("Invalid use_platform_libs in fuzz config in %s", moduleName))
		}
	}
	return true
}

type FuzzConfig struct {
	// Email address of people to CC on bugs or contact about this fuzz target.
	Cc []string `json:"cc,omitempty"`
	// A brief description of what the fuzzed code does.
	Description string `json:"description,omitempty"`
	// Whether the code being fuzzed is remotely accessible or requires privileges
	// to access locally.
	Vector Vector `json:"vector,omitempty"`
	// How privileged the service being fuzzed is.
	Service_privilege ServicePrivilege `json:"service_privilege,omitempty"`
	// Whether the service being fuzzed handles data from multiple users or only
	// a single one.
	Users UserData `json:"users,omitempty"`
	// Specifies the use state of the code being fuzzed. This state factors into
	// how an issue is handled.
	Fuzzed_code_usage FuzzedCodeUsage `json:"fuzzed_code_usage,omitempty"`
	// Comment describing how we came to these settings for this fuzzer.
	Config_comment string
	// Which team to route this to, if it should be routed automatically.
	Automatically_route_to AutomaticallyRouteTo `json:"automatically_route_to,omitempty"`
	// Can third party/untrusted apps supply data to fuzzed code.
	Untrusted_data *bool `json:"untrusted_data,omitempty"`
	// When code was released or will be released.
	Production_date string `json:"production_date,omitempty"`
	// Prevents critical service functionality like phone calls, bluetooth, etc.
	Critical *bool `json:"critical,omitempty"`
	// Specify whether to enable continuous fuzzing on devices. Defaults to true.
	Fuzz_on_haiku_device *bool `json:"fuzz_on_haiku_device,omitempty"`
	// Specify whether to enable continuous fuzzing on host. Defaults to true.
	Fuzz_on_haiku_host *bool `json:"fuzz_on_haiku_host,omitempty"`
	// Component in Google's bug tracking system that bugs should be filed to.
	Componentid *int64 `json:"componentid,omitempty"`
	// Hotlist(s) in Google's bug tracking system that bugs should be marked with.
	Hotlists []string `json:"hotlists,omitempty"`
	// Specify whether this fuzz target was submitted by a researcher. Defaults
	// to false.
	Researcher_submitted *bool `json:"researcher_submitted,omitempty"`
	// Specify who should be acknowledged for CVEs in the Android Security
	// Bulletin.
	Acknowledgement []string `json:"acknowledgement,omitempty"`
	// Additional options to be passed to libfuzzer when run in Haiku.
	Libfuzzer_options []string `json:"libfuzzer_options,omitempty"`
	// Additional options to be passed to HWASAN when running on-device in Haiku.
	Hwasan_options []string `json:"hwasan_options,omitempty"`
	// Additional options to be passed to HWASAN when running on host in Haiku.
	Asan_options []string `json:"asan_options,omitempty"`
	// If there's a Java fuzzer with JNI, a different version of Jazzer would
	// need to be added to the fuzzer package than one without JNI
	IsJni *bool `json:"is_jni,omitempty"`
	// List of modules for monitoring coverage drops in directories (e.g. "libicu")
	Target_modules []string `json:"target_modules,omitempty"`
	// Specifies a bug assignee to replace default ISE assignment
	Triage_assignee string `json:"triage_assignee,omitempty"`
	// Specifies libs used to initialize ART (java only, 'use_none' for no initialization)
	Use_platform_libs UsePlatformLibs `json:"use_platform_libs,omitempty"`
	// Specifies whether fuzz target should check presubmitted code changes for crashes.
	// Defaults to false.
	Use_for_presubmit *bool `json:"use_for_presubmit,omitempty"`
	// Specify which paths to exclude from fuzzing coverage reports
	Exclude_paths_from_reports []string `json:"exclude_paths_from_reports,omitempty"`
}

type FuzzFrameworks struct {
	Afl       *bool
	Libfuzzer *bool
	Jazzer    *bool
}

type FuzzProperties struct {
	// Optional list of seed files to be installed to the fuzz target's output
	// directory.
	Corpus []string `android:"path"`
	// Optional list of data files to be installed to the fuzz target's output
	// directory. Directory structure relative to the module is preserved.
	Data []string `android:"path"`
	// Optional dictionary to be installed to the fuzz target's output directory.
	Dictionary *string `android:"path"`
	// Define the fuzzing frameworks this fuzz target can be built for. If
	// empty then the fuzz target will be available to be  built for all fuzz
	// frameworks available
	Fuzzing_frameworks *FuzzFrameworks
	// Config for running the target on fuzzing infrastructure.
	Fuzz_config *FuzzConfig
}

type FuzzPackagedModule struct {
	FuzzProperties FuzzProperties
	Dictionary     android.Path
	Corpus         android.Paths
	Config         android.Path
	Data           android.Paths
}

func GetFramework(ctx android.LoadHookContext, lang Lang) Framework {
	framework := ctx.Config().Getenv("FUZZ_FRAMEWORK")

	if lang == Cc {
		switch strings.ToLower(framework) {
		case "":
			return LibFuzzer
		case "libfuzzer":
			return LibFuzzer
		case "afl":
			return AFL
		}
	} else if lang == Rust {
		return LibFuzzer
	} else if lang == Java {
		return Jazzer
	}

	ctx.ModuleErrorf(fmt.Sprintf("%s is not a valid fuzzing framework for %s", framework, lang))
	return UnknownFramework
}

func IsValidFrameworkForModule(targetFramework Framework, lang Lang, moduleFrameworks *FuzzFrameworks) bool {
	if targetFramework == UnknownFramework {
		return false
	}

	if moduleFrameworks == nil {
		return true
	}

	switch targetFramework {
	case LibFuzzer:
		return proptools.BoolDefault(moduleFrameworks.Libfuzzer, true)
	case AFL:
		return proptools.BoolDefault(moduleFrameworks.Afl, true)
	case Jazzer:
		return proptools.BoolDefault(moduleFrameworks.Jazzer, true)
	default:
		panic("%s is not supported as a fuzz framework")
	}
}

func IsValid(ctx android.ConfigAndErrorContext, fuzzModule FuzzModule) bool {
	// Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
	// fuzz targets we're going to package anyway.
	if !fuzzModule.Enabled(ctx) || fuzzModule.InRamdisk() || fuzzModule.InVendorRamdisk() || fuzzModule.InRecovery() {
		return false
	}

	// Discard modules that are in an unavailable namespace.
	if !fuzzModule.ExportedToMake() {
		return false
	}

	return true
}

func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip {
	// Package the corpora into a zipfile.
	var files []FileToZip
	if fuzzModule.Corpus != nil {
		corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip")
		command := builder.Command().BuiltTool("soong_zip").
			Flag("-j").
			FlagWithOutput("-o ", corpusZip)
		rspFile := corpusZip.ReplaceExtension(ctx, "rsp")
		command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.Corpus)
		files = append(files, FileToZip{SourceFilePath: corpusZip})
	}

	// Package the data into a zipfile.
	if fuzzModule.Data != nil {
		dataZip := archDir.Join(ctx, module.Name()+"_data.zip")
		command := builder.Command().BuiltTool("soong_zip").
			FlagWithOutput("-o ", dataZip)
		for _, f := range fuzzModule.Data {
			intermediateDir := strings.TrimSuffix(f.String(), f.Rel())
			command.FlagWithArg("-C ", intermediateDir)
			command.FlagWithInput("-f ", f)
		}
		files = append(files, FileToZip{SourceFilePath: dataZip})
	}

	// The dictionary.
	if fuzzModule.Dictionary != nil {
		files = append(files, FileToZip{SourceFilePath: fuzzModule.Dictionary})
	}

	// Additional fuzz config.
	if fuzzModule.Config != nil && IsValidConfig(fuzzModule, module.Name()) {
		files = append(files, FileToZip{SourceFilePath: fuzzModule.Config})
	}

	return files
}

func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) {
	fuzzZip := archDir.Join(ctx, module.Name()+".zip")

	command := builder.Command().BuiltTool("soong_zip").
		Flag("-j").
		FlagWithOutput("-o ", fuzzZip)

	for _, file := range files {
		if file.DestinationPathPrefix != "" {
			command.FlagWithArg("-P ", file.DestinationPathPrefix)
		} else {
			command.Flag("-P ''")
		}
		if file.DestinationPath != "" {
			command.FlagWithArg("-e ", file.DestinationPath)
		}
		command.FlagWithInput("-f ", file.SourceFilePath)
	}

	builder.Build("create-"+fuzzZip.String(),
		"Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)

	if config := fuzzModule.FuzzProperties.Fuzz_config; config != nil {
		if strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_host, true) {
			return archDirs[archOs], false
		} else if !strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_device, true) {
			return archDirs[archOs], false
		}
	}

	s.FuzzTargets[module.Name()] = true
	archDirs[archOs] = append(archDirs[archOs], FileToZip{SourceFilePath: fuzzZip})

	return archDirs[archOs], true
}

func (f *FuzzConfig) String() string {
	b, err := json.Marshal(f)
	if err != nil {
		panic(err)
	}

	return string(b)
}

func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, fuzzType Lang, pctx android.PackageContext) {
	var archOsList []ArchOs
	for archOs := range archDirs {
		archOsList = append(archOsList, archOs)
	}
	sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].Dir < archOsList[j].Dir })

	for _, archOs := range archOsList {
		filesToZip := archDirs[archOs]
		arch := archOs.Arch
		hostOrTarget := archOs.HostOrTarget
		builder := android.NewRuleBuilder(pctx, ctx)
		zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip"
		if fuzzType == Rust {
			zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip"
		}
		if fuzzType == Java {
			zipFileName = "fuzz-java-" + hostOrTarget + "-" + arch + ".zip"
		}

		outputFile := android.PathForOutput(ctx, zipFileName)

		s.Packages = append(s.Packages, outputFile)

		command := builder.Command().BuiltTool("soong_zip").
			Flag("-j").
			FlagWithOutput("-o ", outputFile).
			Flag("-L 0") // No need to try and re-compress the zipfiles.

		for _, fileToZip := range filesToZip {
			if fileToZip.DestinationPathPrefix != "" {
				command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
			} else {
				command.Flag("-P ''")
			}
			command.FlagWithInput("-f ", fileToZip.SourceFilePath)

		}
		builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget,
			"Create fuzz target packages for "+arch+"-"+hostOrTarget)
	}
}

func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets string) {
	fuzzTargets := make([]string, 0, len(s.FuzzTargets))
	for target, _ := range s.FuzzTargets {
		fuzzTargets = append(fuzzTargets, target)
	}

	sort.Strings(fuzzTargets)
	ctx.Strict(targets, strings.Join(fuzzTargets, " "))
}
