aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/report/impact_score.go
blob: dec727d1d3f51200c8a1611b72c3489951f692f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2025 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package report

import (
	"sort"

	"github.com/google/syzkaller/pkg/report/crash"
)

// impactOrder represent an ordering of bug impact severity. The earlier
// entries are considered more severe.
var impactOrder = []crash.Type{
	// Highest Priority (Direct Memory Corruption - Write)
	crash.KASANUseAfterFreeWrite,
	crash.KASANWrite,
	// High Priority (Memory Corruption)
	crash.KASANInvalidFree,
	crash.KFENCEInvalidFree,
	crash.KFENCEMemoryCorruption,
	crash.KASANUseAfterFreeRead,
	crash.KMSANUseAfterFreeRead,
	crash.KASANRead,
	crash.KFENCERead,
	crash.MemorySafetyUBSAN, // array-index-out-of-bounds, at least Read.
	crash.KCSANAssert,
	crash.RefcountWARNING, // we had a few UAFs in the past
	crash.KASANNullPtrDerefWrite,
	crash.KASANNullPtrDerefRead,
	crash.NullPtrDerefBUG,
	// Medium Priority (Infoleaks, Uninitialized Memory, Corruptions)
	crash.KMSANInfoLeak,
	crash.MemorySafetyBUG,
	crash.KMSANUninitValue,
	// Medium Priority (Concurrency and Severe Instability)
	crash.KCSANDataRace,
	crash.AtomicSleep, // high potential for system-wide deadlocks
	crash.LockdepBug,  // indicates potential deadlocks and hangs
	// Lower-Medium Priority (Denial of Service and General Bugs)
	crash.MemoryLeak, // a form of DoS
	crash.DoS,
	crash.Hang,
	// Unknown types shouldn't be mentioned here. If bug goes to Unknown it means we need better parsing/processing.
	// You can find them at the end of the scored list on the bug enumeration pages.
	// crash.KMSANUnknown
	// crash.KASANUnknown
	// crash.KCSANUnknown
}

// TitlesToImpact converts a bug title(s) to an impact score.
// If several titles provided, it returns the highest score.
// A higher score indicates a more severe impact.
// -1 means unknown.
func TitlesToImpact(title string, otherTitles ...string) int {
	maxImpact := -1
	for _, t := range append([]string{title}, otherTitles...) {
		typ := crash.TitleToType(t)
		for i, t := range impactOrder {
			if typ == t {
				maxImpact = max(maxImpact, len(impactOrder)-i)
			}
		}
	}
	return maxImpact
}

type TitleFreqRank struct {
	Title string
	Count int
	Total int
	Rank  int
}

func ExplainTitleStat(ts *titleStat) []*TitleFreqRank {
	titleCount := map[string]int{}
	var totalCount int
	ts.visit(func(count int, titles ...string) {
		uniq := map[string]bool{}
		for _, title := range titles {
			uniq[title] = true
		}
		for title := range uniq {
			titleCount[title] += count
		}
		totalCount += count
	})
	var res []*TitleFreqRank
	for title, count := range titleCount {
		res = append(res, &TitleFreqRank{
			Title: title,
			Count: count,
			Total: totalCount,
			Rank:  TitlesToImpact(title),
		})
	}
	sort.Slice(res, func(l, r int) bool {
		if res[l].Rank != res[r].Rank {
			return res[l].Rank > res[r].Rank
		}
		lTitle, rTitle := res[l].Title, res[r].Title
		if titleCount[lTitle] != titleCount[rTitle] {
			return titleCount[lTitle] > titleCount[rTitle]
		}
		return lTitle < rTitle
	})
	return res
}