prog: add special mutation for binary flags

This commit is contained in:
Veronica Radu 2019-08-07 18:00:46 +02:00 committed by Dmitry Vyukov
parent e5701ed16c
commit aff9e255cd
8 changed files with 126 additions and 11 deletions

View File

@ -175,7 +175,7 @@
#if GOARCH_64
#define GOARCH "64"
#define SYZ_REVISION "8c0a50a6c63e5bd297e9f6421864685e1fd7dc96"
#define SYZ_REVISION "aaee55a3532998a140b25dc52cc113c4de048dd2"
#define SYZ_EXECUTOR_USES_FORK_SERVER 0
#define SYZ_EXECUTOR_USES_SHMEM 0
#define SYZ_PAGE_SIZE 4096

View File

@ -16311,6 +16311,12 @@ const call_t syscalls[] = {
{"foo$fmt4", 0},
{"foo$fmt5", 0},
{"minimize$0", 0},
{"mutate$array", 0},
{"mutate$flags", 0},
{"mutate$flags2", 0},
{"mutate$flags3", 0},
{"mutate$integer", 0},
{"mutate$integer2", 0},
{"mutate0", 0},
{"mutate1", 0},
{"mutate2", 0},

View File

@ -234,7 +234,31 @@ func (t *IntType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Ca
}
func (t *FlagsType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool) {
return mutateInt(r, s, arg)
a := arg.(*ConstArg)
for oldVal := a.Val; oldVal == a.Val; {
// Generate a new value.
if r.nOutOf(1, 5) {
a.Val = r.flags(t.Vals, t.BitMask, 0)
continue
}
if !t.BitMask || (t.BitMask && r.nOutOf(1, 4)) {
a.Val = r.flags(t.Vals, t.BitMask, a.Val)
continue
}
for stop := false; !stop; stop = r.oneOf(3) {
idx := r.rand(len(t.Vals))
if r.bin() {
a.Val |= 1 << t.Vals[idx]
} else {
a.Val &= ^(1 << t.Vals[idx])
}
}
}
return
}
func (t *LenType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool) {

View File

@ -11,6 +11,32 @@ import (
"testing"
)
func TestMutationFlags(t *testing.T) {
tests := [][2]string{
// Mutate flags (bitmask = true).
{
`r0 = mutate$flags(&(0x7f0000000000)="2e2f66696c653000", 0x0, 0x1, 0x1)`,
`r0 = mutate$flags(&(0x7f0000000000)="2e2f66696c653000", 0x20, 0x1, 0x9)`,
},
{
`r0 = mutate$flags2(&(0x7f0000000000)="2e2f66696c653000", 0x0)`,
`r0 = mutate$flags2(&(0x7f0000000000)="2e2f66696c653000", 0xd9)`,
},
// Mutate flags (bitmask = false).
{
`r0 = mutate$flags3(&(0x7f0000000000)="2e2f66696c653000", 0x0)`,
`r0 = mutate$flags3(&(0x7f0000000000)="2e2f66696c653000", 0xddddddddeeeeeeee)`,
},
{
`r0 = mutate$flags3(&(0x7f0000000000)="2e2f66696c653000", 0xddddddddeeeeeeee)`,
`r0 = mutate$flags3(&(0x7f0000000000)="2e2f66696c653000", 0xaaaaaaaaaaaaaaaa)`,
},
}
runMutationTests(t, tests)
}
func TestClone(t *testing.T) {
target, rs, iters := initTest(t)
for i := 0; i < iters; i++ {
@ -68,7 +94,6 @@ func TestMutateCorpus(t *testing.T) {
}
func TestMutateTable(t *testing.T) {
target := initTargetTest(t, "test", "64")
tests := [][2]string{
// Insert a call.
{`
@ -151,6 +176,13 @@ mutate8(0x2)
mutate8(0xffffffffffffffff)
`},
}
runMutationTests(t, tests)
}
func runMutationTests(t *testing.T, tests [][2]string) {
target := initTargetTest(t, "test", "64")
for ti, test := range tests {
test := test
t.Run(fmt.Sprint(ti), func(t *testing.T) {

View File

@ -137,15 +137,17 @@ func (r *randGen) randPageCount() (n uint64) {
return
}
func (r *randGen) flags(vv []uint64) (v uint64) {
// Change a flag value or generate a new one.
func (r *randGen) flags(vv []uint64, bitmask bool, oldVal uint64) (v uint64) {
v = oldVal
switch {
case r.nOutOf(90, 111):
case (bitmask && r.nOutOf(7, 10)) || (!bitmask && r.nOutOf(1, 5)):
for stop := false; !stop; stop = r.bin() {
v |= vv[r.rand(len(vv))]
v |= vv[r.rand(len(vv))] // prioritized when bitmask = true
}
case r.nOutOf(10, 21):
v = vv[r.rand(len(vv))]
case r.nOutOf(10, 11):
case (bitmask && r.nOutOf(2, 3)) || (!bitmask && r.nOutOf(7, 8)):
v = vv[r.rand(len(vv))] // prioritized when bitmask = false
case r.bin():
v = 0
default:
v = r.rand64()
@ -675,7 +677,7 @@ func (a *VmaType) generate(r *randGen, s *state) (arg Arg, calls []*Call) {
}
func (a *FlagsType) generate(r *randGen, s *state) (arg Arg, calls []*Call) {
return MakeConstArg(a, r.flags(a.Vals)), nil
return MakeConstArg(a, r.flags(a.Vals, a.BitMask, 0)), nil
}
func (a *ConstType) generate(r *randGen, s *state) (arg Arg, calls []*Call) {

View File

@ -641,6 +641,43 @@ var syscalls_64 = []*Syscall{
&ProcType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "proc", FldName: "a0", TypeSize: 8}}, ValuesStart: 10, ValuesPerProc: 2},
&ProcType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "proc", FldName: "a1", TypeSize: 8, IsOptional: true}}, ValuesStart: 10, ValuesPerProc: 2},
}},
{Name: "mutate$array", CallName: "mutate", MissingArgs: 6, Args: []Type{
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "i1", TypeSize: 8}}},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "i2", TypeSize: 8}}, Kind: 2, RangeEnd: 536870911},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "vec", TypeSize: 8}, Type: &ArrayType{TypeCommon: TypeCommon{TypeName: "array", IsVarlen: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 1}}},
}},
{Name: "mutate$flags", CallName: "mutate", MissingArgs: 5, Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "filename", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename", IsVarlen: true}, Kind: 3}},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "i1", TypeSize: 8}}},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "b1", TypeSize: 2}}, Kind: 2, RangeEnd: 1},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "bitmask_flags", FldName: "flags", TypeSize: 8}}, Vals: []uint64{1, 8, 16}, BitMask: true},
}},
{Name: "mutate$flags2", CallName: "mutate", MissingArgs: 7, Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "filename", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename", IsVarlen: true}, Kind: 3}},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "bitmask_flags2", FldName: "flags", TypeSize: 8}}, Vals: []uint64{1, 2, 4, 8, 16, 32, 64, 128}, BitMask: true},
}},
{Name: "mutate$flags3", CallName: "mutate", MissingArgs: 7, Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "filename", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename", IsVarlen: true}, Kind: 3}},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "open_flags2", FldName: "flags", TypeSize: 8}}, Vals: []uint64{12297829382473034410, 12297829382759365563, 13527612320720337851, 13527612321006669004, 14757395258967641292, 14757395259253972445, 15987178197214944733, 15987178197501275886, 17216961135462248174, 17216961135748579327, 18446744073709551615}},
}},
{Name: "mutate$integer", CallName: "mutate", Args: []Type{
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "b1", TypeSize: 1}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "b2", TypeSize: 1}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "b3", TypeSize: 1}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "b4", TypeSize: 1}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "b5", TypeSize: 1}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "b6", TypeSize: 1}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "b7", TypeSize: 1}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "b8", TypeSize: 1}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "i9", TypeSize: 8}}},
}},
{Name: "mutate$integer2", CallName: "mutate", MissingArgs: 4, Args: []Type{
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "b1", TypeSize: 8}}, Kind: 2, RangeEnd: 1},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "i1", TypeSize: 8}}},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "i2", TypeSize: 4}}},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "i3", TypeSize: 2}}, Kind: 2, RangeEnd: 8},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "i4", TypeSize: 1}}, Kind: 2, RangeEnd: 8},
}},
{Name: "mutate0", CallName: "mutate0"},
{Name: "mutate1", CallName: "mutate1"},
{Name: "mutate2", CallName: "mutate2"},
@ -1023,6 +1060,7 @@ var consts_64 = []ConstValue{
{Name: "SYS_fallback"},
{Name: "SYS_foo"},
{Name: "SYS_minimize"},
{Name: "SYS_mutate"},
{Name: "SYS_mutate0"},
{Name: "SYS_mutate1"},
{Name: "SYS_mutate2"},
@ -1039,4 +1077,4 @@ var consts_64 = []ConstValue{
{Name: "SYS_unsupported"},
}
const revision_64 = "8c0a50a6c63e5bd297e9f6421864685e1fd7dc96"
const revision_64 = "aaee55a3532998a140b25dc52cc113c4de048dd2"

View File

@ -734,7 +734,19 @@ mutate6(fd fd, data ptr[in, array[int8]], size bytesize[data])
mutate7(a0 ptr[in, string], a1 len[a0])
mutate8(a0 proc[100, 4, opt])
# Test for arguments mutation
mutate$integer(b1 bool8, b2 bool8, b3 bool8, b4 bool8, b5 bool8, b6 bool8, b7 bool8, b8 bool8, i9 int64)
mutate$integer2(b1 bool64, i1 int64, i2 int32, i3 int16[0x0:0x8], i4 int8[0x0:0x8])
mutate$flags(filename ptr[in, filename], i1 int64, b1 bool16, flags flags[bitmask_flags])
mutate$flags2(filename ptr[in, filename], flags flags[bitmask_flags2])
mutate$flags3(filename ptr[in, filename], flags flags[open_flags2])
mutate$array(i1 int64, i2 int64[0x0:0x1fffffff], vec ptr[in, array[int32[0:1]]])
open_flags = 0xabababababababab, 0xcdcdcdcdcdcdcdcd
open_flags2 = 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaabbbbbbbb, 0xbbbbbbbbbbbbbbbb, 0xbbbbbbbbcccccccc, 0xcccccccccccccccc, 0xccccccccdddddddd, 0xdddddddddddddddd, 0xddddddddeeeeeeee, 0xeeeeeeeeeeeeeeee, 0xeeeeeeeeffffffff, 0xffffffffffffffff
bitmask_flags = 0x1, 0x8, 0x10
bitmask_flags2 = 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
# Minimization tests.

View File

@ -1,4 +1,5 @@
SYS_foo = 0
SYS_mutate = 0
SYS_mutate0 = 0
SYS_mutate1 = 0
SYS_mutate2 = 0