From 88e3a1226bc591d81c1fb98e83cb63cd4f341c6e Mon Sep 17 00:00:00 2001 From: Andrey Artemiev Date: Sat, 6 Aug 2022 05:17:33 -0700 Subject: pkg/csource, pkg/instance, pkg/ipc, pkg/mgrconfig, tools/syz-prog2c, syz-manager: introduce a new setting 'sandbox_arg' (#3263) --- pkg/csource/options.go | 89 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 21 deletions(-) (limited to 'pkg/csource/options.go') diff --git a/pkg/csource/options.go b/pkg/csource/options.go index 3fc549282..b150e79a0 100644 --- a/pkg/csource/options.go +++ b/pkg/csource/options.go @@ -24,6 +24,7 @@ type Options struct { Procs int `json:"procs"` Slowdown int `json:"slowdown"` Sandbox string `json:"sandbox"` + SandboxArg int `json:"sandbox_arg"` Leak bool `json:"leak,omitempty"` // do leak checking @@ -197,35 +198,27 @@ func (opts Options) Serialize() []byte { return data } -func DeserializeOptions(data []byte) (Options, error) { - opts := Options{ - Slowdown: 1, - // Before CloseFDs was added, close_fds() was always called, so default to true. - CloseFDs: true, - } - if err := json.Unmarshal(data, &opts); err == nil { - return opts, nil - } - // Support for legacy formats. - data = bytes.Replace(data, []byte("Sandbox: "), []byte("Sandbox:empty "), -1) +func deserializeLegacyOptions1(data string, opts *Options) error { waitRepeat, debug := false, false - n, err := fmt.Sscanf(string(data), + n, err := fmt.Sscanf(data, "{Threaded:%t Collide:%t Repeat:%t Procs:%d Sandbox:%s"+ " Fault:%t FaultCall:%d FaultNth:%d EnableTun:%t UseTmpDir:%t"+ " HandleSegv:%t WaitRepeat:%t Debug:%t Repro:%t}", &opts.Threaded, &opts.Collide, &opts.Repeat, &opts.Procs, &opts.Sandbox, &opts.Fault, &opts.FaultCall, &opts.FaultNth, &opts.NetInjection, &opts.UseTmpDir, &opts.HandleSegv, &waitRepeat, &debug, &opts.Repro) + if err == nil { if want := 14; n != want { - return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want) + return fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want) } - if opts.Sandbox == "empty" { - opts.Sandbox = "" - } - return opts, nil } - n, err = fmt.Sscanf(string(data), + return err +} + +func deserializeLegacyOptions2(data string, opts *Options) error { + waitRepeat, debug := false, false + n, err := fmt.Sscanf(data, "{Threaded:%t Collide:%t Repeat:%t Procs:%d Sandbox:%s"+ " Fault:%t FaultCall:%d FaultNth:%d EnableTun:%t UseTmpDir:%t"+ " EnableCgroups:%t HandleSegv:%t WaitRepeat:%t Debug:%t Repro:%t}", @@ -234,13 +227,67 @@ func DeserializeOptions(data []byte) (Options, error) { &opts.Cgroups, &opts.HandleSegv, &waitRepeat, &debug, &opts.Repro) if err == nil { if want := 15; n != want { - return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want) + return fmt.Errorf("failed to parse repro options 2: got %v fields, want %v", n, want) } - if opts.Sandbox == "empty" { - opts.Sandbox = "" + } + return err +} + +// Android format. +func deserializeLegacyOptions3(data string, opts *Options) error { + waitRepeat, debug := false, false + n, err := fmt.Sscanf(data, + "{Threaded:%t Collide:%t Repeat:%t Procs:%d Sandbox:%s SandboxArg:%d"+ + " Fault:%t FaultCall:%d FaultNth:%d EnableTun:%t UseTmpDir:%t"+ + " EnableCgroups:%t HandleSegv:%t WaitRepeat:%t Debug:%t Repro:%t}", + &opts.Threaded, &opts.Collide, &opts.Repeat, &opts.Procs, &opts.Sandbox, &opts.SandboxArg, + &opts.Fault, &opts.FaultCall, &opts.FaultNth, &opts.NetInjection, &opts.UseTmpDir, + &opts.Cgroups, &opts.HandleSegv, &waitRepeat, &debug, &opts.Repro) + if err == nil { + if want := 16; n != want { + return fmt.Errorf("failed to parse repro options 3: got %v fields, want %v", n, want) } + } + return err +} + +var parsers = []func(string, *Options) error{ + deserializeLegacyOptions1, + deserializeLegacyOptions2, + deserializeLegacyOptions3, +} + +// Support for legacy formats. +func deserializeLegacyFormats(data []byte, opts *Options) error { + data = bytes.Replace(data, []byte("Sandbox: "), []byte("Sandbox:empty "), -1) + strData := string(data) + + // We can distinguish between legacy formats by the number + // of fields. The formats we support have 14, 15 and 16. + // Each field can be recognized by ':' char. + version := strings.Count(strData, ":") + if version < 14 || version > 16 { + return fmt.Errorf("unrecognized options format") + } + index := version - 14 + err := parsers[index](strData, opts) + + if opts.Sandbox == "empty" { + opts.Sandbox = "" + } + return err +} + +func DeserializeOptions(data []byte) (Options, error) { + opts := Options{ + Slowdown: 1, + // Before CloseFDs was added, close_fds() was always called, so default to true. + CloseFDs: true, + } + if err := json.Unmarshal(data, &opts); err == nil { return opts, nil } + err := deserializeLegacyFormats(data, &opts) return opts, err } -- cgit mrf-deployment