mirror of
https://github.com/reactos/syzkaller-ros.git
synced 2025-03-04 01:17:14 +00:00
prog: don't serialize paddings
Paddings in serialized programs are unnecessary and confusing. Instead restore them implicitly. Also use [,,,,] for arrays.
This commit is contained in:
parent
9f9ae3fcc3
commit
4eda9b07e5
@ -43,6 +43,9 @@ func (p *Prog) Serialize() []byte {
|
||||
}
|
||||
fmt.Fprintf(buf, "%v(", c.Meta.Name)
|
||||
for i, a := range c.Args {
|
||||
if sys.IsPad(a.Type) {
|
||||
continue
|
||||
}
|
||||
if i != 0 {
|
||||
fmt.Fprintf(buf, ", ")
|
||||
}
|
||||
@ -59,7 +62,7 @@ func (a *Arg) serialize(buf io.Writer, vars map[*Arg]int, varSeq *int) {
|
||||
return
|
||||
}
|
||||
if len(a.Uses) != 0 {
|
||||
fmt.Fprintf(buf, "[r%v=]", *varSeq)
|
||||
fmt.Fprintf(buf, "<r%v=>", *varSeq)
|
||||
vars[a] = *varSeq
|
||||
*varSeq++
|
||||
}
|
||||
@ -86,14 +89,26 @@ func (a *Arg) serialize(buf io.Writer, vars map[*Arg]int, varSeq *int) {
|
||||
case ArgData:
|
||||
fmt.Fprintf(buf, "\"%v\"", hex.EncodeToString(a.Data))
|
||||
case ArgGroup:
|
||||
fmt.Fprintf(buf, "{")
|
||||
var delims []byte
|
||||
switch a.Type.(type) {
|
||||
case sys.StructType:
|
||||
delims = []byte{'{', '}'}
|
||||
case sys.ArrayType:
|
||||
delims = []byte{'[', ']'}
|
||||
default:
|
||||
panic("unknown group type")
|
||||
}
|
||||
buf.Write([]byte{delims[0]})
|
||||
for i, a1 := range a.Inner {
|
||||
if a1 != nil && sys.IsPad(a1.Type) {
|
||||
continue
|
||||
}
|
||||
if i != 0 {
|
||||
fmt.Fprintf(buf, ", ")
|
||||
}
|
||||
a1.serialize(buf, vars, varSeq)
|
||||
}
|
||||
fmt.Fprintf(buf, "}")
|
||||
buf.Write([]byte{delims[1]})
|
||||
default:
|
||||
panic("unknown arg kind")
|
||||
}
|
||||
@ -123,7 +138,14 @@ func Deserialize(data []byte) (prog *Prog, err error) {
|
||||
prog.Calls = append(prog.Calls, c)
|
||||
p.Parse('(')
|
||||
for i := 0; p.Char() != ')'; i++ {
|
||||
arg, err := parseArg(p, vars)
|
||||
if i >= len(meta.Args) {
|
||||
return nil, fmt.Errorf("wrong call arg count: %v, want %v", i+1, len(meta.Args))
|
||||
}
|
||||
typ := meta.Args[i]
|
||||
if sys.IsPad(typ) {
|
||||
return nil, fmt.Errorf("padding in syscall %v arguments", name)
|
||||
}
|
||||
arg, err := parseArg(typ, p, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -155,13 +177,13 @@ func Deserialize(data []byte) (prog *Prog, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func parseArg(p *parser, vars map[string]*Arg) (*Arg, error) {
|
||||
func parseArg(typ sys.Type, p *parser, vars map[string]*Arg) (*Arg, error) {
|
||||
r := ""
|
||||
if p.Char() == '[' {
|
||||
p.Parse('[')
|
||||
if p.Char() == '<' {
|
||||
p.Parse('<')
|
||||
r = p.Ident()
|
||||
p.Parse('=')
|
||||
p.Parse(']')
|
||||
p.Parse('>')
|
||||
}
|
||||
var arg *Arg
|
||||
switch p.Char() {
|
||||
@ -198,13 +220,21 @@ func parseArg(p *parser, vars map[string]*Arg) (*Arg, error) {
|
||||
arg.OpAdd = uintptr(v)
|
||||
}
|
||||
case '&':
|
||||
var typ1 sys.Type
|
||||
switch t1 := typ.(type) {
|
||||
case sys.PtrType:
|
||||
typ1 = t1.Type
|
||||
case sys.VmaType:
|
||||
default:
|
||||
return nil, fmt.Errorf("& arg is not a pointer: %#v", typ)
|
||||
}
|
||||
p.Parse('&')
|
||||
page, off, err := parseAddr(p, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.Parse('=')
|
||||
inner, err := parseArg(p, vars)
|
||||
inner, err := parseArg(typ1, p, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -228,19 +258,53 @@ func parseArg(p *parser, vars map[string]*Arg) (*Arg, error) {
|
||||
}
|
||||
arg = dataArg(data)
|
||||
case '{':
|
||||
t1, ok := typ.(sys.StructType)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("'{' arg is not a struct: %#v", typ)
|
||||
}
|
||||
p.Parse('{')
|
||||
var inner []*Arg
|
||||
for p.Char() != '}' {
|
||||
arg, err := parseArg(p, vars)
|
||||
for i := 0; p.Char() != '}'; i++ {
|
||||
if i >= len(t1.Fields) {
|
||||
return nil, fmt.Errorf("wrong struct arg count: %v, want %v", i+1, len(t1.Fields))
|
||||
}
|
||||
fld := t1.Fields[i]
|
||||
if sys.IsPad(fld) {
|
||||
inner = append(inner, constArg(0))
|
||||
} else {
|
||||
arg, err := parseArg(fld, p, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inner = append(inner, arg)
|
||||
if p.Char() != '}' {
|
||||
p.Parse(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
p.Parse('}')
|
||||
if sys.IsPad(t1.Fields[len(t1.Fields)-1]) {
|
||||
inner = append(inner, constArg(0))
|
||||
}
|
||||
arg = groupArg(inner)
|
||||
case '[':
|
||||
t1, ok := typ.(sys.ArrayType)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("'[' arg is not an array: %#v", typ)
|
||||
}
|
||||
p.Parse('[')
|
||||
var inner []*Arg
|
||||
for i := 0; p.Char() != ']'; i++ {
|
||||
arg, err := parseArg(t1.Type, p, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inner = append(inner, arg)
|
||||
if p.Char() != '}' {
|
||||
if p.Char() != ']' {
|
||||
p.Parse(',')
|
||||
}
|
||||
}
|
||||
p.Parse('}')
|
||||
p.Parse(']')
|
||||
arg = groupArg(inner)
|
||||
case 'n':
|
||||
p.Parse('n')
|
||||
|
@ -8,6 +8,8 @@ package prog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -57,7 +59,7 @@ func (p *Prog) SerializeForExec() []byte {
|
||||
}
|
||||
return
|
||||
}
|
||||
if pad, _ := arg1.IsPad(); pad {
|
||||
if sys.IsPad(arg1.Type) {
|
||||
return
|
||||
}
|
||||
if arg1.Kind == ArgData && len(arg1.Data) == 0 {
|
||||
|
@ -212,7 +212,7 @@ func TestMinimize(t *testing.T) {
|
||||
// Remove a call and replace results.
|
||||
{
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"pipe2(&(0x7f0000000000)={[r0=]0x0, 0x0}, 0x0)\n" +
|
||||
"pipe2(&(0x7f0000000000)={<r0=>0x0, 0x0}, 0x0)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"1155\", 0x2)\n" +
|
||||
"sched_yield()\n",
|
||||
3,
|
||||
@ -259,7 +259,7 @@ func TestMinimize(t *testing.T) {
|
||||
for ti, test := range tests {
|
||||
p, err := Deserialize([]byte(test.orig))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to deserialize original program: %v", err)
|
||||
t.Fatalf("failed to deserialize original program #%v: %v", ti, err)
|
||||
}
|
||||
p1, ci := Minimize(p, test.callIndex, test.pred)
|
||||
res := p1.Serialize()
|
||||
|
@ -79,13 +79,6 @@ func (a *Arg) Size(typ sys.Type) uintptr {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Arg) IsPad() (bool, uintptr) {
|
||||
if ct, ok := a.Type.(sys.ConstType); ok && ct.Val == 0 && ct.Name() == "pad" {
|
||||
return true, ct.TypeSize
|
||||
}
|
||||
return false, 0
|
||||
}
|
||||
|
||||
func constArg(v uintptr) *Arg {
|
||||
return &Arg{Kind: ArgConst, Val: v}
|
||||
}
|
||||
|
@ -462,7 +462,7 @@ func (r *randGen) createResource(s *state, res sys.ResourceType) (arg *Arg, call
|
||||
// Generate one of them.
|
||||
meta := metas[r.Intn(len(metas))]
|
||||
calls := r.generateParticularCall(s, meta)
|
||||
assignTypeAndDir(calls[len(calls)-1])
|
||||
//assignTypeAndDir(calls[len(calls)-1])
|
||||
s1 := newState(s.ct)
|
||||
s1.analyze(calls[len(calls)-1])
|
||||
// Now see if we have what we want.
|
||||
|
@ -18,12 +18,6 @@ func (p *Prog) validate() error {
|
||||
ctx := &validCtx{make(map[*Arg]bool), make(map[*Arg]*Arg)}
|
||||
for _, c := range p.Calls {
|
||||
if err := c.validate(ctx); err != nil {
|
||||
|
||||
fmt.Printf("PROGRAM:\n")
|
||||
for _, c := range p.Calls {
|
||||
fmt.Printf(" %v: %+v %p\n", c.Meta.Name, c.Args, c.Ret)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -36,6 +30,9 @@ func (p *Prog) validate() error {
|
||||
}
|
||||
|
||||
func (c *Call) validate(ctx *validCtx) error {
|
||||
if c.Meta == nil {
|
||||
return fmt.Errorf("call does not have meta information")
|
||||
}
|
||||
if len(c.Args) != len(c.Meta.Args) {
|
||||
return fmt.Errorf("syscall %v: wrong number of arguments, want %v, got %v", c.Meta.Name, len(c.Meta.Args), len(c.Args))
|
||||
}
|
||||
|
@ -23,6 +23,13 @@ type Type interface {
|
||||
Align() uintptr
|
||||
}
|
||||
|
||||
func IsPad(t Type) bool {
|
||||
if ct, ok := t.(ConstType); ok && ct.IsPad {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type TypeCommon struct {
|
||||
TypeName string
|
||||
IsOptional bool
|
||||
@ -313,6 +320,7 @@ type ConstType struct {
|
||||
TypeCommon
|
||||
TypeSize uintptr
|
||||
Val uintptr
|
||||
IsPad bool
|
||||
}
|
||||
|
||||
func (t ConstType) Size() uintptr {
|
||||
@ -654,5 +662,6 @@ func makePad(sz uintptr) Type {
|
||||
TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false},
|
||||
TypeSize: sz,
|
||||
Val: 0,
|
||||
IsPad: true,
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user