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