syzkaller/prog/clone.go
Dmitry Vyukov 40723a067e prog: validate deserialized programs
The optimization change removed validation too aggressively.
We do need program validation during deserialization,
because we can get bad programs from corpus or hub.
Restore program validation after deserialization.
2017-01-24 10:53:21 +01:00

55 lines
1.2 KiB
Go

// Copyright 2015 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package prog
func (p *Prog) Clone() *Prog {
p1 := new(Prog)
newargs := make(map[*Arg]*Arg)
for _, c := range p.Calls {
c1 := new(Call)
c1.Meta = c.Meta
c1.Ret = c.Ret.clone(c1, newargs)
for _, arg := range c.Args {
c1.Args = append(c1.Args, arg.clone(c1, newargs))
}
p1.Calls = append(p1.Calls, c1)
}
if debug {
if err := p1.validate(); err != nil {
panic(err)
}
}
return p1
}
func (arg *Arg) clone(c *Call, newargs map[*Arg]*Arg) *Arg {
arg1 := new(Arg)
*arg1 = *arg
arg1.Data = append([]byte{}, arg.Data...)
switch arg.Kind {
case ArgPointer:
if arg.Res != nil {
arg1.Res = arg.Res.clone(c, newargs)
}
case ArgUnion:
arg1.Option = arg.Option.clone(c, newargs)
case ArgResult:
r := newargs[arg.Res]
arg1.Res = r
if r.Uses == nil {
r.Uses = make(map[*Arg]bool)
}
r.Uses[arg1] = true
}
arg1.Inner = nil
for _, arg2 := range arg.Inner {
arg1.Inner = append(arg1.Inner, arg2.clone(c, newargs))
}
if len(arg1.Uses) != 0 {
arg1.Uses = nil // filled when we clone the referent
newargs[arg] = arg1
}
return arg1
}