diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2020-04-18 14:43:29 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-04-18 14:43:29 +0200 |
| commit | 365fba2440cee3aed74c774867a1f43e3e2f7aac (patch) | |
| tree | d148c5d3f2e417b31d3dca1ae0e5d9c77da847b9 /sys | |
| parent | 6fe0f49646813924a072d786e080ab7bf4f9ab65 (diff) | |
executor: surround the data mapping with PROT_NONE pages
Surround the main data mapping with PROT_NONE pages to make virtual address layout more consistent
across different configurations (static/non-static build) and C repros.
One observed case before: executor had a mapping above the data mapping (output region),
while C repros did not have that mapping above, as the result in one case VMA had next link,
while in the other it didn't and it caused a bug to not reproduce with the C repro.
The bug that reproduces only with the mapping above:
https://lkml.org/lkml/2020/4/17/819
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/akaros/init.go | 2 | ||||
| -rw-r--r-- | sys/freebsd/init.go | 2 | ||||
| -rw-r--r-- | sys/linux/init.go | 2 | ||||
| -rw-r--r-- | sys/netbsd/init.go | 2 | ||||
| -rw-r--r-- | sys/openbsd/init.go | 2 | ||||
| -rw-r--r-- | sys/targets/common.go | 29 |
6 files changed, 25 insertions, 14 deletions
diff --git a/sys/akaros/init.go b/sys/akaros/init.go index 3016b3dee..c669cedef 100644 --- a/sys/akaros/init.go +++ b/sys/akaros/init.go @@ -16,7 +16,7 @@ func InitTarget(target *prog.Target) { arch := &arch{ MAP_FIXED: target.GetConst("MAP_FIXED"), } - target.MakeDataMmap = targets.MakePosixMmap(target, true) + target.MakeDataMmap = targets.MakePosixMmap(target, true, false) target.Neutralize = arch.Neutralize } diff --git a/sys/freebsd/init.go b/sys/freebsd/init.go index eff43b288..33f93825a 100644 --- a/sys/freebsd/init.go +++ b/sys/freebsd/init.go @@ -13,7 +13,7 @@ func InitTarget(target *prog.Target) { unix: targets.MakeUnixNeutralizer(target), } - target.MakeDataMmap = targets.MakePosixMmap(target, true) + target.MakeDataMmap = targets.MakePosixMmap(target, true, false) target.Neutralize = arch.unix.Neutralize } diff --git a/sys/linux/init.go b/sys/linux/init.go index 6a10c7d82..c9c15a283 100644 --- a/sys/linux/init.go +++ b/sys/linux/init.go @@ -48,7 +48,7 @@ func InitTarget(target *prog.Target) { ARCH_SET_GS: target.ConstMap["ARCH_SET_GS"], } - target.MakeDataMmap = targets.MakePosixMmap(target, true) + target.MakeDataMmap = targets.MakePosixMmap(target, true, true) target.Neutralize = arch.neutralize target.SpecialTypes = map[string]func(g *prog.Gen, typ prog.Type, old prog.Arg) ( prog.Arg, []*prog.Call){ diff --git a/sys/netbsd/init.go b/sys/netbsd/init.go index c90c51eb8..1a7988d61 100644 --- a/sys/netbsd/init.go +++ b/sys/netbsd/init.go @@ -13,7 +13,7 @@ func InitTarget(target *prog.Target) { unix: targets.MakeUnixNeutralizer(target), } - target.MakeDataMmap = targets.MakePosixMmap(target, false) + target.MakeDataMmap = targets.MakePosixMmap(target, false, false) target.Neutralize = arch.unix.Neutralize } diff --git a/sys/openbsd/init.go b/sys/openbsd/init.go index 40ab996f4..6948139aa 100644 --- a/sys/openbsd/init.go +++ b/sys/openbsd/init.go @@ -19,7 +19,7 @@ func InitTarget(target *prog.Target) { S_IFCHR: target.GetConst("S_IFCHR"), } - target.MakeDataMmap = targets.MakePosixMmap(target, false) + target.MakeDataMmap = targets.MakePosixMmap(target, false, false) target.Neutralize = arch.neutralize target.AnnotateCall = arch.annotateCall } diff --git a/sys/targets/common.go b/sys/targets/common.go index 75a1aba4f..d7ee71983 100644 --- a/sys/targets/common.go +++ b/sys/targets/common.go @@ -8,18 +8,21 @@ import ( ) // MakePosixMmap creates a "normal" posix mmap call that maps the target data range. -func MakePosixMmap(target *prog.Target, exec bool) func() []*prog.Call { +// If exec is set, the mapping is mapped as PROT_EXEC. +// If contain is set, the mapping is surrounded by PROT_NONE pages. +// These flags should be in sync with what executor. +func MakePosixMmap(target *prog.Target, exec, contain bool) func() []*prog.Call { meta := target.SyscallMap["mmap"] - prot := target.GetConst("PROT_READ") | target.GetConst("PROT_WRITE") + protRW := target.GetConst("PROT_READ") | target.GetConst("PROT_WRITE") if exec { - prot |= target.GetConst("PROT_EXEC") + protRW |= target.GetConst("PROT_EXEC") } flags := target.GetConst("MAP_ANONYMOUS") | target.GetConst("MAP_PRIVATE") | target.GetConst("MAP_FIXED") - const invalidFD = ^uint64(0) size := target.NumPages * target.PageSize - return func() []*prog.Call { + const invalidFD = ^uint64(0) + makeMmap := func(addr, size, prot uint64) *prog.Call { args := []prog.Arg{ - prog.MakeVmaPointerArg(meta.Args[0], 0, size), + prog.MakeVmaPointerArg(meta.Args[0], addr, size), prog.MakeConstArg(meta.Args[1], size), prog.MakeConstArg(meta.Args[2], prot), prog.MakeConstArg(meta.Args[3], flags), @@ -32,13 +35,21 @@ func MakePosixMmap(target *prog.Target, exec bool) func() []*prog.Call { i++ } args = append(args, prog.MakeConstArg(meta.Args[i], 0)) - - mmapCall := &prog.Call{ + return &prog.Call{ Meta: meta, Args: args, Ret: prog.MakeReturnArg(meta.Ret), } - return []*prog.Call{mmapCall} + } + return func() []*prog.Call { + if contain { + return []*prog.Call{ + makeMmap(^uint64(target.PageSize)+1, target.PageSize, 0), + makeMmap(0, size, protRW), + makeMmap(size, target.PageSize, 0), + } + } + return []*prog.Call{makeMmap(0, size, protRW)} } } |
