From 75a7c5e2d1f09a4a58e7e1f1f4ef0b0f55a33413 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 19 Feb 2018 19:35:04 +0100 Subject: prog: rework address allocation 1. mmap all memory always, without explicit mmap calls in the program. This makes lots of things much easier and removes lots of code. Makes mmap not a special syscall and allows to fuzz without mmap enabled. 2. Change address assignment algorithm. Current algorithm allocates unmapped addresses too frequently and allows collisions between arguments of a single syscall. The new algorithm analyzes actual allocations in the program and places new arguments at unused locations. --- pkg/csource/csource.go | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) (limited to 'pkg/csource/csource.go') diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index bede09122..5c1b0208e 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -26,7 +26,19 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { w: new(bytes.Buffer), calls: make(map[string]uint64), } - for _, c := range p.Calls { + + calls, nvar, err := ctx.generateProgCalls(ctx.p) + if err != nil { + return nil, err + } + + mmapProg := p.Target.GenerateUberMmapProg() + mmapCalls, _, err := ctx.generateProgCalls(mmapProg) + if err != nil { + return nil, err + } + + for _, c := range append(mmapProg.Calls, p.Calls...) { ctx.calls[c.Meta.CallName] = c.Meta.NR } @@ -41,16 +53,6 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.generateSyscallDefines() - exec := make([]byte, prog.ExecBufferSize) - progSize, err := ctx.p.SerializeForExec(exec) - if err != nil { - return nil, fmt.Errorf("failed to serialize program: %v", err) - } - decoded, err := ctx.target.DeserializeExec(exec[:progSize]) - if err != nil { - return nil, err - } - calls, nvar := ctx.generateCalls(decoded) if nvar != 0 { ctx.printf("long r[%v];\n", nvar) } @@ -62,6 +64,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.generateTestFunc(calls, nvar, "loop") ctx.print("int main()\n{\n") + for _, c := range mmapCalls { + ctx.printf("%s", c) + } if opts.HandleSegv { ctx.printf("\tinstall_segv_handler();\n") } @@ -83,6 +88,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.generateTestFunc(calls, nvar, "test") if opts.Procs <= 1 { ctx.print("int main()\n{\n") + for _, c := range mmapCalls { + ctx.printf("%s", c) + } if opts.HandleSegv { ctx.print("\tinstall_segv_handler();\n") } @@ -108,6 +116,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.print("\t}\n}\n") } else { ctx.print("int main()\n{\n") + for _, c := range mmapCalls { + ctx.printf("%s", c) + } if opts.UseTmpDir { ctx.print("\tchar *cwd = get_current_dir_name();\n") } @@ -254,6 +265,20 @@ func (ctx *context) generateSyscallDefines() { ctx.printf("\n") } +func (ctx *context) generateProgCalls(p *prog.Prog) ([]string, uint64, error) { + exec := make([]byte, prog.ExecBufferSize) + progSize, err := p.SerializeForExec(exec) + if err != nil { + return nil, 0, fmt.Errorf("failed to serialize program: %v", err) + } + decoded, err := ctx.target.DeserializeExec(exec[:progSize]) + if err != nil { + return nil, 0, err + } + calls, nvar := ctx.generateCalls(decoded) + return calls, nvar, nil +} + func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) { var calls []string csumSeq := 0 -- cgit mrf-deployment