pkg/ipc: move target characteristics out of config flags

They don't belong there, executor does not know about them.
In preparation for future changes.
This commit is contained in:
Dmitry Vyukov 2019-11-15 11:27:04 +01:00
parent aa27601f9e
commit a129861adb
4 changed files with 24 additions and 32 deletions

View File

@ -39,9 +39,6 @@ const (
FlagEnableCgroups // setup cgroups for testing FlagEnableCgroups // setup cgroups for testing
FlagEnableCloseFds // close fds after each program FlagEnableCloseFds // close fds after each program
FlagEnableDevlinkPCI // setup devlink PCI device FlagEnableDevlinkPCI // setup devlink PCI device
// Executor does not know about these:
FlagUseShmem // use shared memory instead of pipes for communication
FlagUseForkServer // use extended protocol with handshake
) )
// Per-exec flags for ExecOpts.Flags: // Per-exec flags for ExecOpts.Flags:
@ -67,6 +64,9 @@ type Config struct {
// Path to executor binary. // Path to executor binary.
Executor string Executor string
UseShmem bool // use shared memory instead of pipes for communication
UseForkServer bool // use extended protocol with handshake
// Flags are configuation flags, defined above. // Flags are configuation flags, defined above.
Flags EnvFlags Flags EnvFlags
@ -155,7 +155,7 @@ func FlagsToSandbox(flags EnvFlags) string {
func MakeEnv(config *Config, pid int) (*Env, error) { func MakeEnv(config *Config, pid int) (*Env, error) {
var inf, outf *os.File var inf, outf *os.File
var inmem, outmem []byte var inmem, outmem []byte
if config.Flags&FlagUseShmem != 0 { if config.UseShmem {
var err error var err error
inf, inmem, err = osutil.CreateMemMappedFile(prog.ExecBufferSize) inf, inmem, err = osutil.CreateMemMappedFile(prog.ExecBufferSize)
if err != nil { if err != nil {
@ -254,7 +254,7 @@ func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info *ProgInf
return return
} }
var progData []byte var progData []byte
if env.config.Flags&FlagUseShmem == 0 { if !env.config.UseShmem {
progData = env.in[:progSize] progData = env.in[:progSize]
} }
// Zero out the first two words (ncmd and nsig), so that we don't have garbage there // Zero out the first two words (ncmd and nsig), so that we don't have garbage there
@ -288,7 +288,7 @@ func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info *ProgInf
if info != nil && env.config.Flags&FlagSignal == 0 { if info != nil && env.config.Flags&FlagSignal == 0 {
addFallbackSignal(p, info) addFallbackSignal(p, info)
} }
if env.config.Flags&FlagUseForkServer == 0 { if !env.config.UseForkServer {
env.cmd.close() env.cmd.close()
env.cmd = nil env.cmd = nil
} }
@ -620,7 +620,7 @@ func makeCommand(pid int, bin []string, config *Config, inFile, outFile *os.File
// reading from inrp will hang since we hold another end of the pipe open. // reading from inrp will hang since we hold another end of the pipe open.
inwp.Close() inwp.Close()
if c.config.Flags&FlagUseForkServer != 0 { if c.config.UseForkServer {
if err := c.handshake(); err != nil { if err := c.handshake(); err != nil {
return nil, err return nil, err
} }
@ -809,14 +809,14 @@ func sanitizeTimeout(config *Config) time.Duration {
// Executor can be slow due to global locks in namespaces and other things, // Executor can be slow due to global locks in namespaces and other things,
// so let's better wait than report false misleading crashes. // so let's better wait than report false misleading crashes.
timeout = time.Minute timeout = time.Minute
if config.Flags&FlagUseForkServer == 0 { if !config.UseForkServer {
// If there is no fork server, executor does not have internal timeout. // If there is no fork server, executor does not have internal timeout.
timeout = executorTimeout timeout = executorTimeout
} }
} }
// IPC timeout must be larger then executor timeout. // IPC timeout must be larger then executor timeout.
// Otherwise IPC will kill parent executor but leave child executor alive. // Otherwise IPC will kill parent executor but leave child executor alive.
if config.Flags&FlagUseForkServer != 0 && timeout < minTimeout { if config.UseForkServer && timeout < minTimeout {
timeout = minTimeout timeout = minTimeout
} }
return timeout return timeout

View File

@ -31,7 +31,7 @@ func buildExecutor(t *testing.T, target *prog.Target) string {
return bin return bin
} }
func initTest(t *testing.T) (*prog.Target, rand.Source, int, EnvFlags) { func initTest(t *testing.T) (*prog.Target, rand.Source, int, bool, bool) {
t.Parallel() t.Parallel()
iters := 100 iters := 100
if testing.Short() { if testing.Short() {
@ -51,8 +51,7 @@ func initTest(t *testing.T) (*prog.Target, rand.Source, int, EnvFlags) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
flags := cfg.Flags & (FlagUseShmem | FlagUseForkServer) return target, rs, iters, cfg.UseShmem, cfg.UseForkServer
return target, rs, iters, flags
} }
// TestExecutor runs all internal executor unit tests. // TestExecutor runs all internal executor unit tests.
@ -72,7 +71,7 @@ func TestExecutor(t *testing.T) {
} }
func TestExecute(t *testing.T) { func TestExecute(t *testing.T) {
target, _, _, configFlags := initTest(t) target, _, _, useShmem, useForkServer := initTest(t)
bin := buildExecutor(t, target) bin := buildExecutor(t, target)
defer os.Remove(bin) defer os.Remove(bin)
@ -81,9 +80,10 @@ func TestExecute(t *testing.T) {
for _, flag := range flags { for _, flag := range flags {
t.Logf("testing flags 0x%x\n", flag) t.Logf("testing flags 0x%x\n", flag)
cfg := &Config{ cfg := &Config{
Executor: bin, Executor: bin,
Flags: configFlags, UseShmem: useShmem,
Timeout: timeout, UseForkServer: useForkServer,
Timeout: timeout,
} }
env, err := MakeEnv(cfg, 0) env, err := MakeEnv(cfg, 0)
if err != nil { if err != nil {
@ -117,12 +117,13 @@ func TestExecute(t *testing.T) {
} }
func TestParallel(t *testing.T) { func TestParallel(t *testing.T) {
target, _, _, configFlags := initTest(t) target, _, _, useShmem, useForkServer := initTest(t)
bin := buildExecutor(t, target) bin := buildExecutor(t, target)
defer os.Remove(bin) defer os.Remove(bin)
cfg := &Config{ cfg := &Config{
Executor: bin, Executor: bin,
Flags: configFlags, UseShmem: useShmem,
UseForkServer: useForkServer,
} }
const P = 10 const P = 10
errs := make(chan error, P) errs := make(chan error, P)

View File

@ -38,13 +38,8 @@ func Default(target *prog.Target) (*ipc.Config, *ipc.ExecOpts, error) {
} }
c.Flags |= sandboxFlags c.Flags |= sandboxFlags
sysTarget := targets.Get(target.OS, target.Arch) sysTarget := targets.Get(target.OS, target.Arch)
if sysTarget.ExecutorUsesShmem { c.UseShmem = sysTarget.ExecutorUsesShmem
c.Flags |= ipc.FlagUseShmem c.UseForkServer = sysTarget.ExecutorUsesForkServer
}
if sysTarget.ExecutorUsesForkServer {
c.Flags |= ipc.FlagUseForkServer
}
opts := &ipc.ExecOpts{ opts := &ipc.ExecOpts{
Flags: ipc.FlagDedupCover, Flags: ipc.FlagDedupCover,
} }

View File

@ -352,12 +352,8 @@ func (ctx *Context) createSyzTest(p *prog.Prog, sandbox string, threaded, cov bo
sysTarget := targets.Get(p.Target.OS, p.Target.Arch) sysTarget := targets.Get(p.Target.OS, p.Target.Arch)
cfg := new(ipc.Config) cfg := new(ipc.Config)
opts := new(ipc.ExecOpts) opts := new(ipc.ExecOpts)
if sysTarget.ExecutorUsesShmem { cfg.UseShmem = sysTarget.ExecutorUsesShmem
cfg.Flags |= ipc.FlagUseShmem cfg.UseForkServer = sysTarget.ExecutorUsesForkServer
}
if sysTarget.ExecutorUsesForkServer {
cfg.Flags |= ipc.FlagUseForkServer
}
sandboxFlags, err := ipc.SandboxToFlags(sandbox) sandboxFlags, err := ipc.SandboxToFlags(sandbox)
if err != nil { if err != nil {
return nil, err return nil, err