// +build linux

// Public API specification for libseccomp Go bindings
// Contains public API for the bindings

// Package seccomp provides bindings for libseccomp, a library wrapping the Linux
// seccomp syscall. Seccomp enables an application to restrict system call use
// for itself and its children.
package seccomp

import (
	"fmt"
	"os"
	"runtime"
	"strings"
	"sync"
	"syscall"
	"unsafe"
)

// C wrapping code

// #cgo pkg-config: libseccomp
// #include <stdlib.h>
// #include <seccomp.h>
import "C"

// Exported types

// ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a
// per-architecture basis.
type ScmpArch uint

// ScmpAction represents an action to be taken on a filter rule match in
// libseccomp
type ScmpAction uint

// ScmpCompareOp represents a comparison operator which can be used in a filter
// rule
type ScmpCompareOp uint

// ScmpCondition represents a rule in a libseccomp filter context
type ScmpCondition struct {
	Argument uint          `json:"argument,omitempty"`
	Op       ScmpCompareOp `json:"operator,omitempty"`
	Operand1 uint64        `json:"operand_one,omitempty"`
	Operand2 uint64        `json:"operand_two,omitempty"`
}

// ScmpSyscall represents a Linux System Call
type ScmpSyscall int32

// Exported Constants

const (
	// Valid architectures recognized by libseccomp
	// ARM64 and all MIPS architectures are unsupported by versions of the
	// library before v2.2 and will return errors if used

	// ArchInvalid is a placeholder to ensure uninitialized ScmpArch
	// variables are invalid
	ArchInvalid ScmpArch = iota
	// ArchNative is the native architecture of the kernel
	ArchNative ScmpArch = iota
	// ArchX86 represents 32-bit x86 syscalls
	ArchX86 ScmpArch = iota
	// ArchAMD64 represents 64-bit x86-64 syscalls
	ArchAMD64 ScmpArch = iota
	// ArchX32 represents 64-bit x86-64 syscalls (32-bit pointers)
	ArchX32 ScmpArch = iota
	// ArchARM represents 32-bit ARM syscalls
	ArchARM ScmpArch = iota
	// ArchARM64 represents 64-bit ARM syscalls
	ArchARM64 ScmpArch = iota
	// ArchMIPS represents 32-bit MIPS syscalls
	ArchMIPS ScmpArch = iota
	// ArchMIPS64 represents 64-bit MIPS syscalls
	ArchMIPS64 ScmpArch = iota
	// ArchMIPS64N32 represents 64-bit MIPS syscalls (32-bit pointers)
	ArchMIPS64N32 ScmpArch = iota
	// ArchMIPSEL represents 32-bit MIPS syscalls (little endian)
	ArchMIPSEL ScmpArch = iota
	// ArchMIPSEL64 represents 64-bit MIPS syscalls (little endian)
	ArchMIPSEL64 ScmpArch = iota
	// ArchMIPSEL64N32 represents 64-bit MIPS syscalls (little endian,
	// 32-bit pointers)
	ArchMIPSEL64N32 ScmpArch = iota
	// ArchPPC represents 32-bit POWERPC syscalls
	ArchPPC ScmpArch = iota
	// ArchPPC64 represents 64-bit POWER syscalls (big endian)
	ArchPPC64 ScmpArch = iota
	// ArchPPC64LE represents 64-bit POWER syscalls (little endian)
	ArchPPC64LE ScmpArch = iota
	// ArchS390 represents 31-bit System z/390 syscalls
	ArchS390 ScmpArch = iota
	// ArchS390X represents 64-bit System z/390 syscalls
	ArchS390X ScmpArch = iota
)

const (
	// Supported actions on filter match

	// ActInvalid is a placeholder to ensure uninitialized ScmpAction
	// variables are invalid
	ActInvalid ScmpAction = iota
	// ActKill kills the process
	ActKill ScmpAction = iota
	// ActTrap throws SIGSYS
	ActTrap ScmpAction = iota
	// ActErrno causes the syscall to return a negative error code. This
	// code can be set with the SetReturnCode method
	ActErrno ScmpAction = iota
	// ActTrace causes the syscall to notify tracing processes with the
	// given error code. This code can be set with the SetReturnCode method
	ActTrace ScmpAction = iota
	// ActAllow permits the syscall to continue execution
	ActAllow ScmpAction = iota
)

const (
	// These are comparison operators used in conditional seccomp rules
	// They are used to compare the value of a single argument of a syscall
	// against a user-defined constant

	// CompareInvalid is a placeholder to ensure uninitialized ScmpCompareOp
	// variables are invalid
	CompareInvalid ScmpCompareOp = iota
	// CompareNotEqual returns true if the argument is not equal to the
	// given value
	CompareNotEqual ScmpCompareOp = iota
	// CompareLess returns true if the argument is less than the given value
	CompareLess ScmpCompareOp = iota
	// CompareLessOrEqual returns true if the argument is less than or equal
	// to the given value
	CompareLessOrEqual ScmpCompareOp = iota
	// CompareEqual returns true if the argument is equal to the given value
	CompareEqual ScmpCompareOp = iota
	// CompareGreaterEqual returns true if the argument is greater than or
	// equal to the given value
	CompareGreaterEqual ScmpCompareOp = iota
	// CompareGreater returns true if the argument is greater than the given
	// value
	CompareGreater ScmpCompareOp = iota
	// CompareMaskedEqual returns true if the argument is equal to the given
	// value, when masked (bitwise &) against the second given value
	CompareMaskedEqual ScmpCompareOp = iota
)

// Helpers for types

// GetArchFromString returns an ScmpArch constant from a string representing an
// architecture
func GetArchFromString(arch string) (ScmpArch, error) {
	switch strings.ToLower(arch) {
	case "x86":
		return ArchX86, nil
	case "amd64", "x86-64", "x86_64", "x64":
		return ArchAMD64, nil
	case "x32":
		return ArchX32, nil
	case "arm":
		return ArchARM, nil
	case "arm64", "aarch64":
		return ArchARM64, nil
	case "mips":
		return ArchMIPS, nil
	case "mips64":
		return ArchMIPS64, nil
	case "mips64n32":
		return ArchMIPS64N32, nil
	case "mipsel":
		return ArchMIPSEL, nil
	case "mipsel64":
		return ArchMIPSEL64, nil
	case "mipsel64n32":
		return ArchMIPSEL64N32, nil
	case "ppc":
		return ArchPPC, nil
	case "ppc64":
		return ArchPPC64, nil
	case "ppc64le":
		return ArchPPC64LE, nil
	case "s390":
		return ArchS390, nil
	case "s390x":
		return ArchS390X, nil
	default:
		return ArchInvalid, fmt.Errorf("cannot convert unrecognized string %s", arch)
	}
}

// String returns a string representation of an architecture constant
func (a ScmpArch) String() string {
	switch a {
	case ArchX86:
		return "x86"
	case ArchAMD64:
		return "amd64"
	case ArchX32:
		return "x32"
	case ArchARM:
		return "arm"
	case ArchARM64:
		return "arm64"
	case ArchMIPS:
		return "mips"
	case ArchMIPS64:
		return "mips64"
	case ArchMIPS64N32:
		return "mips64n32"
	case ArchMIPSEL:
		return "mipsel"
	case ArchMIPSEL64:
		return "mipsel64"
	case ArchMIPSEL64N32:
		return "mipsel64n32"
	case ArchPPC:
		return "ppc"
	case ArchPPC64:
		return "ppc64"
	case ArchPPC64LE:
		return "ppc64le"
	case ArchS390:
		return "s390"
	case ArchS390X:
		return "s390x"
	case ArchNative:
		return "native"
	case ArchInvalid:
		return "Invalid architecture"
	default:
		return "Unknown architecture"
	}
}

// String returns a string representation of a comparison operator constant
func (a ScmpCompareOp) String() string {
	switch a {
	case CompareNotEqual:
		return "Not equal"
	case CompareLess:
		return "Less than"
	case CompareLessOrEqual:
		return "Less than or equal to"
	case CompareEqual:
		return "Equal"
	case CompareGreaterEqual:
		return "Greater than or equal to"
	case CompareGreater:
		return "Greater than"
	case CompareMaskedEqual:
		return "Masked equality"
	case CompareInvalid:
		return "Invalid comparison operator"
	default:
		return "Unrecognized comparison operator"
	}
}

// String returns a string representation of a seccomp match action
func (a ScmpAction) String() string {
	switch a & 0xFFFF {
	case ActKill:
		return "Action: Kill Process"
	case ActTrap:
		return "Action: Send SIGSYS"
	case ActErrno:
		return fmt.Sprintf("Action: Return error code %d", (a >> 16))
	case ActTrace:
		return fmt.Sprintf("Action: Notify tracing processes with code %d",
			(a >> 16))
	case ActAllow:
		return "Action: Allow system call"
	default:
		return "Unrecognized Action"
	}
}

// SetReturnCode adds a return code to a supporting ScmpAction, clearing any
// existing code Only valid on ActErrno and ActTrace. Takes no action otherwise.
// Accepts 16-bit return code as argument.
// Returns a valid ScmpAction of the original type with the new error code set.
func (a ScmpAction) SetReturnCode(code int16) ScmpAction {
	aTmp := a & 0x0000FFFF
	if aTmp == ActErrno || aTmp == ActTrace {
		return (aTmp | (ScmpAction(code)&0xFFFF)<<16)
	}
	return a
}

// GetReturnCode returns the return code of an ScmpAction
func (a ScmpAction) GetReturnCode() int16 {
	return int16(a >> 16)
}

// General utility functions

// GetLibraryVersion returns the version of the library the bindings are built
// against.
// The version is formatted as follows: Major.Minor.Micro
func GetLibraryVersion() (major, minor, micro int) {
	return verMajor, verMinor, verMicro
}

// Syscall functions

// GetName retrieves the name of a syscall from its number.
// Acts on any syscall number.
// Returns either a string containing the name of the syscall, or an error.
func (s ScmpSyscall) GetName() (string, error) {
	return s.GetNameByArch(ArchNative)
}

// GetNameByArch retrieves the name of a syscall from its number for a given
// architecture.
// Acts on any syscall number.
// Accepts a valid architecture constant.
// Returns either a string containing the name of the syscall, or an error.
// if the syscall is unrecognized or an issue occurred.
func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) {
	if err := sanitizeArch(arch); err != nil {
		return "", err
	}

	cString := C.seccomp_syscall_resolve_num_arch(arch.toNative(), C.int(s))
	if cString == nil {
		return "", fmt.Errorf("could not resolve syscall name")
	}
	defer C.free(unsafe.Pointer(cString))

	finalStr := C.GoString(cString)
	return finalStr, nil
}

// GetSyscallFromName returns the number of a syscall by name on the kernel's
// native architecture.
// Accepts a string containing the name of a syscall.
// Returns the number of the syscall, or an error if no syscall with that name
// was found.
func GetSyscallFromName(name string) (ScmpSyscall, error) {
	cString := C.CString(name)
	defer C.free(unsafe.Pointer(cString))

	result := C.seccomp_syscall_resolve_name(cString)
	if result == scmpError {
		return 0, fmt.Errorf("could not resolve name to syscall")
	}

	return ScmpSyscall(result), nil
}

// GetSyscallFromNameByArch returns the number of a syscall by name for a given
// architecture's ABI.
// Accepts the name of a syscall and an architecture constant.
// Returns the number of the syscall, or an error if an invalid architecture is
// passed or a syscall with that name was not found.
func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
	if err := sanitizeArch(arch); err != nil {
		return 0, err
	}

	cString := C.CString(name)
	defer C.free(unsafe.Pointer(cString))

	result := C.seccomp_syscall_resolve_name_arch(arch.toNative(), cString)
	if result == scmpError {
		return 0, fmt.Errorf("could not resolve name to syscall")
	}

	return ScmpSyscall(result), nil
}

// MakeCondition creates and returns a new condition to attach to a filter rule.
// Associated rules will only match if this condition is true.
// Accepts the number the argument we are checking, and a comparison operator
// and value to compare to.
// The rule will match if argument $arg (zero-indexed) of the syscall is
// $COMPARE_OP the provided comparison value.
// Some comparison operators accept two values. Masked equals, for example,
// will mask $arg of the syscall with the second value provided (via bitwise
// AND) and then compare against the first value provided.
// For example, in the less than or equal case, if the syscall argument was
// 0 and the value provided was 1, the condition would match, as 0 is less
// than or equal to 1.
// Return either an error on bad argument or a valid ScmpCondition struct.
func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) {
	var condStruct ScmpCondition

	if comparison == CompareInvalid {
		return condStruct, fmt.Errorf("invalid comparison operator")
	} else if arg > 5 {
		return condStruct, fmt.Errorf("syscalls only have up to 6 arguments")
	} else if len(values) > 2 {
		return condStruct, fmt.Errorf("conditions can have at most 2 arguments")
	} else if len(values) == 0 {
		return condStruct, fmt.Errorf("must provide at least one value to compare against")
	}

	condStruct.Argument = arg
	condStruct.Op = comparison
	condStruct.Operand1 = values[0]
	if len(values) == 2 {
		condStruct.Operand2 = values[1]
	} else {
		condStruct.Operand2 = 0 // Unused
	}

	return condStruct, nil
}

// Utility Functions

// GetNativeArch returns architecture token representing the native kernel
// architecture
func GetNativeArch() (ScmpArch, error) {
	arch := C.seccomp_arch_native()

	return archFromNative(arch)
}

// Public Filter API

// ScmpFilter represents a filter context in libseccomp.
// A filter context is initially empty. Rules can be added to it, and it can
// then be loaded into the kernel.
type ScmpFilter struct {
	filterCtx C.scmp_filter_ctx
	valid     bool
	lock      sync.Mutex
}

// NewFilter creates and returns a new filter context.
// Accepts a default action to be taken for syscalls which match no rules in
// the filter.
// Returns a reference to a valid filter context, or nil and an error if the
// filter context could not be created or an invalid default action was given.
func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
	if err := sanitizeAction(defaultAction); err != nil {
		return nil, err
	}

	fPtr := C.seccomp_init(defaultAction.toNative())
	if fPtr == nil {
		return nil, fmt.Errorf("could not create filter")
	}

	filter := new(ScmpFilter)
	filter.filterCtx = fPtr
	filter.valid = true
	runtime.SetFinalizer(filter, filterFinalizer)

	return filter, nil
}

// IsValid determines whether a filter context is valid to use.
// Some operations (Release and Merge) render filter contexts invalid and
// consequently prevent further use.
func (f *ScmpFilter) IsValid() bool {
	f.lock.Lock()
	defer f.lock.Unlock()

	return f.valid
}

// Reset resets a filter context, removing all its existing state.
// Accepts a new default action to be taken for syscalls which do not match.
// Returns an error if the filter or action provided are invalid.
func (f *ScmpFilter) Reset(defaultAction ScmpAction) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	if err := sanitizeAction(defaultAction); err != nil {
		return err
	} else if !f.valid {
		return errBadFilter
	}

	retCode := C.seccomp_reset(f.filterCtx, defaultAction.toNative())
	if retCode != 0 {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}

// Release releases a filter context, freeing its memory. Should be called after
// loading into the kernel, when the filter is no longer needed.
// After calling this function, the given filter is no longer valid and cannot
// be used.
// Release() will be invoked automatically when a filter context is garbage
// collected, but can also be called manually to free memory.
func (f *ScmpFilter) Release() {
	f.lock.Lock()
	defer f.lock.Unlock()

	if !f.valid {
		return
	}

	f.valid = false
	C.seccomp_release(f.filterCtx)
}

// Merge merges two filter contexts.
// The source filter src will be released as part of the process, and will no
// longer be usable or valid after this call.
// To be merged, filters must NOT share any architectures, and all their
// attributes (Default Action, Bad Arch Action, No New Privs and TSync bools)
// must match.
// The filter src will be merged into the filter this is called on.
// The architectures of the src filter not present in the destination, and all
// associated rules, will be added to the destination.
// Returns an error if merging the filters failed.
func (f *ScmpFilter) Merge(src *ScmpFilter) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	src.lock.Lock()
	defer src.lock.Unlock()

	if !src.valid || !f.valid {
		return fmt.Errorf("one or more of the filter contexts is invalid or uninitialized")
	}

	// Merge the filters
	retCode := C.seccomp_merge(f.filterCtx, src.filterCtx)
	if syscall.Errno(-1*retCode) == syscall.EINVAL {
		return fmt.Errorf("filters could not be merged due to a mismatch in attributes or invalid filter")
	} else if retCode != 0 {
		return syscall.Errno(-1 * retCode)
	}

	src.valid = false

	return nil
}

// IsArchPresent checks if an architecture is present in a filter.
// If a filter contains an architecture, it uses its default action for
// syscalls which do not match rules in it, and its rules can match syscalls
// for that ABI.
// If a filter does not contain an architecture, all syscalls made to that
// kernel ABI will fail with the filter's default Bad Architecture Action
// (by default, killing the process).
// Accepts an architecture constant.
// Returns true if the architecture is present in the filter, false otherwise,
// and an error on an invalid filter context, architecture constant, or an
// issue with the call to libseccomp.
func (f *ScmpFilter) IsArchPresent(arch ScmpArch) (bool, error) {
	f.lock.Lock()
	defer f.lock.Unlock()

	if err := sanitizeArch(arch); err != nil {
		return false, err
	} else if !f.valid {
		return false, errBadFilter
	}

	retCode := C.seccomp_arch_exist(f.filterCtx, arch.toNative())
	if syscall.Errno(-1*retCode) == syscall.EEXIST {
		// -EEXIST is "arch not present"
		return false, nil
	} else if retCode != 0 {
		return false, syscall.Errno(-1 * retCode)
	}

	return true, nil
}

// AddArch adds an architecture to the filter.
// Accepts an architecture constant.
// Returns an error on invalid filter context or architecture token, or an
// issue with the call to libseccomp.
func (f *ScmpFilter) AddArch(arch ScmpArch) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	if err := sanitizeArch(arch); err != nil {
		return err
	} else if !f.valid {
		return errBadFilter
	}

	// Libseccomp returns -EEXIST if the specified architecture is already
	// present. Succeed silently in this case, as it's not fatal, and the
	// architecture is present already.
	retCode := C.seccomp_arch_add(f.filterCtx, arch.toNative())
	if retCode != 0 && syscall.Errno(-1*retCode) != syscall.EEXIST {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}

// RemoveArch removes an architecture from the filter.
// Accepts an architecture constant.
// Returns an error on invalid filter context or architecture token, or an
// issue with the call to libseccomp.
func (f *ScmpFilter) RemoveArch(arch ScmpArch) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	if err := sanitizeArch(arch); err != nil {
		return err
	} else if !f.valid {
		return errBadFilter
	}

	// Similar to AddArch, -EEXIST is returned if the arch is not present
	// Succeed silently in that case, this is not fatal and the architecture
	// is not present in the filter after RemoveArch
	retCode := C.seccomp_arch_remove(f.filterCtx, arch.toNative())
	if retCode != 0 && syscall.Errno(-1*retCode) != syscall.EEXIST {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}

// Load loads a filter context into the kernel.
// Returns an error if the filter context is invalid or the syscall failed.
func (f *ScmpFilter) Load() error {
	f.lock.Lock()
	defer f.lock.Unlock()

	if !f.valid {
		return errBadFilter
	}

	if retCode := C.seccomp_load(f.filterCtx); retCode != 0 {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}

// GetDefaultAction returns the default action taken on a syscall which does not
// match a rule in the filter, or an error if an issue was encountered
// retrieving the value.
func (f *ScmpFilter) GetDefaultAction() (ScmpAction, error) {
	action, err := f.getFilterAttr(filterAttrActDefault)
	if err != nil {
		return 0x0, err
	}

	return actionFromNative(action)
}

// GetBadArchAction returns the default action taken on a syscall for an
// architecture not in the filter, or an error if an issue was encountered
// retrieving the value.
func (f *ScmpFilter) GetBadArchAction() (ScmpAction, error) {
	action, err := f.getFilterAttr(filterAttrActBadArch)
	if err != nil {
		return 0x0, err
	}

	return actionFromNative(action)
}

// GetNoNewPrivsBit returns the current state the No New Privileges bit will be set
// to on the filter being loaded, or an error if an issue was encountered
// retrieving the value.
// The No New Privileges bit tells the kernel that new processes run with exec()
// cannot gain more privileges than the process that ran exec().
// For example, a process with No New Privileges set would be unable to exec
// setuid/setgid executables.
func (f *ScmpFilter) GetNoNewPrivsBit() (bool, error) {
	noNewPrivs, err := f.getFilterAttr(filterAttrNNP)
	if err != nil {
		return false, err
	}

	if noNewPrivs == 0 {
		return false, nil
	}

	return true, nil
}

// GetTsyncBit returns whether Thread Synchronization will be enabled on the
// filter being loaded, or an error if an issue was encountered retrieving the
// value.
// Thread Sync ensures that all members of the thread group of the calling
// process will share the same Seccomp filter set.
// Tsync is a fairly recent addition to the Linux kernel and older kernels
// lack support. If the running kernel does not support Tsync and it is
// requested in a filter, Libseccomp will not enable TSync support and will
// proceed as normal.
// This function is unavailable before v2.2 of libseccomp and will return an
// error.
func (f *ScmpFilter) GetTsyncBit() (bool, error) {
	tSync, err := f.getFilterAttr(filterAttrTsync)
	if err != nil {
		return false, err
	}

	if tSync == 0 {
		return false, nil
	}

	return true, nil
}

// SetBadArchAction sets the default action taken on a syscall for an
// architecture not in the filter, or an error if an issue was encountered
// setting the value.
func (f *ScmpFilter) SetBadArchAction(action ScmpAction) error {
	if err := sanitizeAction(action); err != nil {
		return err
	}

	return f.setFilterAttr(filterAttrActBadArch, action.toNative())
}

// SetNoNewPrivsBit sets the state of the No New Privileges bit, which will be
// applied on filter load, or an error if an issue was encountered setting the
// value.
// Filters with No New Privileges set to 0 can only be loaded if the process
// has the CAP_SYS_ADMIN capability.
func (f *ScmpFilter) SetNoNewPrivsBit(state bool) error {
	var toSet C.uint32_t = 0x0

	if state {
		toSet = 0x1
	}

	return f.setFilterAttr(filterAttrNNP, toSet)
}

// SetTsync sets whether Thread Synchronization will be enabled on the filter
// being loaded. Returns an error if setting Tsync failed, or the filter is
// invalid.
// Thread Sync ensures that all members of the thread group of the calling
// process will share the same Seccomp filter set.
// Tsync is a fairly recent addition to the Linux kernel and older kernels
// lack support. If the running kernel does not support Tsync and it is
// requested in a filter, Libseccomp will not enable TSync support and will
// proceed as normal.
// This function is unavailable before v2.2 of libseccomp and will return an
// error.
func (f *ScmpFilter) SetTsync(enable bool) error {
	var toSet C.uint32_t = 0x0

	if enable {
		toSet = 0x1
	}

	return f.setFilterAttr(filterAttrTsync, toSet)
}

// SetSyscallPriority sets a syscall's priority.
// This provides a hint to the filter generator in libseccomp about the
// importance of this syscall. High-priority syscalls are placed
// first in the filter code, and incur less overhead (at the expense of
// lower-priority syscalls).
func (f *ScmpFilter) SetSyscallPriority(call ScmpSyscall, priority uint8) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	if !f.valid {
		return errBadFilter
	}

	if retCode := C.seccomp_syscall_priority(f.filterCtx, C.int(call),
		C.uint8_t(priority)); retCode != 0 {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}

// AddRule adds a single rule for an unconditional action on a syscall.
// Accepts the number of the syscall and the action to be taken on the call
// being made.
// Returns an error if an issue was encountered adding the rule.
func (f *ScmpFilter) AddRule(call ScmpSyscall, action ScmpAction) error {
	return f.addRuleGeneric(call, action, false, nil)
}

// AddRuleExact adds a single rule for an unconditional action on a syscall.
// Accepts the number of the syscall and the action to be taken on the call
// being made.
// No modifications will be made to the rule, and it will fail to add if it
// cannot be applied to the current architecture without modification.
// The rule will function exactly as described, but it may not function identically
// (or be able to be applied to) all architectures.
// Returns an error if an issue was encountered adding the rule.
func (f *ScmpFilter) AddRuleExact(call ScmpSyscall, action ScmpAction) error {
	return f.addRuleGeneric(call, action, true, nil)
}

// AddRuleConditional adds a single rule for a conditional action on a syscall.
// Returns an error if an issue was encountered adding the rule.
// All conditions must match for the rule to match.
// There is a bug in library versions below v2.2.1 which can, in some cases,
// cause conditions to be lost when more than one are used. Consequently,
// AddRuleConditional is disabled on library versions lower than v2.2.1
func (f *ScmpFilter) AddRuleConditional(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error {
	return f.addRuleGeneric(call, action, false, conds)
}

// AddRuleConditionalExact adds a single rule for a conditional action on a
// syscall.
// No modifications will be made to the rule, and it will fail to add if it
// cannot be applied to the current architecture without modification.
// The rule will function exactly as described, but it may not function identically
// (or be able to be applied to) all architectures.
// Returns an error if an issue was encountered adding the rule.
// There is a bug in library versions below v2.2.1 which can, in some cases,
// cause conditions to be lost when more than one are used. Consequently,
// AddRuleConditionalExact is disabled on library versions lower than v2.2.1
func (f *ScmpFilter) AddRuleConditionalExact(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error {
	return f.addRuleGeneric(call, action, true, conds)
}

// ExportPFC output PFC-formatted, human-readable dump of a filter context's
// rules to a file.
// Accepts file to write to (must be open for writing).
// Returns an error if writing to the file fails.
func (f *ScmpFilter) ExportPFC(file *os.File) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	fd := file.Fd()

	if !f.valid {
		return errBadFilter
	}

	if retCode := C.seccomp_export_pfc(f.filterCtx, C.int(fd)); retCode != 0 {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}

// ExportBPF outputs Berkeley Packet Filter-formatted, kernel-readable dump of a
// filter context's rules to a file.
// Accepts file to write to (must be open for writing).
// Returns an error if writing to the file fails.
func (f *ScmpFilter) ExportBPF(file *os.File) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	fd := file.Fd()

	if !f.valid {
		return errBadFilter
	}

	if retCode := C.seccomp_export_bpf(f.filterCtx, C.int(fd)); retCode != 0 {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}
