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 4package prog 5 6import ( 7 "fmt" 8) 9 10type 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 19type Dir int 20 21const ( 22 DirIn Dir = iota 23 DirOut 24 DirInOut 25) 26 27func (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 40type BinaryFormat int 41 42const ( 43 FormatNative BinaryFormat = iota 44 FormatBigEndian 45 FormatStrDec 46 FormatStrHex 47 FormatStrOct 48) 49 50type 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 70func IsPad(t Type) bool { 71 if ct, ok := t.(*ConstType); ok && ct.IsPad { 72 return true 73 } 74 return false 75} 76 77type 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 86func (t *TypeCommon) Name() string { 87 return t.TypeName 88} 89 90func (t *TypeCommon) FieldName() string { 91 return t.FldName 92} 93 94func (t *TypeCommon) Optional() bool { 95 return t.IsOptional 96} 97 98func (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 105func (t *TypeCommon) Varlen() bool { 106 return t.IsVarlen 107} 108 109func (t *TypeCommon) Format() BinaryFormat { 110 return FormatNative 111} 112 113func (t *TypeCommon) BitfieldOffset() uint64 { 114 return 0 115} 116 117func (t *TypeCommon) BitfieldLength() uint64 { 118 return 0 119} 120 121func (t *TypeCommon) BitfieldMiddle() bool { 122 return false 123} 124 125func (t TypeCommon) Dir() Dir { 126 return t.ArgDir 127} 128 129type ResourceDesc struct { 130 Name string 131 Type Type 132 Kind []string 133 Values []uint64 134} 135 136type ResourceType struct { 137 TypeCommon 138 ArgFormat BinaryFormat 139 Desc *ResourceDesc 140} 141 142func (t *ResourceType) String() string { 143 return t.Name() 144} 145 146func (t *ResourceType) makeDefaultArg() Arg { 147 return MakeResultArg(t, nil, t.Default()) 148} 149 150func (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 156func (t *ResourceType) Default() uint64 { 157 return t.Desc.Values[0] 158} 159 160func (t *ResourceType) SpecialValues() []uint64 { 161 return t.Desc.Values 162} 163 164func (t *ResourceType) Format() BinaryFormat { 165 return t.ArgFormat 166} 167 168type IntTypeCommon struct { 169 TypeCommon 170 ArgFormat BinaryFormat 171 BitfieldOff uint64 172 BitfieldLen uint64 173 BitfieldMdl bool 174} 175 176func (t *IntTypeCommon) String() string { 177 return t.Name() 178} 179 180func (t *IntTypeCommon) Format() BinaryFormat { 181 return t.ArgFormat 182} 183 184func (t *IntTypeCommon) BitfieldOffset() uint64 { 185 return t.BitfieldOff 186} 187 188func (t *IntTypeCommon) BitfieldLength() uint64 { 189 return t.BitfieldLen 190} 191 192func (t *IntTypeCommon) BitfieldMiddle() bool { 193 return t.BitfieldMdl 194} 195 196type ConstType struct { 197 IntTypeCommon 198 Val uint64 199 IsPad bool 200} 201 202func (t *ConstType) makeDefaultArg() Arg { 203 return MakeConstArg(t, t.Val) 204} 205 206func (t *ConstType) isDefaultArg(arg Arg) bool { 207 return arg.(*ConstArg).Val == t.Val 208} 209 210func (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 217type IntKind int 218 219const ( 220 IntPlain IntKind = iota 221 IntFileoff // offset within a file 222 IntRange 223) 224 225type IntType struct { 226 IntTypeCommon 227 Kind IntKind 228 RangeBegin uint64 229 RangeEnd uint64 230} 231 232func (t *IntType) makeDefaultArg() Arg { 233 return MakeConstArg(t, 0) 234} 235 236func (t *IntType) isDefaultArg(arg Arg) bool { 237 return arg.(*ConstArg).Val == 0 238} 239 240type FlagsType struct { 241 IntTypeCommon 242 Vals []uint64 243 BitMask bool 244} 245 246func (t *FlagsType) makeDefaultArg() Arg { 247 return MakeConstArg(t, 0) 248} 249 250func (t *FlagsType) isDefaultArg(arg Arg) bool { 251 return arg.(*ConstArg).Val == 0 252} 253 254type LenType struct { 255 IntTypeCommon 256 BitSize uint64 // want size in multiple of bits instead of array size 257 Buf string 258} 259 260func (t *LenType) makeDefaultArg() Arg { 261 return MakeConstArg(t, 0) 262} 263 264func (t *LenType) isDefaultArg(arg Arg) bool { 265 return arg.(*ConstArg).Val == 0 266} 267 268type ProcType struct { 269 IntTypeCommon 270 ValuesStart uint64 271 ValuesPerProc uint64 272} 273 274const ( 275 MaxPids = 32 276 procDefaultValue = 0xffffffffffffffff // special value denoting 0 for all procs 277) 278 279func (t *ProcType) makeDefaultArg() Arg { 280 return MakeConstArg(t, procDefaultValue) 281} 282 283func (t *ProcType) isDefaultArg(arg Arg) bool { 284 return arg.(*ConstArg).Val == procDefaultValue 285} 286 287type CsumKind int 288 289const ( 290 CsumInet CsumKind = iota 291 CsumPseudo 292) 293 294type CsumType struct { 295 IntTypeCommon 296 Kind CsumKind 297 Buf string 298 Protocol uint64 // for CsumPseudo 299} 300 301func (t *CsumType) String() string { 302 return "csum" 303} 304 305func (t *CsumType) makeDefaultArg() Arg { 306 return MakeConstArg(t, 0) 307} 308 309func (t *CsumType) isDefaultArg(arg Arg) bool { 310 return arg.(*ConstArg).Val == 0 311} 312 313type VmaType struct { 314 TypeCommon 315 RangeBegin uint64 // in pages 316 RangeEnd uint64 317} 318 319func (t *VmaType) String() string { 320 return "vma" 321} 322 323func (t *VmaType) makeDefaultArg() Arg { 324 return MakeNullPointerArg(t) 325} 326 327func (t *VmaType) isDefaultArg(arg Arg) bool { 328 return arg.(*PointerArg).IsNull() 329} 330 331type BufferKind int 332 333const ( 334 BufferBlobRand BufferKind = iota 335 BufferBlobRange 336 BufferString 337 BufferFilename 338 BufferText 339) 340 341type TextKind int 342 343const ( 344 TextX86Real TextKind = iota 345 TextX86bit16 346 TextX86bit32 347 TextX86bit64 348 TextArm64 349) 350 351type 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 362func (t *BufferType) String() string { 363 return "buffer" 364} 365 366func (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 381func (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 400type ArrayKind int 401 402const ( 403 ArrayRandLen ArrayKind = iota 404 ArrayRangeLen 405) 406 407type ArrayType struct { 408 TypeCommon 409 Type Type 410 Kind ArrayKind 411 RangeBegin uint64 412 RangeEnd uint64 413} 414 415func (t *ArrayType) String() string { 416 return fmt.Sprintf("array[%v]", t.Type.String()) 417} 418 419func (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 429func (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 442type PtrType struct { 443 TypeCommon 444 Type Type 445} 446 447func (t *PtrType) String() string { 448 return fmt.Sprintf("ptr[%v, %v]", t.Dir(), t.Type.String()) 449} 450 451func (t *PtrType) makeDefaultArg() Arg { 452 if t.Optional() { 453 return MakeNullPointerArg(t) 454 } 455 return MakePointerArg(t, 0, t.Type.makeDefaultArg()) 456} 457 458func (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 466type StructType struct { 467 Key StructKey 468 FldName string 469 *StructDesc 470} 471 472func (t *StructType) String() string { 473 return t.Name() 474} 475 476func (t *StructType) FieldName() string { 477 return t.FldName 478} 479 480func (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 488func (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 498type UnionType struct { 499 Key StructKey 500 FldName string 501 *StructDesc 502} 503 504func (t *UnionType) String() string { 505 return t.Name() 506} 507 508func (t *UnionType) FieldName() string { 509 return t.FldName 510} 511 512func (t *UnionType) makeDefaultArg() Arg { 513 return MakeUnionArg(t, t.Fields[0].makeDefaultArg()) 514} 515 516func (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 521type StructDesc struct { 522 TypeCommon 523 Fields []Type 524 AlignAttr uint64 525} 526 527func (t *StructDesc) FieldName() string { 528 panic("must not be called") 529} 530 531type StructKey struct { 532 Name string 533 Dir Dir 534} 535 536type KeyedStruct struct { 537 Key StructKey 538 Desc *StructDesc 539} 540 541type ConstValue struct { 542 Name string 543 Value uint64 544} 545 546func 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