diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-11-27 17:23:09 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-12-11 15:22:17 +0000 |
| commit | 299ee674e6c124a35f1cf258df4f0f3c6e1db1f3 (patch) | |
| tree | 416b515e959a1d0a64a9516b1524a062ae63ba7d /pkg/rpcserver | |
| parent | ff949d2512c5ac33d0407d26d80f1df77b2de0e7 (diff) | |
executor: query globs in the test program context
We query globs for 2 reasons:
1. Expand glob types in syscall descriptions.
2. Dynamic file probing for automatic descriptions generation.
In both of these contexts are are interested in files
that will be present during test program execution
(rather than normal unsandboxed execution).
For example, some files may not be accessible to test programs
after pivot root. On the other hand, we create and link
some additional files for the test program that don't
normally exist.
Add a new request type for querying of globs that are
executed in the test program context.
Diffstat (limited to 'pkg/rpcserver')
| -rw-r--r-- | pkg/rpcserver/local.go | 3 | ||||
| -rw-r--r-- | pkg/rpcserver/mocks/Manager.go | 10 | ||||
| -rw-r--r-- | pkg/rpcserver/rpcserver.go | 25 | ||||
| -rw-r--r-- | pkg/rpcserver/runner.go | 31 |
4 files changed, 36 insertions, 33 deletions
diff --git a/pkg/rpcserver/local.go b/pkg/rpcserver/local.go index c8052138a..5faa8334b 100644 --- a/pkg/rpcserver/local.go +++ b/pkg/rpcserver/local.go @@ -112,8 +112,7 @@ type local struct { setupDone chan bool } -func (ctx *local) MachineChecked(info *flatrpc.InfoRequest, features flatrpc.Feature, - syscalls map[*prog.Syscall]bool) queue.Source { +func (ctx *local) MachineChecked(features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source { <-ctx.setupDone ctx.serv.TriagedCorpus() return ctx.cfg.MachineChecked(features, syscalls) diff --git a/pkg/rpcserver/mocks/Manager.go b/pkg/rpcserver/mocks/Manager.go index 0c14c8c9f..810b5028f 100644 --- a/pkg/rpcserver/mocks/Manager.go +++ b/pkg/rpcserver/mocks/Manager.go @@ -72,17 +72,17 @@ func (_m *Manager) CoverageFilter(modules []*vminfo.KernelModule) []uint64 { return r0 } -// MachineChecked provides a mock function with given fields: info, features, syscalls -func (_m *Manager) MachineChecked(info *flatrpc.InfoRequestRawT, features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source { - ret := _m.Called(info, features, syscalls) +// MachineChecked provides a mock function with given fields: features, syscalls +func (_m *Manager) MachineChecked(features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source { + ret := _m.Called(features, syscalls) if len(ret) == 0 { panic("no return value specified for MachineChecked") } var r0 queue.Source - if rf, ok := ret.Get(0).(func(*flatrpc.InfoRequestRawT, flatrpc.Feature, map[*prog.Syscall]bool) queue.Source); ok { - r0 = rf(info, features, syscalls) + if rf, ok := ret.Get(0).(func(flatrpc.Feature, map[*prog.Syscall]bool) queue.Source); ok { + r0 = rf(features, syscalls) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(queue.Source) diff --git a/pkg/rpcserver/rpcserver.go b/pkg/rpcserver/rpcserver.go index c064e6938..9d259b733 100644 --- a/pkg/rpcserver/rpcserver.go +++ b/pkg/rpcserver/rpcserver.go @@ -48,26 +48,22 @@ type Config struct { DebugTimeouts bool Procs int Slowdown int - // Extra globs that will be requested during machine checking, - // and will be passed to MachineChecked callback. - CheckGlobs []string - pcBase uint64 - localModules []*vminfo.KernelModule + pcBase uint64 + localModules []*vminfo.KernelModule } type RemoteConfig struct { *mgrconfig.Config - Manager Manager - Stats Stats - CheckGlobs []string - Debug bool + Manager Manager + Stats Stats + Debug bool } //go:generate ../../tools/mockery.sh --name Manager --output ./mocks type Manager interface { MaxSignal() signal.Signal BugFrames() (leaks []string, races []string) - MachineChecked(info *flatrpc.InfoRequest, features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source + MachineChecked(features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source CoverageFilter(modules []*vminfo.KernelModule) []uint64 } @@ -181,7 +177,6 @@ func New(cfg *RemoteConfig) (Server, error) { Slowdown: cfg.Timeouts.Slowdown, pcBase: pcBase, localModules: cfg.LocalModules, - CheckGlobs: cfg.CheckGlobs, }, cfg.Manager), nil } @@ -280,7 +275,6 @@ func (serv *server) handleRunnerConn(runner *Runner, conn *flatrpc.Conn) error { opts.Features = serv.setupFeatures } else { opts.Files = append(opts.Files, serv.checker.CheckFiles()...) - opts.Globs = append(serv.target.RequiredGlobs(), serv.cfg.CheckGlobs...) opts.Features = serv.cfg.Features } @@ -321,11 +315,6 @@ func (serv *server) handleMachineInfo(infoReq *flatrpc.InfoRequestRawT) (handsha serv.StatModules.Add(len(modules)) serv.canonicalModules = cover.NewCanonicalizer(modules, serv.cfg.Cover) serv.coverFilter = serv.mgr.CoverageFilter(modules) - globs := make(map[string][]string) - for _, glob := range infoReq.Globs { - globs[glob.Name] = glob.Files - } - serv.target.UpdateGlobs(globs) // Flatbuffers don't do deep copy of byte slices, // so clone manually since we pass it a goroutine. for _, file := range infoReq.Files { @@ -395,7 +384,7 @@ func (serv *server) runCheck(info *flatrpc.InfoRequest) error { } enabledFeatures := features.Enabled() serv.setupFeatures = features.NeedSetup() - newSource := serv.mgr.MachineChecked(info, enabledFeatures, enabledCalls) + newSource := serv.mgr.MachineChecked(enabledFeatures, enabledCalls) serv.baseSource.Store(newSource) serv.checkDone.Store(true) return nil diff --git a/pkg/rpcserver/runner.go b/pkg/rpcserver/runner.go index 29e79bad5..9ac1a6866 100644 --- a/pkg/rpcserver/runner.go +++ b/pkg/rpcserver/runner.go @@ -69,7 +69,6 @@ type handshakeConfig struct { LeakFrames []string RaceFrames []string Files []string - Globs []string Features flatrpc.Feature // Callback() is called in the middle of the handshake process. @@ -102,7 +101,6 @@ func (runner *Runner) Handshake(conn *flatrpc.Conn, cfg *handshakeConfig) error LeakFrames: cfg.LeakFrames, RaceFrames: cfg.RaceFrames, Files: cfg.Files, - Globs: cfg.Globs, Features: cfg.Features, } if err := flatrpc.Send(conn, connectReply); err != nil { @@ -292,7 +290,8 @@ func (runner *Runner) sendRequest(req *queue.Request) error { opts.EnvFlags |= flatrpc.ExecEnvDebug } var data []byte - if req.BinaryFile == "" { + switch req.Type { + case flatrpc.RequestTypeProgram: progData, err := req.Prog.SerializeForExec() if err != nil { // It's bad if we systematically fail to serialize programs, @@ -303,8 +302,7 @@ func (runner *Runner) sendRequest(req *queue.Request) error { return nil } data = progData - } else { - flags |= flatrpc.RequestFlagIsBinary + case flatrpc.RequestTypeBinary: fileData, err := os.ReadFile(req.BinaryFile) if err != nil { req.Done(&queue.Result{ @@ -314,6 +312,11 @@ func (runner *Runner) sendRequest(req *queue.Request) error { return nil } data = fileData + case flatrpc.RequestTypeGlob: + data = append([]byte(req.GlobPattern), 0) + flags |= flatrpc.RequestFlagReturnOutput + default: + panic("unhandled request type") } var avoid uint64 for _, id := range req.Avoid { @@ -326,8 +329,9 @@ func (runner *Runner) sendRequest(req *queue.Request) error { Type: flatrpc.HostMessagesRawExecRequest, Value: &flatrpc.ExecRequest{ Id: id, + Type: req.Type, Avoid: avoid, - ProgData: data, + Data: data, Flags: flags, ExecOpts: &opts, AllSignal: allSignal, @@ -361,7 +365,18 @@ func (runner *Runner) handleExecutingMessage(msg *flatrpc.ExecutingMessage) erro } else { runner.stats.statExecRetries.Add(1) } - runner.lastExec.Note(int(msg.Id), proc, req.Prog.Serialize(), osutil.MonotonicNano()) + var data []byte + switch req.Type { + case flatrpc.RequestTypeProgram: + data = req.Prog.Serialize() + case flatrpc.RequestTypeBinary: + data = []byte(fmt.Sprintf("executing binary %v\n", req.BinaryFile)) + case flatrpc.RequestTypeGlob: + data = []byte(fmt.Sprintf("expanding glob: %v\n", req.GlobPattern)) + default: + panic(fmt.Sprintf("unhandled request type %v", req.Type)) + } + runner.lastExec.Note(int(msg.Id), proc, data, osutil.MonotonicNano()) select { case runner.injectExec <- true: default: @@ -385,7 +400,7 @@ func (runner *Runner) handleExecResult(msg *flatrpc.ExecResult) error { } delete(runner.requests, msg.Id) delete(runner.executing, msg.Id) - if msg.Info != nil { + if req.Type == flatrpc.RequestTypeProgram && msg.Info != nil { for len(msg.Info.Calls) < len(req.Prog.Calls) { msg.Info.Calls = append(msg.Info.Calls, &flatrpc.CallInfo{ Error: 999, |
