seccomp: Make empty And and Or invalid.

This prevents accidentally creating them.

PiperOrigin-RevId: 578333240
This commit is contained in:
Etienne Perot
2023-10-31 16:16:59 -07:00
committed by gVisor bot
parent 41614ddfa1
commit a44ddf5be5
2 changed files with 57 additions and 7 deletions
+10 -4
View File
@@ -337,11 +337,14 @@ func (MatchAll) Render(program *syscallProgram, labelSet *labelSet) {
func (MatchAll) String() string { return "true" }
// Or expresses an "OR" (a disjunction) over a set of `SyscallRule`s.
// If an Or is empty, it will not match anything.
// An `Or` may not be empty.
type Or []SyscallRule
// Render implements `SyscallRule.Render`.
func (or Or) Render(program *syscallProgram, labelSet *labelSet) {
if len(or) == 0 {
panic("Or expression cannot be empty")
}
// If `len(or) == 1`, this will be optimized away to be the same as
// rendering the single rule in the disjunction.
for i, rule := range or {
@@ -358,7 +361,7 @@ func (or Or) Render(program *syscallProgram, labelSet *labelSet) {
func (or Or) String() string {
switch len(or) {
case 0:
return "false"
return "invalid"
case 1:
return or[0].String()
default:
@@ -376,11 +379,14 @@ 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.
// An `And` may not be empty.
type And []SyscallRule
// Render implements `SyscallRule.Render`.
func (and And) Render(program *syscallProgram, labelSet *labelSet) {
if len(and) == 0 {
panic("And expression cannot be empty")
}
// 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 {
@@ -397,7 +403,7 @@ func (and And) Render(program *syscallProgram, labelSet *labelSet) {
func (and And) String() string {
switch len(and) {
case 0:
return "true"
return "invalid"
case 1:
return and[0].String()
default:
+47 -3
View File
@@ -72,6 +72,7 @@ func TestBasic(t *testing.T) {
for _, test := range []struct {
name string
ruleSets []RuleSet
wantPanic bool
defaultAction linux.BPFAction
badArchAction linux.BPFAction
specs []spec
@@ -305,6 +306,18 @@ func TestBasic(t *testing.T) {
},
},
},
{
name: "empty Or is invalid",
ruleSets: []RuleSet{
{
Rules: MakeSyscallRules(map[uintptr]SyscallRule{
1: Or{},
}),
Action: linux.SECCOMP_RET_ALLOW,
},
},
wantPanic: true,
},
{
name: "And of multiple rules",
ruleSets: []RuleSet{
@@ -342,6 +355,18 @@ func TestBasic(t *testing.T) {
},
},
},
{
name: "empty And is invalid",
ruleSets: []RuleSet{
{
Rules: MakeSyscallRules(map[uintptr]SyscallRule{
1: And{},
}),
Action: linux.SECCOMP_RET_ALLOW,
},
},
wantPanic: true,
},
{
name: "EqualTo",
ruleSets: []RuleSet{
@@ -905,9 +930,28 @@ func TestBasic(t *testing.T) {
},
} {
t.Run(test.name, func(t *testing.T) {
instrs, _, err := BuildProgram(test.ruleSets, test.defaultAction, test.badArchAction)
if err != nil {
t.Fatalf("BuildProgram() got error: %v", err)
var instrs []bpf.Instruction
var panicErr any
func() {
t.Helper()
defer func() {
panicErr = recover()
t.Helper()
}()
var err error
instrs, _, err = BuildProgram(test.ruleSets, test.defaultAction, test.badArchAction)
if err != nil {
t.Fatalf("BuildProgram() got error: %v", err)
}
}()
if test.wantPanic {
if panicErr == nil {
t.Fatal("BuildProgram did not panick")
}
return
}
if panicErr != nil {
t.Fatalf("BuildProgram unexpectedly panicked: %v", panicErr)
}
p, err := bpf.Compile(instrs, true /* optimize */)
if err != nil {