seccomp

package
v0.0.0-...-205026a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2024 License: Apache-2.0, MIT Imports: 10 Imported by: 33

Documentation

Overview

Package seccomp provides generation of basic seccomp filters. Currently, only little endian systems are supported.

Index

Constants

View Source
const (
	LINUX_AUDIT_ARCH = linux.AUDIT_ARCH_X86_64
	SYS_SECCOMP      = 317
)
View Source
const RuleIP = 6

RuleIP indicates what rules in the Rule array have to be applied to instruction pointer.

Variables

DenyNewExecMappings is a set of rules that denies creating new executable mappings and converting existing ones.

View Source
var SyscallName = func(sysno uintptr) string {
	return fmt.Sprintf("syscall_%d", sysno)
}

SyscallName gives names to system calls. It is used purely for debugging purposes.

An alternate namer can be provided to the package at initialization time.

Functions

func DataAsBPFInput

func DataAsBPFInput(d *linux.SeccompData, buf []byte) bpf.Input

DataAsBPFInput converts a linux.SeccompData to a bpf.Input. It uses `buf` as scratch buffer; this buffer must be wide enough to accommodate a mashaled version of `d`.

func DefaultAction

func DefaultAction() (linux.BPFAction, error)

DefaultAction returns a sane default for a failure to match a seccomp-bpf filter. Either kill the process, or trap.

func Install

func Install(rules SyscallRules, denyRules SyscallRules, options ProgramOptions) error

Install generates BPF code based on the set of syscalls provided. It only allows syscalls that conform to the specification. Syscalls that violate the specification will trigger RET_KILL_PROCESS. If RET_KILL_PROCESS is not supported, violations will trigger RET_TRAP instead. RET_KILL_THREAD is not used because it only kills the offending thread and often keeps the sentry hanging.

denyRules describes forbidden syscalls. rules describes allowed syscalls. denyRules is executed before rules.

Be aware that RET_TRAP sends SIGSYS to the process and it may be ignored, making it possible for the process to continue running after a violation. However, it will leave a SECCOMP audit event trail behind. In any case, the syscall is still blocked from executing.

func SetFilter

func SetFilter(instrs []bpf.Instruction) error

SetFilter installs the given BPF program.

func SetFilterInChild

func SetFilterInChild(instrs []bpf.Instruction) unix.Errno

SetFilterInChild is equivalent to SetFilter, but:

  • It is safe to call after runtime.syscall_runtime_AfterForkInChild.

  • It requires that the calling goroutine cannot be moved to another thread, which either requires that runtime.LockOSThread() is in effect or that the caller is in fact in a fork()ed child process.

  • Since fork()ed child processes cannot perform heap allocation, it returns a unix.Errno rather than an error.

  • The race instrumentation has to be disabled for all functions that are called in a forked child.

Types

type And

type And []SyscallRule

And expresses an "AND" (a conjunction) over a set of `SyscallRule`s. An `And` may not be empty.

func (And) Copy

func (and And) Copy() SyscallRule

Copy implements `SyscallRule.Copy`.

func (And) Recurse

func (and And) Recurse(fn func(SyscallRule) SyscallRule)

Recurse implements `SyscallRule.Recurse`.

func (And) Render

func (and And) Render(program *syscallProgram, labelSet *labelSet)

Render implements `SyscallRule.Render`.

func (And) String

func (and And) String() string

String implements `SyscallRule.String`.

type AnyValue

type AnyValue struct{}

AnyValue is marker to indicate any value will be accepted. It implements ValueMatcher.

func (AnyValue) InterestingValues

func (av AnyValue) InterestingValues() []uint64

InterestingValues implements `halfValueMatcher.InterestingValues`.

func (AnyValue) Render

func (av AnyValue) Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

Render implements `ValueMatcher.Render`.

func (AnyValue) Repr

func (av AnyValue) Repr() string

Repr implements `ValueMatcher.Repr`.

func (AnyValue) String

func (AnyValue) String() string

String implements `ValueMatcher.String`.

type BuildStats

type BuildStats struct {
	// SizeBeforeOptimizations and SizeAfterOptimizations correspond to the
	// number of instructions in the program before vs after optimization.
	SizeBeforeOptimizations, SizeAfterOptimizations int

	// BuildDuration is the amount of time it took to build the program (before
	// BPF bytecode optimizations).
	BuildDuration time.Duration

	// RuleOptimizeDuration is the amount of time it took to run SyscallRule
	// optimizations.
	RuleOptimizeDuration time.Duration

	// BPFOptimizeDuration is the amount of time it took to run BPF bytecode
	// optimizations.
	BPFOptimizeDuration time.Duration
}

BuildStats contains information about seccomp program generation.

func BuildProgram

func BuildProgram(rules []RuleSet, options ProgramOptions) ([]bpf.Instruction, BuildStats, error)

BuildProgram builds a BPF program from the given map of actions to matching SyscallRules. The single generated program covers all provided RuleSets.

type EqualTo

type EqualTo uintptr

EqualTo specifies a value that needs to be strictly matched. It implements ValueMatcher.

func (EqualTo) InterestingValues

func (eq EqualTo) InterestingValues() []uint64

InterestingValues implements `halfValueMatcher.InterestingValues`.

func (EqualTo) Render

func (eq EqualTo) Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

Render implements `ValueMatcher.Render`.

func (EqualTo) Repr

func (eq EqualTo) Repr() string

Repr implements `ValueMatcher.Repr`.

func (EqualTo) String

func (eq EqualTo) String() string

String implements `ValueMatcher.String`.

type GreaterThan

type GreaterThan uintptr

GreaterThan specifies a value that needs to be strictly smaller.

func (GreaterThan) InterestingValues

func (gt GreaterThan) InterestingValues() []uint64

InterestingValues implements `halfValueMatcher.InterestingValues`.

func (GreaterThan) Render

func (gt GreaterThan) Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

Render implements `ValueMatcher.Render`.

func (GreaterThan) Repr

func (gt GreaterThan) Repr() string

Repr implements `ValueMatcher.Repr`.

func (GreaterThan) String

func (gt GreaterThan) String() string

String implements `ValueMatcher.String`.

type GreaterThanOrEqual

type GreaterThanOrEqual uintptr

GreaterThanOrEqual specifies a value that needs to be smaller or equal.

func (GreaterThanOrEqual) InterestingValues

func (ge GreaterThanOrEqual) InterestingValues() []uint64

InterestingValues implements `halfValueMatcher.InterestingValues`.

func (GreaterThanOrEqual) Render

func (ge GreaterThanOrEqual) Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

Render implements `ValueMatcher.Render`.

func (GreaterThanOrEqual) Repr

func (ge GreaterThanOrEqual) Repr() string

Repr implements `ValueMatcher.Repr`.

func (GreaterThanOrEqual) String

func (ge GreaterThanOrEqual) String() string

String implements `ValueMatcher.String`.

type LessThan

type LessThan uintptr

LessThan specifies a value that needs to be strictly greater.

func (LessThan) InterestingValues

func (lt LessThan) InterestingValues() []uint64

InterestingValues implements `halfValueMatcher.InterestingValues`.

func (LessThan) Render

func (lt LessThan) Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

Render implements `ValueMatcher.Render`.

func (LessThan) Repr

func (lt LessThan) Repr() string

Repr implements `ValueMatcher.Repr`.

func (LessThan) String

func (lt LessThan) String() string

String implements `ValueMatcher.String`.

type LessThanOrEqual

type LessThanOrEqual uintptr

LessThanOrEqual specifies a value that needs to be greater or equal.

func (LessThanOrEqual) InterestingValues

func (le LessThanOrEqual) InterestingValues() []uint64

InterestingValues implements `halfValueMatcher.InterestingValues`.

func (LessThanOrEqual) Render

func (le LessThanOrEqual) Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

Render implements `ValueMatcher.Render`.

func (LessThanOrEqual) Repr

func (le LessThanOrEqual) Repr() string

Repr implements `ValueMatcher.Repr`.

func (LessThanOrEqual) String

func (le LessThanOrEqual) String() string

String implements `ValueMatcher.String`.

type MatchAll

type MatchAll struct{}

MatchAll implements `SyscallRule` and matches everything.

func (MatchAll) Copy

func (MatchAll) Copy() SyscallRule

Copy implements `SyscallRule.Copy`.

func (MatchAll) Recurse

func (MatchAll) Recurse(func(SyscallRule) SyscallRule)

Recurse implements `SyscallRule.Recurse`.

func (MatchAll) Render

func (MatchAll) Render(program *syscallProgram, labelSet *labelSet)

Render implements `SyscallRule.Render`.

func (MatchAll) String

func (MatchAll) String() string

String implements `SyscallRule.String`.

type NonNegativeFD

type NonNegativeFD struct{}

NonNegativeFD ensures that an FD argument is a non-negative int32.

func (NonNegativeFD) InterestingValues

func (nnfd NonNegativeFD) InterestingValues() []uint64

InterestingValues implements `halfValueMatcher.InterestingValues`.

func (NonNegativeFD) Render

func (nnfd NonNegativeFD) Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

Render implements `ValueMatcher.Render`.

func (NonNegativeFD) Repr

func (NonNegativeFD) Repr() string

Repr implements `ValueMatcher.Repr`.

func (NonNegativeFD) String

func (NonNegativeFD) String() string

String implements `ValueMatcher.String`.

type NotEqual

type NotEqual uintptr

NotEqual specifies a value that is strictly not equal.

func (NotEqual) InterestingValues

func (ne NotEqual) InterestingValues() []uint64

InterestingValues implements `halfValueMatcher.InterestingValues`.

func (NotEqual) Render

func (ne NotEqual) Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

Render implements `ValueMatcher.Render`.

func (NotEqual) Repr

func (ne NotEqual) Repr() string

Repr implements `ValueMatcher.Repr`.

func (NotEqual) String

func (ne NotEqual) String() string

String implements `ValueMatcher.String`.

type Or

type Or []SyscallRule

Or expresses an "OR" (a disjunction) over a set of `SyscallRule`s. An `Or` may not be empty.

func (Or) Copy

func (or Or) Copy() SyscallRule

Copy implements `SyscallRule.Copy`.

func (Or) Recurse

func (or Or) Recurse(fn func(SyscallRule) SyscallRule)

Recurse implements `SyscallRule.Recurse`.

func (Or) Render

func (or Or) Render(program *syscallProgram, labelSet *labelSet)

Render implements `SyscallRule.Render`.

func (Or) String

func (or Or) String() string

String implements `SyscallRule.String`.

type PerArg

type PerArg [7]ValueMatcher // 6 arguments + RIP

PerArg implements SyscallRule and verifies the syscall arguments and RIP.

For example:

rule := PerArg{
	EqualTo(linux.ARCH_GET_FS | linux.ARCH_SET_FS), // arg0
}

func (PerArg) Copy

func (pa PerArg) Copy() SyscallRule

Copy implements `SyscallRule.Copy`.

func (PerArg) Recurse

func (PerArg) Recurse(fn func(SyscallRule) SyscallRule)

Recurse implements `SyscallRule.Recurse`.

func (PerArg) Render

func (pa PerArg) Render(program *syscallProgram, labelSet *labelSet)

Render implements `SyscallRule.Render`.

func (PerArg) String

func (pa PerArg) String() string

String implements `SyscallRule.String`.

type ProgramOptions

type ProgramOptions struct {
	// DefaultAction is the action returned when none of the rules match.
	DefaultAction linux.BPFAction

	// BadArchAction is the action returned when the architecture of the
	// syscall structure input doesn't match the one the program expects.
	BadArchAction linux.BPFAction

	// Optimize specifies whether optimizations should be applied to the
	// syscall rules and generated BPF bytecode.
	Optimize bool

	// HotSyscalls is the set of syscall numbers that are the hottest,
	// where "hotness" refers to frequency (regardless of the amount of
	// computation that the kernel will do handling them, and regardless of
	// the complexity of the syscall rule for this).
	// It should only contain very hot syscalls (i.e. any syscall that is
	// called >10% of the time out of all syscalls made).
	// It is ordered from most frequent to least frequent.
	HotSyscalls []uintptr
}

ProgramOptions configure a seccomp program.

func DefaultProgramOptions

func DefaultProgramOptions() ProgramOptions

DefaultProgramOptions returns the default program options.

type RuleSet

type RuleSet struct {
	Rules  SyscallRules
	Action linux.BPFAction

	// Vsyscall indicates that a check is made for a function being called
	// from kernel mappings. This is where the vsyscall page is located
	// (and typically) emulated, so this RuleSet will not match any
	// functions not dispatched from the vsyscall page.
	Vsyscall bool
}

RuleSet is a set of rules and associated action.

type SyscallRule

type SyscallRule interface {
	// Render renders the syscall rule in the given `program`.
	// The emitted instructions **must** end up jumping to either
	// `labelSet.Matched()` or `labelSet.Mismatched()`; they may
	// not "fall through" to whatever instructions will be added
	// next into the program.
	Render(program *syscallProgram, labelSet *labelSet)

	// Copy returns a copy of this `SyscallRule`.
	Copy() SyscallRule

	// Recurse should call the given function on all `SyscallRule`s that are
	// part of this `SyscallRule`, and should replace them with the returned
	// `SyscallRule`. For example, conjunctive rules should call the given
	// function on each of the `SyscallRule`s that they are ANDing, replacing
	// them with the rule returned by the function.
	Recurse(func(SyscallRule) SyscallRule)

	// String returns a human-readable string representing what the rule does.
	String() string
}

SyscallRule expresses a set of rules to verify the arguments of a specific syscall.

type SyscallRules

type SyscallRules struct {
	// contains filtered or unexported fields
}

SyscallRules maps syscall numbers to their corresponding rules.

For example:

rules := MakeSyscallRules(map[uintptr]SyscallRule{
	syscall.SYS_FUTEX: Or{
		PerArg{
			AnyValue{},
			EqualTo(linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG),
		},
		PerArg{
			AnyValue{},
			EqualTo(linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG),
		},
	},
	syscall.SYS_GETPID: MatchAll{},
})

func MakeSyscallRules

func MakeSyscallRules(rules map[uintptr]SyscallRule) SyscallRules

MakeSyscallRules returns a new SyscallRules with the given set of rules.

func NewSyscallRules

func NewSyscallRules() SyscallRules

NewSyscallRules returns a new SyscallRules.

func (SyscallRules) Add

func (sr SyscallRules) Add(sysno uintptr, r SyscallRule) SyscallRules

Add adds the given rule. It will create a new entry for a new syscall, otherwise it will append to the existing rules. Returns itself for chainability.

func (SyscallRules) Copy

func (sr SyscallRules) Copy() SyscallRules

Copy returns a deep copy of these SyscallRules.

func (SyscallRules) ForSingleArgument

func (sr SyscallRules) ForSingleArgument(sysno uintptr, argNum int, fn func(ValueMatcher) error) error

ForSingleArgument runs the given function on the `ValueMatcher` rules for a single specific syscall argument of the given syscall number. If the function returns an error, it will be propagated along with some details as to which rule caused the error to be returned. ForSingleArgument also returns an error if there are no rules defined for the given syscall number, or if at least one rule for this syscall number is not either a `PerArg` rule or a rule with children rules (as this would indicate that the `PerArg` rules alone may not be a good representation of the entire set of rules for this system call).

func (SyscallRules) Get

func (sr SyscallRules) Get(sysno uintptr) SyscallRule

Get returns the rule defined for the given syscall number.

func (SyscallRules) Has

func (sr SyscallRules) Has(sysno uintptr) bool

Has returns whether there is a rule defined for the given syscall number.

func (SyscallRules) Merge

func (sr SyscallRules) Merge(other SyscallRules) SyscallRules

Merge merges the given SyscallRules. Returns itself for chainability.

func (SyscallRules) Remove

func (sr SyscallRules) Remove(sysno uintptr)

Remove clears the syscall rule for the given syscall number. It will panic if there is no syscall rule for this syscall number.

func (SyscallRules) Set

func (sr SyscallRules) Set(sysno uintptr, r SyscallRule) SyscallRules

Set sets the rule for the given syscall number. Panics if there is already a rule for this syscall number. This is useful for deterministic rules where the set of syscall rules is added in multiple chunks but is known to never overlap by syscall number. Returns itself for chainability.

func (SyscallRules) Size

func (sr SyscallRules) Size() int

Size returns the number of syscall numbers for which a rule is defined.

func (SyscallRules) String

func (sr SyscallRules) String() string

String returns a string representation of the syscall rules, one syscall per line.

func (SyscallRules) UsefulTestCases

func (sr SyscallRules) UsefulTestCases() []linux.SeccompData

UsefulTestCases returns a best-effort list of test cases that may be useful in fuzzing this set of rules.

type ValueMatcher

type ValueMatcher interface {
	// String returns a human-readable representation of the match rule.
	// If the returned string contains "VAL", it will be replaced with
	// the symbolic name of the value being matched against.
	String() string

	// Repr returns a string that will be used for asserting equality between
	// two `ValueMatcher` instances. It must therefore be unique to the
	// `ValueMatcher` implementation and to its parameters.
	// It must not contain the character ";".
	Repr() string

	// Render should add rules to the given program that verify the value
	// loadable from `value` matches this rule or not.
	// The rules should indicate this by either jumping to `labelSet.Matched()`
	// or `labelSet.Mismatched()`. They may not fall through.
	Render(program *syscallProgram, labelSet *labelSet, value matchedValue)

	// InterestingValues returns a list of values that may be interesting to
	// test this `ValueMatcher` against.
	InterestingValues() []uint64
}

ValueMatcher verifies a numerical value, typically a syscall argument or RIP value.

func BitsAllowlist

func BitsAllowlist(allowlist uintptr) ValueMatcher

BitsAllowlist specifies that a value can only have non-zero bits within the mask specified in `allowlist`. It implements `ValueMatcher`.

func MaskedEqual

func MaskedEqual(mask, value uintptr) ValueMatcher

MaskedEqual specifies a value that matches the input after the input is masked (bitwise &) against the given mask. Can be used to verify that input only includes certain approved flags.

Directories

Path Synopsis
precompiledseccomp
example
Package example defines two seccomp programs ("example_program1" and "example_program2") to be embedded in the `usage` package in this directory.
Package example defines two seccomp programs ("example_program1" and "example_program2") to be embedded in the `usage` package in this directory.
example/usage
Package usage shows how to use precompiled seccomp-bpf programs.
Package usage shows how to use precompiled seccomp-bpf programs.
Test binary used to test that seccomp filters are properly constructed and indeed kill the process on violation.
Test binary used to test that seccomp filters are properly constructed and indeed kill the process on violation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL