diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2022-06-20 10:44:45 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2022-06-20 13:25:11 +0200 |
| commit | ffa8ac3a590fe2a10eab5fb47a18c0e3393fa730 (patch) | |
| tree | f21882a562a8061e8de319d7da4483493b94c15e /prog/mutation.go | |
| parent | 6bc654432e118601d676876d83964b604758bf3a (diff) | |
prog: fix out-of-bounds access in any blob mutation
If we grow any blob during mutation, we allocate a new address for it
(so that it does not overlap with other data).
To do this we call analyze after the mutation.
However, after mutation the blob can grow out of bounds of the data area
and analyze will cause out-of-bounds access during marking of existing
allocations.
Fix this by calling analyze before we mutate the blob.
Also while we are here use the proper call for analyze.
Currently we always analyze only the first call,
which is wrong (probably a latent TODO from initial implementation).
Fixes #3206
Diffstat (limited to 'prog/mutation.go')
| -rw-r--r-- | prog/mutation.go | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/prog/mutation.go b/prog/mutation.go index 0181aaa43..022ebce62 100644 --- a/prog/mutation.go +++ b/prog/mutation.go @@ -93,12 +93,12 @@ func (ctx *mutator) squashAny() bool { return false } ptr := complexPtrs[r.Intn(len(complexPtrs))] - if !p.Target.isAnyPtr(ptr.Type()) { - p.Target.squashPtr(ptr) + if !p.Target.isAnyPtr(ptr.arg.Type()) { + p.Target.squashPtr(ptr.arg) } var blobs []*DataArg var bases []*PointerArg - ForeachSubArg(ptr, func(arg Arg, ctx *ArgCtx) { + ForeachSubArg(ptr.arg, func(arg Arg, ctx *ArgCtx) { if data, ok := arg.(*DataArg); ok && arg.Dir() != DirOut { blobs = append(blobs, data) bases = append(bases, ctx.Base) @@ -107,6 +107,10 @@ func (ctx *mutator) squashAny() bool { if len(blobs) == 0 { return false } + // Note: we need to call analyze before we mutate the blob. + // After mutation the blob can grow out of bounds of the data area + // and analyze will crash with out-of-bounds access while marking existing allocations. + s := analyze(ctx.ct, ctx.corpus, p, ptr.call) // TODO(dvyukov): we probably want special mutation for ANY. // E.g. merging adjacent ANYBLOBs (we don't create them, // but they can appear in future); or replacing ANYRES @@ -118,7 +122,6 @@ func (ctx *mutator) squashAny() bool { arg.data = mutateData(r, arg.Data(), 0, maxBlobLen) // Update base pointer if size has increased. if baseSize < base.Res.Size() { - s := analyze(ctx.ct, ctx.corpus, p, p.Calls[0]) newArg := r.allocAddr(s, base.Type(), base.Dir(), base.Res.Size(), base.Res) *base = *newArg } |
