Class: SeccompTools::Explain::QwordFusion
- Inherits:
-
Object
- Object
- SeccompTools::Explain::QwordFusion
- Defined in:
- lib/seccomp-tools/explain/qword.rb
Overview
A 64-bit field of seccomp_data (+instruction_pointer+ or an argument) is two 32-bit words,
and filters check them separately. This class fuses such word facts back into 64-bit ones
(Qword), both within one path condition (#fold) and across the sibling or-branches
libseccomp compiles a 64-bit range comparison into (#merge_or).
Constant Summary collapse
- BASES =
Byte offsets of the 64-bit fields whose two 32-bit words this class fuses.
Const::BPF::SeccompData::QWORD_BASES
- OR_MERGE =
How the extra facts of two sibling or-branches fuse into one 64-bit comparison: one branch holds a strict high-word fact
hi <hi_op> H(+hi_op+ is>,<or!=, normalized by #strict) and the otherhi == H && lo <lo_op> L; keyed by[hi_op, lo_op], they are exactlyfield <fused op> (H << 32 | L). This is the shape libseccomp compiles SCMP_CMP_GT/GE/LT/LE/NE argument comparisons into. { %i[> >] => :>, %i[> >=] => :>=, %i[< <] => :<, %i[< <=] => :<=, %i[!= !=] => :!= }.freeze
Instance Method Summary collapse
-
#base_of(offset) ⇒ Object
The byte offset of the 64-bit field that the word at
offsetbelongs to. -
#fold(constraints) ⇒ Array<Symbolic::Constraint, Qword>
Fuses the 32-bit word facts of one path condition into whole-field Qwords; facts that do not form a fusable pair pass through unchanged.
-
#hi_off(base) ⇒ Object
The byte offset of the high 32-bit word of the 64-bit field at
base. -
#initialize(arch) ⇒ QwordFusion
constructor
A new instance of QwordFusion.
-
#lo_off(base) ⇒ Object
The byte offset of the low 32-bit word of the 64-bit field at
base. -
#merge_or(lists) ⇒ Array<Array<Symbolic::Constraint, Qword>>
Fuses sibling or-branches that together express one 64-bit comparison, repeatedly until nothing fuses; branches that do not pair up are returned untouched.
Constructor Details
#initialize(arch) ⇒ QwordFusion
Returns a new instance of QwordFusion.
42 43 44 |
# File 'lib/seccomp-tools/explain/qword.rb', line 42 def initialize(arch) @hi_first = Const::Endian.big?(arch) end |
Instance Method Details
#base_of(offset) ⇒ Object
The byte offset of the 64-bit field that the word at offset belongs to.
57 58 59 |
# File 'lib/seccomp-tools/explain/qword.rb', line 57 def base_of(offset) offset - (offset % 8) end |
#fold(constraints) ⇒ Array<Symbolic::Constraint, Qword>
Fuses the 32-bit word facts of one path condition into whole-field SeccompTools::Explain::Qwords; facts that do not form a fusable pair pass through unchanged.
71 72 73 74 75 76 77 78 79 |
# File 'lib/seccomp-tools/explain/qword.rb', line 71 def fold(constraints) plan = qword_plan(constraints) constraints.filter_map do |c| action = plan[c] next if action == :drop action || c end end |
#hi_off(base) ⇒ Object
The byte offset of the high 32-bit word of the 64-bit field at base.
52 53 54 |
# File 'lib/seccomp-tools/explain/qword.rb', line 52 def hi_off(base) @hi_first ? base : base + 4 end |
#lo_off(base) ⇒ Object
The byte offset of the low 32-bit word of the 64-bit field at base.
47 48 49 |
# File 'lib/seccomp-tools/explain/qword.rb', line 47 def lo_off(base) @hi_first ? base + 4 : base end |
#merge_or(lists) ⇒ Array<Array<Symbolic::Constraint, Qword>>
Fuses sibling or-branches that together express one 64-bit comparison, repeatedly until nothing fuses; branches that do not pair up are returned untouched. See #fuse_pair for the shape of a fusable pair.
91 92 93 94 95 |
# File 'lib/seccomp-tools/explain/qword.rb', line 91 def merge_or(lists) lists = lists.dup # own a mutable copy; the caller's array is left untouched loop { break unless merge_one_pair!(lists) } lists end |