github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/flatrpc/helpers.go (about) 1 // Copyright 2024 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 flatrpc 5 6 import ( 7 "fmt" 8 "slices" 9 "sync/atomic" 10 "syscall" 11 "unsafe" 12 13 "github.com/google/syzkaller/prog" 14 ) 15 16 const AllFeatures = ^Feature(0) 17 18 // Flatbuffers compiler adds T suffix to object API types, which are actual structs representing types. 19 // This leads to non-idiomatic Go code, e.g. we would have to use []FileInfoT in Go code. 20 // So we use Raw suffix for all flatbuffers tables and rename object API types here to idiomatic names. 21 type ConnectHello = ConnectHelloRawT 22 type ConnectRequest = ConnectRequestRawT 23 type ConnectReply = ConnectReplyRawT 24 type InfoRequest = InfoRequestRawT 25 type InfoReply = InfoReplyRawT 26 type FileInfo = FileInfoRawT 27 type GlobInfo = GlobInfoRawT 28 type FeatureInfo = FeatureInfoRawT 29 type HostMessages = HostMessagesRawT 30 type HostMessage = HostMessageRawT 31 type ExecutorMessages = ExecutorMessagesRawT 32 type ExecutorMessage = ExecutorMessageRawT 33 type ExecRequest = ExecRequestRawT 34 type StateRequest = StateRequestRawT 35 type SignalUpdate = SignalUpdateRawT 36 type CorpusTriaged = CorpusTriagedRawT 37 type ExecutingMessage = ExecutingMessageRawT 38 type CallInfo = CallInfoRawT 39 type Comparison = ComparisonRawT 40 type ExecOpts = ExecOptsRawT 41 type ProgInfo = ProgInfoRawT 42 type ExecResult = ExecResultRawT 43 type StateResult = StateResultRawT 44 45 func init() { 46 var req ExecRequest 47 if prog.MaxPids > unsafe.Sizeof(req.Avoid)*8 { 48 panic("all procs won't fit ito ExecRequest.Avoid") 49 } 50 } 51 52 func (pi *ProgInfo) Clone() *ProgInfo { 53 if pi == nil { 54 return nil 55 } 56 ret := *pi 57 ret.Extra = ret.Extra.clone() 58 ret.Calls = make([]*CallInfo, len(pi.Calls)) 59 for i, call := range pi.Calls { 60 ret.Calls[i] = call.clone() 61 } 62 return &ret 63 } 64 65 func (ci *CallInfo) clone() *CallInfo { 66 if ci == nil { 67 return nil 68 } 69 ret := *ci 70 ret.Signal = slices.Clone(ret.Signal) 71 ret.Cover = slices.Clone(ret.Cover) 72 ret.Comps = slices.Clone(ret.Comps) 73 return &ret 74 } 75 76 func EmptyProgInfo(calls int) *ProgInfo { 77 info := &ProgInfo{} 78 for i := 0; i < calls; i++ { 79 info.Calls = append(info.Calls, &CallInfo{ 80 // Store some unsuccessful errno in the case we won't get any result. 81 // It also won't have CallExecuted flag, but it's handy to make it 82 // look failed based on errno as well. 83 Error: int32(syscall.ENOSYS), 84 }) 85 } 86 return info 87 } 88 89 func SandboxToFlags(sandbox string) (ExecEnv, error) { 90 switch sandbox { 91 case "none": 92 return ExecEnvSandboxNone, nil 93 case "setuid": 94 return ExecEnvSandboxSetuid, nil 95 case "namespace": 96 return ExecEnvSandboxNamespace, nil 97 case "android": 98 return ExecEnvSandboxAndroid, nil 99 default: 100 return 0, fmt.Errorf("sandbox must contain one of none/setuid/namespace/android") 101 } 102 } 103 104 func (hdr *SnapshotHeaderT) UpdateState(state SnapshotState) { 105 atomic.StoreUint64((*uint64)(unsafe.Pointer(&hdr.State)), uint64(state)) 106 } 107 108 func (hdr *SnapshotHeaderT) LoadState() SnapshotState { 109 return SnapshotState(atomic.LoadUint64((*uint64)(unsafe.Pointer(&hdr.State)))) 110 }