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  }