aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2016-09-13 12:43:03 +0200
committerAndrey Konovalov <andreyknvl@google.com>2016-09-19 15:55:28 +0200
commit705a657fbe15b0b271490b18c8167b078a2ca16d (patch)
tree3177dfcc7bdaab3d326a69388383cc0904c91f00
parent9decc82111be1754889e46944a6c6bfdfefdbeb7 (diff)
Better blob mutation
-rw-r--r--prog/mutation.go176
1 files changed, 170 insertions, 6 deletions
diff --git a/prog/mutation.go b/prog/mutation.go
index a00f64e43..35c9ba65d 100644
--- a/prog/mutation.go
+++ b/prog/mutation.go
@@ -6,6 +6,7 @@ package prog
import (
"fmt"
"math/rand"
+ "unsafe"
"github.com/google/syzkaller/sys"
)
@@ -370,19 +371,75 @@ func mutationArgs(c *Call) (args, bases []*Arg, parents []*[]*Arg) {
return
}
+func swap16(v uint16) uint16 {
+ v0 := byte(v >> 0)
+ v1 := byte(v >> 8)
+ v = 0
+ v |= uint16(v1) << 0
+ v |= uint16(v0) << 8
+ return v
+}
+
+func swap32(v uint32) uint32 {
+ v0 := byte(v >> 0)
+ v1 := byte(v >> 8)
+ v2 := byte(v >> 16)
+ v3 := byte(v >> 24)
+ v = 0
+ v |= uint32(v3) << 0
+ v |= uint32(v2) << 8
+ v |= uint32(v1) << 16
+ v |= uint32(v0) << 24
+ return v
+}
+
+func swap64(v uint64) uint64 {
+ v0 := byte(v >> 0)
+ v1 := byte(v >> 8)
+ v2 := byte(v >> 16)
+ v3 := byte(v >> 24)
+ v4 := byte(v >> 32)
+ v5 := byte(v >> 40)
+ v6 := byte(v >> 48)
+ v7 := byte(v >> 56)
+ v = 0
+ v |= uint64(v7) << 0
+ v |= uint64(v6) << 8
+ v |= uint64(v5) << 16
+ v |= uint64(v4) << 24
+ v |= uint64(v3) << 32
+ v |= uint64(v2) << 40
+ v |= uint64(v1) << 48
+ v |= uint64(v0) << 56
+ return v
+}
+
func mutateData(r *randGen, data []byte) []byte {
+ const maxInc = 35
for stop := false; !stop; stop = r.bin() {
r.choose(
- 1, func() {
+ 100, func() {
+ // Append byte.
data = append(data, byte(r.rand(256)))
},
- 1, func() {
+ 100, func() {
+ // Remove byte.
+ if len(data) == 0 {
+ return
+ }
+ i := r.Intn(len(data))
+ copy(data[i:], data[i+1:])
+ data = data[:len(data)-1]
+ },
+ 100, func() {
+ // Replace byte with random value.
if len(data) == 0 {
return
}
data[r.Intn(len(data))] = byte(r.rand(256))
},
- 1, func() {
+ 100, func() {
+ // Flip bit in byte.
if len(data) == 0 {
return
}
@@ -390,13 +447,120 @@ func mutateData(r *randGen, data []byte) []byte {
bit := r.Intn(8)
data[byt] ^= 1 << uint(bit)
},
- 1, func() {
+ 100, func() {
+ // Swap two bytes.
+ if len(data) < 2 {
+ return
+ }
+ i1 := r.Intn(len(data))
+ i2 := r.Intn(len(data))
+ data[i1], data[i2] = data[i2], data[i1]
+ },
+ 100, func() {
+ // Add / subtract from a byte.
if len(data) == 0 {
return
}
i := r.Intn(len(data))
- copy(data[i:], data[i+1:])
- data = data[:len(data)-1]
+ delta := byte(r.rand(2*maxInc+1) - maxInc)
+ if delta == 0 {
+ delta = 1
+ }
+ data[i] += delta
+ },
+ 100, func() {
+ // Add / subtract from a uint16.
+ if len(data) < 2 {
+ return
+ }
+ i := r.Intn(len(data) - 1)
+ p := (*uint16)(unsafe.Pointer(&data[i]))
+ delta := uint16(r.rand(2*maxInc+1) - maxInc)
+ if delta == 0 {
+ delta = 1
+ }
+ if r.bin() {
+ *p += delta
+ } else {
+ *p = swap16(swap16(*p) + delta)
+ }
+ },
+ 100, func() {
+ // Add / subtract from a uint32.
+ if len(data) < 4 {
+ return
+ }
+ i := r.Intn(len(data) - 3)
+ p := (*uint32)(unsafe.Pointer(&data[i]))
+ delta := uint32(r.rand(2*maxInc+1) - maxInc)
+ if delta == 0 {
+ delta = 1
+ }
+ if r.bin() {
+ *p += delta
+ } else {
+ *p = swap32(swap32(*p) + delta)
+ }
+ },
+ 100, func() {
+ // Add / subtract from a uint64.
+ if len(data) < 8 {
+ return
+ }
+ i := r.Intn(len(data) - 7)
+ p := (*uint64)(unsafe.Pointer(&data[i]))
+ delta := uint64(r.rand(2*maxInc+1) - maxInc)
+ if delta == 0 {
+ delta = 1
+ }
+ if r.bin() {
+ *p += delta
+ } else {
+ *p = swap64(swap64(*p) + delta)
+ }
+ },
+ 100, func() {
+ // Set byte to an interesting value.
+ if len(data) == 0 {
+ return
+ }
+ data[r.Intn(len(data))] = byte(r.randInt())
+ },
+ 100, func() {
+ // Set uint16 to an interesting value.
+ if len(data) < 2 {
+ return
+ }
+ i := r.Intn(len(data) - 1)
+ value := uint16(r.randInt())
+ if r.bin() {
+ value = swap16(value)
+ }
+ *(*uint16)(unsafe.Pointer(&data[i])) = value
+ },
+ 100, func() {
+ // Set uint32 to an interesting value.
+ if len(data) < 4 {
+ return
+ }
+ i := r.Intn(len(data) - 3)
+ value := uint32(r.randInt())
+ if r.bin() {
+ value = swap32(value)
+ }
+ *(*uint32)(unsafe.Pointer(&data[i])) = value
+ },
+ 100, func() {
+ // Set uint64 to an interesting value.
+ if len(data) < 8 {
+ return
+ }
+ i := r.Intn(len(data) - 7)
+ value := uint64(r.randInt())
+ if r.bin() {
+ value = swap64(value)
+ }
+ *(*uint64)(unsafe.Pointer(&data[i])) = value
},
)
}