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/fuzzer/queue/queue.go | |
| 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/fuzzer/queue/queue.go')
| -rw-r--r-- | pkg/fuzzer/queue/queue.go | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/pkg/fuzzer/queue/queue.go b/pkg/fuzzer/queue/queue.go index 1d25cbc8a..05d9cfbed 100644 --- a/pkg/fuzzer/queue/queue.go +++ b/pkg/fuzzer/queue/queue.go @@ -9,6 +9,7 @@ import ( "encoding/gob" "fmt" "math/rand" + "strings" "sync" "sync/atomic" @@ -20,8 +21,15 @@ import ( ) type Request struct { - Prog *prog.Prog - ExecOpts flatrpc.ExecOpts + // Type of the request. + // RequestTypeProgram executes Prog, and is used by most requests (also the default zero value). + // RequestTypeBinary executes binary with file name stored in Data. + // RequestTypeGlob expands glob pattern stored in Data. + Type flatrpc.RequestType + ExecOpts flatrpc.ExecOpts + Prog *prog.Prog // for RequestTypeProgram + BinaryFile string // for RequestTypeBinary + GlobPattern string // for RequestTypeGlob // If specified, the resulting signal for call SignalFilterCall // will include subset of it even if it's not new. @@ -36,9 +44,6 @@ type Request struct { // This stat will be incremented on request completion. Stat *stat.Val - // Options needed by runtest. - BinaryFile string // If set, it's executed instead of Prog. - // Important requests will be retried even from crashed VMs. Important bool @@ -123,20 +128,51 @@ func (r *Request) Validate() error { if (collectComps) && (collectSignal || collectCover) { return fmt.Errorf("hint collection is mutually exclusive with signal/coverage") } - sandboxes := flatrpc.ExecEnvSandboxNone | flatrpc.ExecEnvSandboxSetuid | - flatrpc.ExecEnvSandboxNamespace | flatrpc.ExecEnvSandboxAndroid - if r.BinaryFile == "" && r.ExecOpts.EnvFlags&sandboxes == 0 { - return fmt.Errorf("no sandboxes set") + switch r.Type { + case flatrpc.RequestTypeProgram: + if r.Prog == nil { + return fmt.Errorf("program is not set") + } + sandboxes := flatrpc.ExecEnvSandboxNone | flatrpc.ExecEnvSandboxSetuid | + flatrpc.ExecEnvSandboxNamespace | flatrpc.ExecEnvSandboxAndroid + if r.ExecOpts.EnvFlags&sandboxes == 0 { + return fmt.Errorf("no sandboxes set") + } + case flatrpc.RequestTypeBinary: + if r.BinaryFile == "" { + return fmt.Errorf("binary file name is not set") + } + case flatrpc.RequestTypeGlob: + if r.GlobPattern == "" { + return fmt.Errorf("glob pattern is not set") + } + default: + return fmt.Errorf("unknown request type") } return nil } func (r *Request) hash() hash.Sig { buf := new(bytes.Buffer) - if err := gob.NewEncoder(buf).Encode(r.ExecOpts); err != nil { + enc := gob.NewEncoder(buf) + if err := enc.Encode(r.Type); err != nil { + panic(err) + } + if err := enc.Encode(r.ExecOpts); err != nil { panic(err) } - return hash.Hash(r.Prog.Serialize(), buf.Bytes()) + var data []byte + switch r.Type { + case flatrpc.RequestTypeProgram: + data = r.Prog.Serialize() + case flatrpc.RequestTypeBinary: + data = []byte(r.BinaryFile) + case flatrpc.RequestTypeGlob: + data = []byte(r.GlobPattern) + default: + panic("unknown request type") + } + return hash.Hash(data, buf.Bytes()) } func (r *Request) initChannel() { @@ -172,6 +208,15 @@ func (r *Result) Stop() bool { } } +// Globs returns result of RequestTypeGlob. +func (r *Result) GlobFiles() []string { + out := strings.Trim(string(r.Output), "\000") + if out == "" { + return nil + } + return strings.Split(out, "\000") +} + type Status int const ( |
