diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-02-10 11:38:05 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2023-02-10 14:34:44 +0100 |
| commit | 50b2f41ed948a2a47420d8edc9abca2d477eccfb (patch) | |
| tree | adcef18a7dd0188e32dbf8ef4dad9d5b72f15dde /pkg/subsystem/linux | |
| parent | 0241baba08ba2fd732e46a9634434154d58092e3 (diff) | |
pkg/subsystem: detect loops on the go
This lets us reduce the amount of code in parents.go.
Diffstat (limited to 'pkg/subsystem/linux')
| -rw-r--r-- | pkg/subsystem/linux/parents.go | 46 | ||||
| -rw-r--r-- | pkg/subsystem/linux/parents_test.go | 15 |
2 files changed, 1 insertions, 60 deletions
diff --git a/pkg/subsystem/linux/parents.go b/pkg/subsystem/linux/parents.go index 6d27565bf..fdea4a62f 100644 --- a/pkg/subsystem/linux/parents.go +++ b/pkg/subsystem/linux/parents.go @@ -4,8 +4,6 @@ package linux import ( - "fmt" - "github.com/google/syzkaller/pkg/subsystem/entity" "github.com/google/syzkaller/pkg/subsystem/match" ) @@ -39,12 +37,9 @@ func setParents(matrix *match.CoincidenceMatrix, list []*entity.Subsystem) error // Demand that >= 50% paths are related. if 2*count/matrix.Count(a) >= 1 && matrix.Count(a) < matrix.Count(b) { a.Parents = append(a.Parents, b) + a.ReachableParents() // make sure we haven't created a loop } }) - // Just in case. - if loopsExist(list) { - return fmt.Errorf("there are loops in the parents relation") - } transitiveReduction(list) return nil } @@ -124,42 +119,3 @@ func transitiveReduction(list []*entity.Subsystem) { s.Parents = newParents } } - -// loopsExist is a helper method that verifies that the resulting graph has no loops. -func loopsExist(list []*entity.Subsystem) bool { - type graphNode struct { - obj *entity.Subsystem - entered bool - left bool - } - nodes := []*graphNode{} - objToNode := map[*entity.Subsystem]*graphNode{} - for _, obj := range list { - node := &graphNode{obj: obj} - nodes = append(nodes, node) - objToNode[obj] = node - } - var dfs func(*graphNode) bool - dfs = func(node *graphNode) bool { - if node.left { - return false - } - if node.entered { - // We've found a cycle. - return true - } - node.entered = true - anyLoop := false - for _, parent := range node.obj.Parents { - anyLoop = anyLoop || dfs(objToNode[parent]) - } - node.left = true - return anyLoop - } - for _, node := range nodes { - if dfs(node) { - return true - } - } - return false -} diff --git a/pkg/subsystem/linux/parents_test.go b/pkg/subsystem/linux/parents_test.go index f1942671d..dde13177d 100644 --- a/pkg/subsystem/linux/parents_test.go +++ b/pkg/subsystem/linux/parents_test.go @@ -69,21 +69,6 @@ func TestDropDuplicateSubsystems(t *testing.T) { assert.ElementsMatch(t, ret, expected) } -func TestLoopsDoExist(t *testing.T) { - a := &entity.Subsystem{} - b := &entity.Subsystem{Parents: []*entity.Subsystem{a}} - c := &entity.Subsystem{Parents: []*entity.Subsystem{b}} - a.Parents = []*entity.Subsystem{c} - assert.True(t, loopsExist([]*entity.Subsystem{a, b, c})) -} - -func TestLoopsDoNotExist(t *testing.T) { - a := &entity.Subsystem{} - b := &entity.Subsystem{Parents: []*entity.Subsystem{a}} - c := &entity.Subsystem{Parents: []*entity.Subsystem{b}} - assert.False(t, loopsExist([]*entity.Subsystem{a, b, c})) -} - func TestTransitiveReduction(t *testing.T) { // (d, c), (c, b), (b, a) // (d, a) |
