diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-04-29 07:55:42 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-04-29 14:53:56 +0000 |
| commit | ee541933d6cdece196c947c5aeecf496cab5e983 (patch) | |
| tree | a71a35dce425a0b48243884cc21ebbe6c9995f76 /prog | |
| parent | ff7c0a076c7baabdc6797179f649803250f21bd9 (diff) | |
prog: add raw deserialization mode
Raw deserialization mode does not do any program sanitization
and allows to use global file names, prohibited ioctl's, etc.
This will be useful for moving syscall/feature checking code
to the host, we will need to probe opening global files, etc.
Diffstat (limited to 'prog')
| -rw-r--r-- | prog/encoding.go | 23 | ||||
| -rw-r--r-- | prog/validation.go | 5 |
2 files changed, 21 insertions, 7 deletions
diff --git a/prog/encoding.go b/prog/encoding.go index db32484a8..06099993f 100644 --- a/prog/encoding.go +++ b/prog/encoding.go @@ -235,8 +235,17 @@ func (a *ResultArg) serialize(ctx *serializer) { type DeserializeMode int const ( - Strict DeserializeMode = iota - NonStrict DeserializeMode = iota + // In strict mode deserialization fails if the program is malformed in any way. + // This mode is used for manually written programs to ensure that they are correct. + Strict DeserializeMode = iota + // In non-strict mode malformed programs silently fixed in a best-effort way, + // e.g. missing/wrong arguments are replaced with default values. + // This mode is used for the corpus programs to "repair" them after descriptions changes. + NonStrict + // Unsafe mode is used for VM checking programs. In this mode programs are not fixed + // for safety, e.g. can access global files, issue prohibited ioctl's, disabled syscalls, etc. + StrictUnsafe + NonStrictUnsafe ) func (target *Target) Deserialize(data []byte, mode DeserializeMode) (*Prog, error) { @@ -246,7 +255,8 @@ func (target *Target) Deserialize(data []byte, mode DeserializeMode) (*Prog, err err, target.OS, target.Arch, GitRevision, mode, data)) } }() - p := newParser(target, data, mode == Strict) + strict := mode == Strict || mode == StrictUnsafe + p := newParser(target, data, strict) prog, err := p.parseProg() if err := p.Err(); err != nil { return nil, err @@ -260,6 +270,7 @@ func (target *Target) Deserialize(data []byte, mode DeserializeMode) (*Prog, err if err := prog.validateWithOpts(validationOptions{ // Don't validate auto-set conditional fields. We'll patch them later. ignoreTransient: true, + allowUnsafe: mode == StrictUnsafe || mode == NonStrictUnsafe, }); err != nil { return nil, err } @@ -267,8 +278,10 @@ func (target *Target) Deserialize(data []byte, mode DeserializeMode) (*Prog, err if p.autos != nil { p.fixupAutos(prog) } - if err := prog.sanitize(mode == NonStrict); err != nil { - return nil, err + if mode != StrictUnsafe { + if err := prog.sanitize(!strict); err != nil { + return nil, err + } } return prog, nil } diff --git a/prog/validation.go b/prog/validation.go index f38dcd1e8..b2a358706 100644 --- a/prog/validation.go +++ b/prog/validation.go @@ -34,6 +34,7 @@ type validCtx struct { type validationOptions struct { ignoreTransient bool + allowUnsafe bool // allow global file names, etc } func (p *Prog) validateWithOpts(opts validationOptions) error { @@ -60,7 +61,7 @@ func (p *Prog) validateWithOpts(opts validationOptions) error { } func (ctx *validCtx) validateCall(c *Call) error { - if c.Meta.Attrs.Disabled { + if !ctx.opts.allowUnsafe && c.Meta.Attrs.Disabled { return fmt.Errorf("use of a disabled call") } if c.Props.Rerun > 0 && c.Props.FailNth > 0 { @@ -210,7 +211,7 @@ func (arg *DataArg) validate(ctx *validCtx, dir Dir) error { typ.Name(), arg.Size(), typ.TypeSize) } case BufferFilename: - if escapingFilename(string(arg.data)) { + if !ctx.opts.allowUnsafe && escapingFilename(string(arg.data)) { return fmt.Errorf("escaping filename %q", arg.data) } } |
