Class: SeccompTools::Explain::PathFacts

Inherits:
Object
  • Object
show all
Defined in:
lib/seccomp-tools/explain/path_facts.rb

Overview

The seccomp reading of one leaf's path condition: which syscall number it pins or bounds, which architecture value it pins, and which facts remain for the rule's when clause. The path is immutable, so every query is derived once, eagerly.

Constant Summary collapse

SYS =
Const::BPF::SeccompData::SYS_NUMBER
ARCH =
Const::BPF::SeccompData::ARCH
U32_MAX =

Largest 32-bit value, the upper end of an unconstrained syscall-number range.

0xffffffff

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ PathFacts

Returns a new instance of PathFacts.

Parameters:



45
46
47
48
49
50
51
# File 'lib/seccomp-tools/explain/path_facts.rb', line 45

def initialize(path)
  @path = path
  @sys_eq = eq(SYS)
  @arch_eq = eq(ARCH)
  @sys_range = compute_sys_range
  @residual = compute_residual
end

Instance Attribute Details

#arch_eqInteger? (readonly)

The architecture value the path pins with ==, or nil.

Returns:

  • (Integer?)


22
23
24
# File 'lib/seccomp-tools/explain/path_facts.rb', line 22

def arch_eq
  @arch_eq
end

#residualArray<Symbolic::Constraint> (readonly)

Constraints not already conveyed by the syscall-number / architecture presentation.

Consumed (dropped): ==, != and range facts on sys_number - the named/ranged buckets and the "any other syscall" default wording express them; +==+/+!=+ facts on arch - the per-architecture sections and the "any other" fall-through express them; and any non-+==+ fact on a word that some == on the same path already pins (it is then redundant - a contradicting combination would have been pruned as infeasible).

Everything else is kept so a kernel-valid check is never silently dropped: bit-tests on an unpinned sys_number (e.g. an odd/even dispatch), bit-tests or ranges on arch (e.g. testing the __AUDIT_ARCH_64BIT flag instead of pinning one value), and any comparison against a register rather than a constant.

Returns:



42
43
44
# File 'lib/seccomp-tools/explain/path_facts.rb', line 42

def residual
  @residual
end

#sys_eqInteger? (readonly)

The syscall number the path pins with ==, or nil.

Returns:

  • (Integer?)


19
20
21
# File 'lib/seccomp-tools/explain/path_facts.rb', line 19

def sys_eq
  @sys_eq
end

#sys_rangeArray(Integer, Integer?)? (readonly)

The [lo, hi] range (inclusive; hi is nil when unbounded) all bound facts restrict the syscall number to, or nil when there is no lower bound. An upper bound alone does not make a range rule: it is the complement of one (e.g. the sys < 0x40000000 side of an x32 guard) and reads naturally as part of the default bucket.

Returns:

  • (Array(Integer, Integer?)?)


28
29
30
# File 'lib/seccomp-tools/explain/path_facts.rb', line 28

def sys_range
  @sys_range
end

Instance Method Details

#arch_consistent?(val) ⇒ Boolean

Is the path consistent with the architecture being val? Every constant arch fact is evaluated against val.

Parameters:

  • val (Integer)

Returns:

  • (Boolean)


57
58
59
60
61
62
63
# File 'lib/seccomp-tools/explain/path_facts.rb', line 57

def arch_consistent?(val)
  @path.all? do |c|
    next true unless c.plain_data_fact?(ARCH)

    Symbolic::Constraint.evaluate(val, c.op, c.rhs.val)
  end
end

#catch_all?Boolean

Does the path match no syscall, no range, and no arguments - i.e. describe the filter's catch-all behavior?

Returns:

  • (Boolean)


68
69
70
# File 'lib/seccomp-tools/explain/path_facts.rb', line 68

def catch_all?
  sys_eq.nil? && sys_range.nil? && residual.empty?
end