// 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
	CorpusIntermediateDir android.Path
	Config                android.Path
	Data                  android.Paths
	DataIntermediateDir   android.Path
}

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(fuzzModule FuzzModule) bool {
	// Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
	// fuzz targets we're going to package anyway.
	if !fuzzModule.Enabled() || 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)

	// Don't add modules to 'make haiku-rust' that are set to not be
	// exported to the fuzzing infrastructure.
	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 !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, " "))
}
