prog: refactor target.MakeMmap

Make MakeMmap return more than 1 call.
This is a preparation for future changes.
Also remove addr/size as they are effectively
always the same and can be inferred from the target
(will also conflict with the future changes).
Also rename to MakeDataMmap to better represent
the new purpose: it's just some arbitrary mmap,
but rather mapping of the data segment.
This commit is contained in:
Dmitry Vyukov 2020-04-18 12:36:52 +02:00
parent ea36da8271
commit 67234372ef
15 changed files with 51 additions and 48 deletions

View File

@ -32,7 +32,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
return nil, err
}
mmapProg := p.Target.GenerateUberMmapProg()
mmapProg := p.Target.DataMmapProg()
mmapCalls, _, err := ctx.generateProgCalls(mmapProg, false)
if err != nil {
return nil, err

View File

@ -92,7 +92,7 @@ func TestExecute(t *testing.T) {
defer env.Close()
for i := 0; i < 10; i++ {
p := target.GenerateSimpleProg()
p := target.DataMmapProg()
opts := &ExecOpts{
Flags: flag,
}
@ -139,7 +139,7 @@ func TestParallel(t *testing.T) {
env.Close()
errs <- err
}()
p := target.GenerateSimpleProg()
p := target.DataMmapProg()
opts := &ExecOpts{}
output, info, hanged, err := env.Exec(opts, p)
if err != nil {

View File

@ -589,19 +589,12 @@ func (target *Target) GenerateAllSyzProg(rs rand.Source) *Prog {
return p
}
// GenerateSimpleProg generates the simplest non-empty program for testing
// (e.g. containing a single mmap).
func (target *Target) GenerateSimpleProg() *Prog {
// DataMmapProg creates program that maps data segment.
// Also used for testing as the simplest program.
func (target *Target) DataMmapProg() *Prog {
return &Prog{
Target: target,
Calls: []*Call{target.MakeMmap(0, target.PageSize)},
}
}
func (target *Target) GenerateUberMmapProg() *Prog {
return &Prog{
Target: target,
Calls: []*Call{target.MakeMmap(0, target.NumPages*target.PageSize)},
Calls: target.MakeDataMmap(),
}
}

View File

@ -25,8 +25,8 @@ type Target struct {
Structs []*KeyedStruct
Consts []ConstValue
// MakeMmap creates call that maps [addr, addr+size) memory range.
MakeMmap func(addr, size uint64) *Call
// MakeDataMmap creates calls that mmaps target data memory range.
MakeDataMmap func() []*Call
// Neutralize neutralizes harmful calls by transforming them into non-harmful ones
// (e.g. an ioctl that turns off console output is turned into ioctl that turns on output).

View File

@ -16,7 +16,7 @@ func InitTarget(target *prog.Target) {
arch := &arch{
MAP_FIXED: target.GetConst("MAP_FIXED"),
}
target.MakeMmap = targets.MakePosixMmap(target, true)
target.MakeDataMmap = targets.MakePosixMmap(target, true)
target.Neutralize = arch.Neutralize
}

View File

@ -13,7 +13,7 @@ func InitTarget(target *prog.Target) {
unix: targets.MakeUnixNeutralizer(target),
}
target.MakeMmap = targets.MakePosixMmap(target, true)
target.MakeDataMmap = targets.MakePosixMmap(target, true)
target.Neutralize = arch.unix.Neutralize
}

View File

@ -11,5 +11,5 @@ import (
)
func InitTarget(target *prog.Target) {
target.MakeMmap = targets.MakeSyzMmap(target)
target.MakeDataMmap = targets.MakeSyzMmap(target)
}

View File

@ -48,7 +48,7 @@ func InitTarget(target *prog.Target) {
ARCH_SET_GS: target.ConstMap["ARCH_SET_GS"],
}
target.MakeMmap = targets.MakePosixMmap(target, true)
target.MakeDataMmap = targets.MakePosixMmap(target, true)
target.Neutralize = arch.neutralize
target.SpecialTypes = map[string]func(g *prog.Gen, typ prog.Type, old prog.Arg) (
prog.Arg, []*prog.Call){

View File

@ -13,7 +13,7 @@ func InitTarget(target *prog.Target) {
unix: targets.MakeUnixNeutralizer(target),
}
target.MakeMmap = targets.MakePosixMmap(target, false)
target.MakeDataMmap = targets.MakePosixMmap(target, false)
target.Neutralize = arch.unix.Neutralize
}

View File

@ -19,7 +19,7 @@ func InitTarget(target *prog.Target) {
S_IFCHR: target.GetConst("S_IFCHR"),
}
target.MakeMmap = targets.MakePosixMmap(target, false)
target.MakeDataMmap = targets.MakePosixMmap(target, false)
target.Neutralize = arch.neutralize
target.AnnotateCall = arch.annotateCall
}

View File

@ -7,8 +7,8 @@ import (
"github.com/google/syzkaller/prog"
)
// MakePosixMmap creates a "normal" posix mmap call that maps [addr, addr+size) range.
func MakePosixMmap(target *prog.Target, exec bool) func(addr, size uint64) *prog.Call {
// MakePosixMmap creates a "normal" posix mmap call that maps the target data range.
func MakePosixMmap(target *prog.Target, exec bool) func() []*prog.Call {
meta := target.SyscallMap["mmap"]
prot := target.GetConst("PROT_READ") | target.GetConst("PROT_WRITE")
if exec {
@ -16,9 +16,10 @@ func MakePosixMmap(target *prog.Target, exec bool) func(addr, size uint64) *prog
}
flags := target.GetConst("MAP_ANONYMOUS") | target.GetConst("MAP_PRIVATE") | target.GetConst("MAP_FIXED")
const invalidFD = ^uint64(0)
return func(addr, size uint64) *prog.Call {
size := target.NumPages * target.PageSize
return func() []*prog.Call {
args := []prog.Arg{
prog.MakeVmaPointerArg(meta.Args[0], addr, size),
prog.MakeVmaPointerArg(meta.Args[0], 0, size),
prog.MakeConstArg(meta.Args[1], size),
prog.MakeConstArg(meta.Args[2], prot),
prog.MakeConstArg(meta.Args[3], flags),
@ -32,24 +33,28 @@ func MakePosixMmap(target *prog.Target, exec bool) func(addr, size uint64) *prog
}
args = append(args, prog.MakeConstArg(meta.Args[i], 0))
return &prog.Call{
mmapCall := &prog.Call{
Meta: meta,
Args: args,
Ret: prog.MakeReturnArg(meta.Ret),
}
return []*prog.Call{mmapCall}
}
}
func MakeSyzMmap(target *prog.Target) func(addr, size uint64) *prog.Call {
func MakeSyzMmap(target *prog.Target) func() []*prog.Call {
meta := target.SyscallMap["syz_mmap"]
return func(addr, size uint64) *prog.Call {
return &prog.Call{
Meta: meta,
Args: []prog.Arg{
prog.MakeVmaPointerArg(meta.Args[0], addr, size),
prog.MakeConstArg(meta.Args[1], size),
size := target.NumPages * target.PageSize
return func() []*prog.Call {
return []*prog.Call{
&prog.Call{
Meta: meta,
Args: []prog.Arg{
prog.MakeVmaPointerArg(meta.Args[0], 0, size),
prog.MakeConstArg(meta.Args[1], size),
},
Ret: prog.MakeReturnArg(meta.Ret),
},
Ret: prog.MakeReturnArg(meta.Ret),
}
}
}

View File

@ -9,5 +9,5 @@ import (
)
func InitTarget(target *prog.Target) {
target.MakeMmap = targets.MakeSyzMmap(target)
target.MakeDataMmap = targets.MakeSyzMmap(target)
}

View File

@ -9,5 +9,5 @@ import (
)
func InitTarget(target *prog.Target) {
target.MakeMmap = targets.MakeSyzMmap(target)
target.MakeDataMmap = targets.MakeSyzMmap(target)
}

View File

@ -9,16 +9,18 @@ import (
func InitTarget(target *prog.Target) {
arch := &arch{
target: target,
virtualAllocSyscall: target.SyscallMap["VirtualAlloc"],
MEM_COMMIT: target.GetConst("MEM_COMMIT"),
MEM_RESERVE: target.GetConst("MEM_RESERVE"),
PAGE_EXECUTE_READWRITE: target.GetConst("PAGE_EXECUTE_READWRITE"),
}
target.MakeMmap = arch.makeMmap
target.MakeDataMmap = arch.makeMmap
}
type arch struct {
target *prog.Target
virtualAllocSyscall *prog.Syscall
MEM_COMMIT uint64
@ -26,16 +28,19 @@ type arch struct {
PAGE_EXECUTE_READWRITE uint64
}
func (arch *arch) makeMmap(addr, size uint64) *prog.Call {
func (arch *arch) makeMmap() []*prog.Call {
meta := arch.virtualAllocSyscall
return &prog.Call{
Meta: meta,
Args: []prog.Arg{
prog.MakeVmaPointerArg(meta.Args[0], addr, size),
prog.MakeConstArg(meta.Args[1], size),
prog.MakeConstArg(meta.Args[2], arch.MEM_COMMIT|arch.MEM_RESERVE),
prog.MakeConstArg(meta.Args[3], arch.PAGE_EXECUTE_READWRITE),
size := arch.target.NumPages * arch.target.PageSize
return []*prog.Call{
&prog.Call{
Meta: meta,
Args: []prog.Arg{
prog.MakeVmaPointerArg(meta.Args[0], 0, size),
prog.MakeConstArg(meta.Args[1], size),
prog.MakeConstArg(meta.Args[2], arch.MEM_COMMIT|arch.MEM_RESERVE),
prog.MakeConstArg(meta.Args[3], arch.PAGE_EXECUTE_READWRITE),
},
Ret: prog.MakeReturnArg(meta.Ret),
},
Ret: prog.MakeReturnArg(meta.Ret),
}
}

View File

@ -241,7 +241,7 @@ func checkSimpleProgram(args *checkArgs, features *host.Features) error {
return fmt.Errorf("failed to create ipc env: %v", err)
}
defer env.Close()
p := args.target.GenerateSimpleProg()
p := args.target.DataMmapProg()
output, info, hanged, err := env.Exec(args.ipcExecOpts, p)
if err != nil {
return fmt.Errorf("program execution failed: %v\n%s", err, output)