aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prog/prio.go120
-rw-r--r--prog/prio_test.go10
-rw-r--r--syz-manager/html.go4
-rw-r--r--tools/syz-showprio/showprio.go4
4 files changed, 53 insertions, 85 deletions
diff --git a/prog/prio.go b/prog/prio.go
index 25ecfd41a..2c3436151 100644
--- a/prog/prio.go
+++ b/prog/prio.go
@@ -24,38 +24,27 @@ import (
// Note: the current implementation is very basic, there is no theory behind any
// constants.
-func (target *Target) CalculatePriorities(corpus []*Prog) [][]float32 {
+func (target *Target) CalculatePriorities(corpus []*Prog) [][]int32 {
static := target.calcStaticPriorities()
if len(corpus) != 0 {
dynamic := target.calcDynamicPrio(corpus)
for i, prios := range dynamic {
+ dst := static[i]
for j, p := range prios {
- static[i][j] *= p
+ dst[j] = dst[j] * p / prioHigh
}
}
}
return static
}
-func (target *Target) calcStaticPriorities() [][]float32 {
+func (target *Target) calcStaticPriorities() [][]int32 {
uses := target.calcResourceUsage()
- prios := make([][]float32, len(target.Syscalls))
+ prios := make([][]int32, len(target.Syscalls))
for i := range prios {
- prios[i] = make([]float32, len(target.Syscalls))
+ prios[i] = make([]int32, len(target.Syscalls))
}
- var keys []string
- for key := range uses {
- keys = append(keys, key)
- }
- sort.Strings(keys)
- for _, key := range keys {
- weights := make([]weights, 0, len(uses[key]))
- for _, weight := range uses[key] {
- weights = append(weights, weight)
- }
- sort.Slice(weights, func(i, j int) bool {
- return weights[i].call < weights[j].call
- })
+ for _, weights := range uses {
for _, w0 := range weights {
for _, w1 := range weights {
if w0.call == w1.call {
@@ -64,14 +53,14 @@ func (target *Target) calcStaticPriorities() [][]float32 {
}
// The static priority is assigned based on the direction of arguments. A higher priority will be
// assigned when c0 is a call that produces a resource and c1 a call that uses that resource.
- prios[w0.call][w1.call] += w0.inout*w1.in + 0.7*w0.inout*w1.inout
+ prios[w0.call][w1.call] += w0.inout*w1.in*3/2 + w0.inout*w1.inout
}
}
}
normalizePrio(prios)
// The value assigned for self-priority (call wrt itself) have to be high, but not too high.
for c0, pp := range prios {
- pp[c0] = 0.9
+ pp[c0] = prioHigh * 9 / 10
}
return prios
}
@@ -83,42 +72,42 @@ func (target *Target) calcResourceUsage() map[string]map[int]weights {
switch a := t.(type) {
case *ResourceType:
if target.AuxResources[a.Desc.Name] {
- noteUsage(uses, c, 0.1, ctx.Dir, "res%v", a.Desc.Name)
+ noteUsage(uses, c, 1, ctx.Dir, "res%v", a.Desc.Name)
} else {
str := "res"
for i, k := range a.Desc.Kind {
str += "-" + k
- w := 1.0
+ w := int32(10)
if i < len(a.Desc.Kind)-1 {
- w = 0.2
+ w = 2
}
- noteUsage(uses, c, float32(w), ctx.Dir, str)
+ noteUsage(uses, c, w, ctx.Dir, str)
}
}
case *PtrType:
if _, ok := a.Elem.(*StructType); ok {
- noteUsage(uses, c, 1.0, ctx.Dir, "ptrto-%v", a.Elem.Name())
+ noteUsage(uses, c, 10, ctx.Dir, "ptrto-%v", a.Elem.Name())
}
if _, ok := a.Elem.(*UnionType); ok {
- noteUsage(uses, c, 1.0, ctx.Dir, "ptrto-%v", a.Elem.Name())
+ noteUsage(uses, c, 10, ctx.Dir, "ptrto-%v", a.Elem.Name())
}
if arr, ok := a.Elem.(*ArrayType); ok {
- noteUsage(uses, c, 1.0, ctx.Dir, "ptrto-%v", arr.Elem.Name())
+ noteUsage(uses, c, 10, ctx.Dir, "ptrto-%v", arr.Elem.Name())
}
case *BufferType:
switch a.Kind {
case BufferBlobRand, BufferBlobRange, BufferText:
case BufferString:
if a.SubKind != "" {
- noteUsage(uses, c, 0.2, ctx.Dir, fmt.Sprintf("str-%v", a.SubKind))
+ noteUsage(uses, c, 2, ctx.Dir, fmt.Sprintf("str-%v", a.SubKind))
}
case BufferFilename:
- noteUsage(uses, c, 1.0, DirIn, "filename")
+ noteUsage(uses, c, 10, DirIn, "filename")
default:
panic("unknown buffer kind")
}
case *VmaType:
- noteUsage(uses, c, 0.5, ctx.Dir, "vma")
+ noteUsage(uses, c, 5, ctx.Dir, "vma")
case *IntType:
switch a.Kind {
case IntPlain, IntRange:
@@ -132,11 +121,11 @@ func (target *Target) calcResourceUsage() map[string]map[int]weights {
type weights struct {
call int
- in float32
- inout float32
+ in int32
+ inout int32
}
-func noteUsage(uses map[string]map[int]weights, c *Syscall, weight float32, dir Dir, str string, args ...interface{}) {
+func noteUsage(uses map[string]map[int]weights, c *Syscall, weight int32, dir Dir, str string, args ...interface{}) {
id := fmt.Sprintf(str, args...)
if uses[id] == nil {
uses[id] = make(map[int]weights)
@@ -154,17 +143,15 @@ func noteUsage(uses map[string]map[int]weights, c *Syscall, weight float32, dir
uses[id][c.ID] = callWeight
}
-func (target *Target) calcDynamicPrio(corpus []*Prog) [][]float32 {
- prios := make([][]float32, len(target.Syscalls))
+func (target *Target) calcDynamicPrio(corpus []*Prog) [][]int32 {
+ prios := make([][]int32, len(target.Syscalls))
for i := range prios {
- prios[i] = make([]float32, len(target.Syscalls))
+ prios[i] = make([]int32, len(target.Syscalls))
}
for _, p := range corpus {
for idx0, c0 := range p.Calls {
for _, c1 := range p.Calls[idx0+1:] {
- id0 := c0.Meta.ID
- id1 := c1.Meta.ID
- prios[id0][id1] += 1.0
+ prios[c0.Meta.ID][c1.Meta.ID]++
}
}
}
@@ -172,43 +159,22 @@ func (target *Target) calcDynamicPrio(corpus []*Prog) [][]float32 {
return prios
}
-// normalizePrio assigns some minimal priorities to calls with zero priority,
-// and then normalizes priorities to 0.1..1 range.
-func normalizePrio(prios [][]float32) {
+const (
+ prioLow = 10
+ prioHigh = 1000
+)
+
+// normalizePrio normalizes priorities to [prioLow..prioHigh] range.
+func normalizePrio(prios [][]int32) {
for _, prio := range prios {
- max := float32(0)
- min := float32(1e10)
- nzero := 0
+ max := int32(1)
for _, p := range prio {
if max < p {
max = p
}
- if p != 0 && min > p {
- min = p
- }
- if p == 0 {
- nzero++
- }
- }
- if nzero != 0 {
- min /= 2 * float32(nzero)
- }
- if min == max {
- max = 0
}
for i, p := range prio {
- if max == 0 {
- prio[i] = 1
- continue
- }
- if p == 0 {
- p = min
- }
- p = (p-min)/(max-min)*0.9 + 0.1
- if p > 1 {
- p = 1
- }
- prio[i] = p
+ prio[i] = prioLow + p*(prioHigh-prioLow)/max
}
}
}
@@ -217,7 +183,7 @@ func normalizePrio(prios [][]float32) {
// based on call-to-call priorities and a set of enabled syscalls.
type ChoiceTable struct {
target *Target
- runs [][]int
+ runs [][]int32
calls []*Syscall
}
@@ -252,16 +218,16 @@ func (target *Target) BuildChoiceTable(corpus []*Prog, enabled map[*Syscall]bool
}
}
prios := target.CalculatePriorities(corpus)
- run := make([][]int, len(target.Syscalls))
+ run := make([][]int32, len(target.Syscalls))
for i := range run {
if !enabled[target.Syscalls[i]] {
continue
}
- run[i] = make([]int, len(target.Syscalls))
- sum := 0
+ run[i] = make([]int32, len(target.Syscalls))
+ var sum int32
for j := range run[i] {
if enabled[target.Syscalls[j]] {
- sum += int(prios[i][j] * 1000)
+ sum += prios[i][j]
}
run[i][j] = sum
}
@@ -282,8 +248,10 @@ func (ct *ChoiceTable) choose(r *rand.Rand, bias int) int {
panic("disabled syscall")
}
run := ct.runs[bias]
- x := r.Intn(run[len(run)-1]) + 1
- res := sort.SearchInts(run, x)
+ x := int32(r.Intn(int(run[len(run)-1])) + 1)
+ res := sort.Search(len(run), func(i int) bool {
+ return run[i] >= x
+ })
if !ct.Enabled(res) {
panic("selected disabled syscall")
}
diff --git a/prog/prio_test.go b/prog/prio_test.go
index 902dbf3d4..21eb7f147 100644
--- a/prog/prio_test.go
+++ b/prog/prio_test.go
@@ -10,15 +10,15 @@ import (
)
func TestNormalizePrio(t *testing.T) {
- prios := [][]float32{
+ prios := [][]int32{
{2, 2, 2},
{1, 2, 4},
{1, 2, 0},
}
- want := [][]float32{
- {1, 1, 1},
- {0.1, 0.4, 1},
- {0.4, 1, 0.1},
+ want := [][]int32{
+ {1000, 1000, 1000},
+ {257, 505, 1000},
+ {505, 1000, 10},
}
t.Logf("had: %+v", prios)
normalizePrio(prios)
diff --git a/syz-manager/html.go b/syz-manager/html.go
index 8431be248..91b3cc68d 100644
--- a/syz-manager/html.go
+++ b/syz-manager/html.go
@@ -823,7 +823,7 @@ type UIPrioData struct {
type UIPrio struct {
Call string
- Prio float32
+ Prio int32
}
var prioTemplate = html.CreatePage(`
@@ -842,7 +842,7 @@ var prioTemplate = html.CreatePage(`
</tr>
{{range $p := $.Prios}}
<tr>
- <td>{{printf "%.4f" $p.Prio}}</td>
+ <td>{{printf "%5v" $p.Prio}}</td>
<td><a href='/prio?call={{$p.Call}}'>{{$p.Call}}</a></td>
</tr>
{{end}}
diff --git a/tools/syz-showprio/showprio.go b/tools/syz-showprio/showprio.go
index 3f4cf452f..0729f4388 100644
--- a/tools/syz-showprio/showprio.go
+++ b/tools/syz-showprio/showprio.go
@@ -48,13 +48,13 @@ func main() {
showPriorities(enabled, target.CalculatePriorities(corpus), target)
}
-func showPriorities(calls []string, prios [][]float32, target *prog.Target) {
+func showPriorities(calls []string, prios [][]int32, target *prog.Target) {
printLine(append([]string{"CALLS"}, calls...))
for _, callRow := range calls {
line := []string{callRow}
for _, callCol := range calls {
val := prios[target.SyscallMap[callRow].ID][target.SyscallMap[callCol].ID]
- line = append(line, fmt.Sprintf("%.2f", val))
+ line = append(line, fmt.Sprintf("%v", val))
}
printLine(line)
}