Home | History | Annotate | Download | only in prog
      1 // Copyright 2015/2016 syzkaller project authors. All rights reserved.
      2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
      3 
      4 package prog
      5 
      6 import (
      7 	"fmt"
      8 )
      9 
     10 type Syscall struct {
     11 	ID       int
     12 	NR       uint64 // kernel syscall number
     13 	Name     string
     14 	CallName string
     15 	Args     []Type
     16 	Ret      Type
     17 }
     18 
     19 type Dir int
     20 
     21 const (
     22 	DirIn Dir = iota
     23 	DirOut
     24 	DirInOut
     25 )
     26 
     27 func (dir Dir) String() string {
     28 	switch dir {
     29 	case DirIn:
     30 		return "in"
     31 	case DirOut:
     32 		return "out"
     33 	case DirInOut:
     34 		return "inout"
     35 	default:
     36 		panic("unknown dir")
     37 	}
     38 }
     39 
     40 type BinaryFormat int
     41 
     42 const (
     43 	FormatNative BinaryFormat = iota
     44 	FormatBigEndian
     45 	FormatStrDec
     46 	FormatStrHex
     47 	FormatStrOct
     48 )
     49 
     50 type Type interface {
     51 	String() string
     52 	Name() string
     53 	FieldName() string
     54 	Dir() Dir
     55 	Optional() bool
     56 	Varlen() bool
     57 	Size() uint64
     58 	Format() BinaryFormat
     59 	BitfieldOffset() uint64
     60 	BitfieldLength() uint64
     61 	BitfieldMiddle() bool // returns true for all but last bitfield in a group
     62 
     63 	makeDefaultArg() Arg
     64 	isDefaultArg(arg Arg) bool
     65 	generate(r *randGen, s *state) (arg Arg, calls []*Call)
     66 	mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool)
     67 	minimize(ctx *minimizeArgsCtx, arg Arg, path string) bool
     68 }
     69 
     70 func IsPad(t Type) bool {
     71 	if ct, ok := t.(*ConstType); ok && ct.IsPad {
     72 		return true
     73 	}
     74 	return false
     75 }
     76 
     77 type TypeCommon struct {
     78 	TypeName   string
     79 	FldName    string // for struct fields and named args
     80 	TypeSize   uint64 // static size of the type, or 0 for variable size types
     81 	ArgDir     Dir
     82 	IsOptional bool
     83 	IsVarlen   bool
     84 }
     85 
     86 func (t *TypeCommon) Name() string {
     87 	return t.TypeName
     88 }
     89 
     90 func (t *TypeCommon) FieldName() string {
     91 	return t.FldName
     92 }
     93 
     94 func (t *TypeCommon) Optional() bool {
     95 	return t.IsOptional
     96 }
     97 
     98 func (t *TypeCommon) Size() uint64 {
     99 	if t.IsVarlen {
    100 		panic(fmt.Sprintf("static type size is not known: %#v", t))
    101 	}
    102 	return t.TypeSize
    103 }
    104 
    105 func (t *TypeCommon) Varlen() bool {
    106 	return t.IsVarlen
    107 }
    108 
    109 func (t *TypeCommon) Format() BinaryFormat {
    110 	return FormatNative
    111 }
    112 
    113 func (t *TypeCommon) BitfieldOffset() uint64 {
    114 	return 0
    115 }
    116 
    117 func (t *TypeCommon) BitfieldLength() uint64 {
    118 	return 0
    119 }
    120 
    121 func (t *TypeCommon) BitfieldMiddle() bool {
    122 	return false
    123 }
    124 
    125 func (t TypeCommon) Dir() Dir {
    126 	return t.ArgDir
    127 }
    128 
    129 type ResourceDesc struct {
    130 	Name   string
    131 	Type   Type
    132 	Kind   []string
    133 	Values []uint64
    134 }
    135 
    136 type ResourceType struct {
    137 	TypeCommon
    138 	ArgFormat BinaryFormat
    139 	Desc      *ResourceDesc
    140 }
    141 
    142 func (t *ResourceType) String() string {
    143 	return t.Name()
    144 }
    145 
    146 func (t *ResourceType) makeDefaultArg() Arg {
    147 	return MakeResultArg(t, nil, t.Default())
    148 }
    149 
    150 func (t *ResourceType) isDefaultArg(arg Arg) bool {
    151 	a := arg.(*ResultArg)
    152 	return a.Res == nil && a.OpDiv == 0 && a.OpAdd == 0 &&
    153 		len(a.uses) == 0 && a.Val == t.Default()
    154 }
    155 
    156 func (t *ResourceType) Default() uint64 {
    157 	return t.Desc.Values[0]
    158 }
    159 
    160 func (t *ResourceType) SpecialValues() []uint64 {
    161 	return t.Desc.Values
    162 }
    163 
    164 func (t *ResourceType) Format() BinaryFormat {
    165 	return t.ArgFormat
    166 }
    167 
    168 type IntTypeCommon struct {
    169 	TypeCommon
    170 	ArgFormat   BinaryFormat
    171 	BitfieldOff uint64
    172 	BitfieldLen uint64
    173 	BitfieldMdl bool
    174 }
    175 
    176 func (t *IntTypeCommon) String() string {
    177 	return t.Name()
    178 }
    179 
    180 func (t *IntTypeCommon) Format() BinaryFormat {
    181 	return t.ArgFormat
    182 }
    183 
    184 func (t *IntTypeCommon) BitfieldOffset() uint64 {
    185 	return t.BitfieldOff
    186 }
    187 
    188 func (t *IntTypeCommon) BitfieldLength() uint64 {
    189 	return t.BitfieldLen
    190 }
    191 
    192 func (t *IntTypeCommon) BitfieldMiddle() bool {
    193 	return t.BitfieldMdl
    194 }
    195 
    196 type ConstType struct {
    197 	IntTypeCommon
    198 	Val   uint64
    199 	IsPad bool
    200 }
    201 
    202 func (t *ConstType) makeDefaultArg() Arg {
    203 	return MakeConstArg(t, t.Val)
    204 }
    205 
    206 func (t *ConstType) isDefaultArg(arg Arg) bool {
    207 	return arg.(*ConstArg).Val == t.Val
    208 }
    209 
    210 func (t *ConstType) String() string {
    211 	if t.IsPad {
    212 		return fmt.Sprintf("pad[%v]", t.Size())
    213 	}
    214 	return fmt.Sprintf("const[%v, %v]", t.Val, t.IntTypeCommon.String())
    215 }
    216 
    217 type IntKind int
    218 
    219 const (
    220 	IntPlain   IntKind = iota
    221 	IntFileoff         // offset within a file
    222 	IntRange
    223 )
    224 
    225 type IntType struct {
    226 	IntTypeCommon
    227 	Kind       IntKind
    228 	RangeBegin uint64
    229 	RangeEnd   uint64
    230 }
    231 
    232 func (t *IntType) makeDefaultArg() Arg {
    233 	return MakeConstArg(t, 0)
    234 }
    235 
    236 func (t *IntType) isDefaultArg(arg Arg) bool {
    237 	return arg.(*ConstArg).Val == 0
    238 }
    239 
    240 type FlagsType struct {
    241 	IntTypeCommon
    242 	Vals    []uint64
    243 	BitMask bool
    244 }
    245 
    246 func (t *FlagsType) makeDefaultArg() Arg {
    247 	return MakeConstArg(t, 0)
    248 }
    249 
    250 func (t *FlagsType) isDefaultArg(arg Arg) bool {
    251 	return arg.(*ConstArg).Val == 0
    252 }
    253 
    254 type LenType struct {
    255 	IntTypeCommon
    256 	BitSize uint64 // want size in multiple of bits instead of array size
    257 	Buf     string
    258 }
    259 
    260 func (t *LenType) makeDefaultArg() Arg {
    261 	return MakeConstArg(t, 0)
    262 }
    263 
    264 func (t *LenType) isDefaultArg(arg Arg) bool {
    265 	return arg.(*ConstArg).Val == 0
    266 }
    267 
    268 type ProcType struct {
    269 	IntTypeCommon
    270 	ValuesStart   uint64
    271 	ValuesPerProc uint64
    272 }
    273 
    274 const (
    275 	MaxPids          = 32
    276 	procDefaultValue = 0xffffffffffffffff // special value denoting 0 for all procs
    277 )
    278 
    279 func (t *ProcType) makeDefaultArg() Arg {
    280 	return MakeConstArg(t, procDefaultValue)
    281 }
    282 
    283 func (t *ProcType) isDefaultArg(arg Arg) bool {
    284 	return arg.(*ConstArg).Val == procDefaultValue
    285 }
    286 
    287 type CsumKind int
    288 
    289 const (
    290 	CsumInet CsumKind = iota
    291 	CsumPseudo
    292 )
    293 
    294 type CsumType struct {
    295 	IntTypeCommon
    296 	Kind     CsumKind
    297 	Buf      string
    298 	Protocol uint64 // for CsumPseudo
    299 }
    300 
    301 func (t *CsumType) String() string {
    302 	return "csum"
    303 }
    304 
    305 func (t *CsumType) makeDefaultArg() Arg {
    306 	return MakeConstArg(t, 0)
    307 }
    308 
    309 func (t *CsumType) isDefaultArg(arg Arg) bool {
    310 	return arg.(*ConstArg).Val == 0
    311 }
    312 
    313 type VmaType struct {
    314 	TypeCommon
    315 	RangeBegin uint64 // in pages
    316 	RangeEnd   uint64
    317 }
    318 
    319 func (t *VmaType) String() string {
    320 	return "vma"
    321 }
    322 
    323 func (t *VmaType) makeDefaultArg() Arg {
    324 	return MakeNullPointerArg(t)
    325 }
    326 
    327 func (t *VmaType) isDefaultArg(arg Arg) bool {
    328 	return arg.(*PointerArg).IsNull()
    329 }
    330 
    331 type BufferKind int
    332 
    333 const (
    334 	BufferBlobRand BufferKind = iota
    335 	BufferBlobRange
    336 	BufferString
    337 	BufferFilename
    338 	BufferText
    339 )
    340 
    341 type TextKind int
    342 
    343 const (
    344 	TextX86Real TextKind = iota
    345 	TextX86bit16
    346 	TextX86bit32
    347 	TextX86bit64
    348 	TextArm64
    349 )
    350 
    351 type BufferType struct {
    352 	TypeCommon
    353 	Kind       BufferKind
    354 	RangeBegin uint64   // for BufferBlobRange kind
    355 	RangeEnd   uint64   // for BufferBlobRange kind
    356 	Text       TextKind // for BufferText
    357 	SubKind    string
    358 	Values     []string // possible values for BufferString kind
    359 	NoZ        bool     // non-zero terminated BufferString/BufferFilename
    360 }
    361 
    362 func (t *BufferType) String() string {
    363 	return "buffer"
    364 }
    365 
    366 func (t *BufferType) makeDefaultArg() Arg {
    367 	if t.Dir() == DirOut {
    368 		var sz uint64
    369 		if !t.Varlen() {
    370 			sz = t.Size()
    371 		}
    372 		return MakeOutDataArg(t, sz)
    373 	}
    374 	var data []byte
    375 	if !t.Varlen() {
    376 		data = make([]byte, t.Size())
    377 	}
    378 	return MakeDataArg(t, data)
    379 }
    380 
    381 func (t *BufferType) isDefaultArg(arg Arg) bool {
    382 	a := arg.(*DataArg)
    383 	if a.Size() == 0 {
    384 		return true
    385 	}
    386 	if a.Type().Varlen() {
    387 		return false
    388 	}
    389 	if a.Type().Dir() == DirOut {
    390 		return true
    391 	}
    392 	for _, v := range a.Data() {
    393 		if v != 0 {
    394 			return false
    395 		}
    396 	}
    397 	return true
    398 }
    399 
    400 type ArrayKind int
    401 
    402 const (
    403 	ArrayRandLen ArrayKind = iota
    404 	ArrayRangeLen
    405 )
    406 
    407 type ArrayType struct {
    408 	TypeCommon
    409 	Type       Type
    410 	Kind       ArrayKind
    411 	RangeBegin uint64
    412 	RangeEnd   uint64
    413 }
    414 
    415 func (t *ArrayType) String() string {
    416 	return fmt.Sprintf("array[%v]", t.Type.String())
    417 }
    418 
    419 func (t *ArrayType) makeDefaultArg() Arg {
    420 	var elems []Arg
    421 	if t.Kind == ArrayRangeLen && t.RangeBegin == t.RangeEnd {
    422 		for i := uint64(0); i < t.RangeBegin; i++ {
    423 			elems = append(elems, t.Type.makeDefaultArg())
    424 		}
    425 	}
    426 	return MakeGroupArg(t, elems)
    427 }
    428 
    429 func (t *ArrayType) isDefaultArg(arg Arg) bool {
    430 	a := arg.(*GroupArg)
    431 	if !a.fixedInnerSize() && len(a.Inner) != 0 {
    432 		return false
    433 	}
    434 	for _, elem := range a.Inner {
    435 		if !isDefault(elem) {
    436 			return false
    437 		}
    438 	}
    439 	return true
    440 }
    441 
    442 type PtrType struct {
    443 	TypeCommon
    444 	Type Type
    445 }
    446 
    447 func (t *PtrType) String() string {
    448 	return fmt.Sprintf("ptr[%v, %v]", t.Dir(), t.Type.String())
    449 }
    450 
    451 func (t *PtrType) makeDefaultArg() Arg {
    452 	if t.Optional() {
    453 		return MakeNullPointerArg(t)
    454 	}
    455 	return MakePointerArg(t, 0, t.Type.makeDefaultArg())
    456 }
    457 
    458 func (t *PtrType) isDefaultArg(arg Arg) bool {
    459 	a := arg.(*PointerArg)
    460 	if t.Optional() {
    461 		return a.IsNull()
    462 	}
    463 	return a.Address == 0 && isDefault(a.Res)
    464 }
    465 
    466 type StructType struct {
    467 	Key     StructKey
    468 	FldName string
    469 	*StructDesc
    470 }
    471 
    472 func (t *StructType) String() string {
    473 	return t.Name()
    474 }
    475 
    476 func (t *StructType) FieldName() string {
    477 	return t.FldName
    478 }
    479 
    480 func (t *StructType) makeDefaultArg() Arg {
    481 	inner := make([]Arg, len(t.Fields))
    482 	for i, field := range t.Fields {
    483 		inner[i] = field.makeDefaultArg()
    484 	}
    485 	return MakeGroupArg(t, inner)
    486 }
    487 
    488 func (t *StructType) isDefaultArg(arg Arg) bool {
    489 	a := arg.(*GroupArg)
    490 	for _, elem := range a.Inner {
    491 		if !isDefault(elem) {
    492 			return false
    493 		}
    494 	}
    495 	return true
    496 }
    497 
    498 type UnionType struct {
    499 	Key     StructKey
    500 	FldName string
    501 	*StructDesc
    502 }
    503 
    504 func (t *UnionType) String() string {
    505 	return t.Name()
    506 }
    507 
    508 func (t *UnionType) FieldName() string {
    509 	return t.FldName
    510 }
    511 
    512 func (t *UnionType) makeDefaultArg() Arg {
    513 	return MakeUnionArg(t, t.Fields[0].makeDefaultArg())
    514 }
    515 
    516 func (t *UnionType) isDefaultArg(arg Arg) bool {
    517 	a := arg.(*UnionArg)
    518 	return a.Option.Type().FieldName() == t.Fields[0].FieldName() && isDefault(a.Option)
    519 }
    520 
    521 type StructDesc struct {
    522 	TypeCommon
    523 	Fields    []Type
    524 	AlignAttr uint64
    525 }
    526 
    527 func (t *StructDesc) FieldName() string {
    528 	panic("must not be called")
    529 }
    530 
    531 type StructKey struct {
    532 	Name string
    533 	Dir  Dir
    534 }
    535 
    536 type KeyedStruct struct {
    537 	Key  StructKey
    538 	Desc *StructDesc
    539 }
    540 
    541 type ConstValue struct {
    542 	Name  string
    543 	Value uint64
    544 }
    545 
    546 func ForeachType(meta *Syscall, f func(Type)) {
    547 	seen := make(map[*StructDesc]bool)
    548 	var rec func(t Type)
    549 	rec = func(t Type) {
    550 		f(t)
    551 		switch a := t.(type) {
    552 		case *PtrType:
    553 			rec(a.Type)
    554 		case *ArrayType:
    555 			rec(a.Type)
    556 		case *StructType:
    557 			if seen[a.StructDesc] {
    558 				return // prune recursion via pointers to structs/unions
    559 			}
    560 			seen[a.StructDesc] = true
    561 			for _, f := range a.Fields {
    562 				rec(f)
    563 			}
    564 		case *UnionType:
    565 			if seen[a.StructDesc] {
    566 				return // prune recursion via pointers to structs/unions
    567 			}
    568 			seen[a.StructDesc] = true
    569 			for _, opt := range a.Fields {
    570 				rec(opt)
    571 			}
    572 		case *ResourceType, *BufferType, *VmaType, *LenType,
    573 			*FlagsType, *ConstType, *IntType, *ProcType, *CsumType:
    574 		default:
    575 			panic("unknown type")
    576 		}
    577 	}
    578 	for _, t := range meta.Args {
    579 		rec(t)
    580 	}
    581 	if meta.Ret != nil {
    582 		rec(meta.Ret)
    583 	}
    584 }
    585