mirror of
https://github.com/reactos/syzkaller.git
synced 2025-01-30 00:04:27 +00:00
prog: glue mmap's together during minimization
This commit is contained in:
parent
6af1c1f308
commit
28571fdc32
@ -235,10 +235,71 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable) {
|
||||
// whether it is equal to the orginal program or not. If it is equivalent then
|
||||
// the simplification attempt is committed and the process continues.
|
||||
func Minimize(p0 *Prog, callIndex0 int, pred func(*Prog, int) bool) (*Prog, int) {
|
||||
if callIndex0 < 0 || callIndex0 >= len(p0.Calls) {
|
||||
panic("bad call index")
|
||||
name0 := ""
|
||||
if callIndex0 != -1 {
|
||||
if callIndex0 < 0 || callIndex0 >= len(p0.Calls) {
|
||||
panic("bad call index")
|
||||
}
|
||||
name0 = p0.Calls[callIndex0].Meta.Name
|
||||
}
|
||||
name0 := p0.Calls[callIndex0].Meta.Name
|
||||
|
||||
// Try to glue all mmap's together.
|
||||
s := analyze(nil, p0, nil)
|
||||
hi := -1
|
||||
for i := 0; i < maxPages; i++ {
|
||||
if s.pages[i] {
|
||||
hi = i
|
||||
}
|
||||
}
|
||||
if hi != -1 {
|
||||
p := p0.Clone()
|
||||
callIndex := callIndex0
|
||||
// Remove all mmaps.
|
||||
for i := 0; i < len(p.Calls); i++ {
|
||||
c := p.Calls[i]
|
||||
if i != callIndex && c.Meta.Name == "mmap" {
|
||||
copy(p.Calls[i:], p.Calls[i+1:])
|
||||
p.Calls = p.Calls[:len(p.Calls)-1]
|
||||
|
||||
for _, arg := range referencedArgs(c.Args, c.Ret) {
|
||||
arg1 := constArg(arg.Type.Default())
|
||||
replaceArg(p, arg, arg1, nil)
|
||||
}
|
||||
foreachArg(c, func(arg, _ *Arg, _ *[]*Arg) {
|
||||
if arg.Kind == ArgResult {
|
||||
delete(arg.Res.Uses, arg)
|
||||
}
|
||||
})
|
||||
|
||||
if i < callIndex {
|
||||
callIndex--
|
||||
}
|
||||
i--
|
||||
}
|
||||
}
|
||||
// Prepend uber-mmap.
|
||||
mmap := &Call{
|
||||
Meta: sys.CallMap["mmap"],
|
||||
Args: []*Arg{
|
||||
pointerArg(0, 0, nil),
|
||||
pageSizeArg(uintptr(hi)+1, 0),
|
||||
constArg(PROT_READ | PROT_WRITE),
|
||||
constArg(MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED),
|
||||
constArg(sys.InvalidFD),
|
||||
constArg(0),
|
||||
},
|
||||
}
|
||||
assignTypeAndDir(mmap)
|
||||
p.Calls = append([]*Call{mmap}, p.Calls...)
|
||||
if callIndex != -1 {
|
||||
callIndex++
|
||||
}
|
||||
if pred(p, callIndex) {
|
||||
p0 = p
|
||||
callIndex0 = callIndex
|
||||
}
|
||||
}
|
||||
|
||||
// Try to remove all calls except the last one one-by-one.
|
||||
for i := len(p0.Calls) - 1; i >= 0; i-- {
|
||||
if i == callIndex0 {
|
||||
@ -248,9 +309,8 @@ func Minimize(p0 *Prog, callIndex0 int, pred func(*Prog, int) bool) (*Prog, int)
|
||||
if i < callIndex {
|
||||
callIndex--
|
||||
}
|
||||
c := p0.Calls[i]
|
||||
p := p0.Clone()
|
||||
c = p.Calls[i]
|
||||
c := p.Calls[i]
|
||||
copy(p.Calls[i:], p.Calls[i+1:])
|
||||
p.Calls = p.Calls[:len(p.Calls)-1]
|
||||
for _, arg := range referencedArgs(c.Args, c.Ret) {
|
||||
@ -274,9 +334,11 @@ func Minimize(p0 *Prog, callIndex0 int, pred func(*Prog, int) bool) (*Prog, int)
|
||||
// - remove offsets from addresses
|
||||
// - replace file descriptors with -1
|
||||
// etc
|
||||
if callIndex0 < 0 || callIndex0 >= len(p0.Calls) || name0 != p0.Calls[callIndex0].Meta.Name {
|
||||
panic(fmt.Sprintf("bad call index after minimizatoin: ncalls=%v index=%v call=%v/%v",
|
||||
len(p0.Calls), callIndex0, name0, p0.Calls[callIndex0].Meta.Name))
|
||||
if callIndex0 != -1 {
|
||||
if callIndex0 < 0 || callIndex0 >= len(p0.Calls) || name0 != p0.Calls[callIndex0].Meta.Name {
|
||||
panic(fmt.Sprintf("bad call index after minimizatoin: ncalls=%v index=%v call=%v/%v",
|
||||
len(p0.Calls), callIndex0, name0, p0.Calls[callIndex0].Meta.Name))
|
||||
}
|
||||
}
|
||||
return p0, callIndex0
|
||||
}
|
||||
|
@ -150,10 +150,11 @@ nextTest:
|
||||
|
||||
func TestMinimize(t *testing.T) {
|
||||
tests := []struct {
|
||||
orig string
|
||||
callIndex int
|
||||
pred func(*Prog, int) bool
|
||||
result string
|
||||
orig string
|
||||
callIndex int
|
||||
pred func(*Prog, int) bool
|
||||
result string
|
||||
resultCallIndex int
|
||||
}{
|
||||
// Predicate always returns false, so must get the same program.
|
||||
{
|
||||
@ -173,6 +174,7 @@ func TestMinimize(t *testing.T) {
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"sched_yield()\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n",
|
||||
2,
|
||||
},
|
||||
// Remove a call.
|
||||
{
|
||||
@ -186,6 +188,7 @@ func TestMinimize(t *testing.T) {
|
||||
},
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n",
|
||||
1,
|
||||
},
|
||||
// Remove two dependent calls.
|
||||
{
|
||||
@ -204,6 +207,7 @@ func TestMinimize(t *testing.T) {
|
||||
return false
|
||||
},
|
||||
"sched_yield()\n",
|
||||
0,
|
||||
},
|
||||
// Remove a call and replace results.
|
||||
{
|
||||
@ -218,6 +222,7 @@ func TestMinimize(t *testing.T) {
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"write(0xffffffffffffffff, &(0x7f0000000000)=\"1155\", 0x2)\n" +
|
||||
"sched_yield()\n",
|
||||
2,
|
||||
},
|
||||
// Remove a call and replace results.
|
||||
{
|
||||
@ -225,13 +230,30 @@ func TestMinimize(t *testing.T) {
|
||||
"r0=open(&(0x7f0000000000)=\"1155\", 0x0, 0x0)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"1155\", 0x2)\n" +
|
||||
"sched_yield()\n",
|
||||
3,
|
||||
-1,
|
||||
func(p *Prog, callIndex int) bool {
|
||||
return p.String() == "mmap-write-sched_yield"
|
||||
},
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"write(0xffffffffffffffff, &(0x7f0000000000)=\"1155\", 0x2)\n" +
|
||||
"sched_yield()\n",
|
||||
-1,
|
||||
},
|
||||
// Glue several mmaps together.
|
||||
{
|
||||
"sched_yield()\n" +
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"mmap(&(0x7f0000001000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"getpid()\n" +
|
||||
"mmap(&(0x7f0000005000)=nil, (0x2000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n",
|
||||
3,
|
||||
func(p *Prog, callIndex int) bool {
|
||||
return p.String() == "mmap-sched_yield-getpid"
|
||||
},
|
||||
"mmap(&(0x7f0000000000)=nil, (0x7000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"sched_yield()\n" +
|
||||
"getpid()\n",
|
||||
2,
|
||||
},
|
||||
}
|
||||
for ti, test := range tests {
|
||||
@ -239,12 +261,16 @@ func TestMinimize(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to deserialize original program: %v", err)
|
||||
}
|
||||
p1, _ := Minimize(p, test.callIndex, test.pred)
|
||||
p1, ci := Minimize(p, test.callIndex, test.pred)
|
||||
res := p1.Serialize()
|
||||
if string(res) != test.result {
|
||||
t.Fatalf("minimization produced wrong result #%v\norig:\n%v\nexpect:\n%v\ngot:\n%v\n",
|
||||
ti, test.orig, test.result, string(res))
|
||||
}
|
||||
if ci != test.resultCallIndex {
|
||||
t.Fatalf("minimization broke call index #%v: got %v, want %v",
|
||||
ti, ci, test.resultCallIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user