seccomp: Add And as a logical AND between multiple syscall rules.

PiperOrigin-RevId: 578283208
This commit is contained in:
Etienne Perot
2023-10-31 13:26:34 -07:00
committed by gVisor bot
parent 3d7d82f8f5
commit 41614ddfa1
2 changed files with 76 additions and 0 deletions
+39
View File
@@ -375,6 +375,45 @@ func (or Or) String() string {
}
}
// And expresses an "AND" (a conjunction) over a set of `SyscallRule`s.
// If an And is empty, it will match anything.
type And []SyscallRule
// Render implements `SyscallRule.Render`.
func (and And) Render(program *syscallProgram, labelSet *labelSet) {
// If `len(and) == 1`, this will be optimized away to be the same as
// rendering the single rule in the conjunction.
for i, rule := range and {
frag := program.Record()
nextRuleLabel := labelSet.NewLabel()
rule.Render(program, labelSet.Push(fmt.Sprintf("and[%d]", i), nextRuleLabel, labelSet.Mismatched()))
frag.MustHaveJumpedTo(nextRuleLabel, labelSet.Mismatched())
program.Label(nextRuleLabel)
}
program.JumpTo(labelSet.Matched())
}
// String implements `SyscallRule.String`.
func (and And) String() string {
switch len(and) {
case 0:
return "true"
case 1:
return and[0].String()
default:
var sb strings.Builder
sb.WriteRune('(')
for i, rule := range and {
if i != 0 {
sb.WriteString(" && ")
}
sb.WriteString(rule.String())
}
sb.WriteRune(')')
return sb.String()
}
}
// merge merges `rule1` and `rule2`, simplifying `MatchAll` and `Or` rules.
func merge(rule1, rule2 SyscallRule) SyscallRule {
_, rule1IsMatchAll := rule1.(MatchAll)
+37
View File
@@ -305,6 +305,43 @@ func TestBasic(t *testing.T) {
},
},
},
{
name: "And of multiple rules",
ruleSets: []RuleSet{
{
Rules: MakeSyscallRules(map[uintptr]SyscallRule{
1: And{
PerArg{
NotEqual(0xf),
},
PerArg{
NotEqual(0xe),
},
},
}),
Action: linux.SECCOMP_RET_ALLOW,
},
},
defaultAction: linux.SECCOMP_RET_TRAP,
badArchAction: linux.SECCOMP_RET_KILL_THREAD,
specs: []spec{
{
desc: "hit first rule",
data: linux.SeccompData{Nr: 1, Arch: LINUX_AUDIT_ARCH, Args: [6]uint64{0xf}},
want: linux.SECCOMP_RET_TRAP,
},
{
desc: "hit 2nd rule",
data: linux.SeccompData{Nr: 1, Arch: LINUX_AUDIT_ARCH, Args: [6]uint64{0xe}},
want: linux.SECCOMP_RET_TRAP,
},
{
desc: "hit neither rule",
data: linux.SeccompData{Nr: 1, Arch: LINUX_AUDIT_ARCH, Args: [6]uint64{0xd}},
want: linux.SECCOMP_RET_ALLOW,
},
},
},
{
name: "EqualTo",
ruleSets: []RuleSet{